diff options
| author | Jörg Frings-Fürst <debian@jff.email> | 2024-03-06 10:24:08 +0100 | 
|---|---|---|
| committer | Jörg Frings-Fürst <debian@jff.email> | 2024-03-06 10:24:08 +0100 | 
| commit | aad5ad9bf0c02aa4e79bc6b7d6c934612fff4026 (patch) | |
| tree | 9cc224b059f248a6229ab0dcdc64eb4a73fa9800 /doc/cxx | |
| parent | c1034fc5e99197f507caf450aa15bc178698b26e (diff) | |
New upstream version 4.2.0upstream/4.2.0upstream
Diffstat (limited to 'doc/cxx')
| -rw-r--r-- | doc/cxx/parser/guide/figure-1.png | bin | 0 -> 34195 bytes | |||
| -rw-r--r-- | doc/cxx/parser/guide/figure-1.svg | 373 | ||||
| -rw-r--r-- | doc/cxx/parser/guide/guide.html2ps.in | 65 | ||||
| -rw-r--r-- | doc/cxx/parser/guide/index.xhtml | 4163 | ||||
| -rw-r--r-- | doc/cxx/parser/guide/index.xhtml.in | 4163 | ||||
| -rw-r--r-- | doc/cxx/tree/guide/guide.html2ps.in | 65 | ||||
| -rw-r--r-- | doc/cxx/tree/guide/index.xhtml | 2736 | ||||
| -rw-r--r-- | doc/cxx/tree/guide/index.xhtml.in | 2736 | ||||
| -rw-r--r-- | doc/cxx/tree/manual/index.xhtml | 6826 | ||||
| -rw-r--r-- | doc/cxx/tree/manual/index.xhtml.in | 6826 | ||||
| -rw-r--r-- | doc/cxx/tree/manual/manual.html2ps.in | 66 | 
11 files changed, 28019 insertions, 0 deletions
diff --git a/doc/cxx/parser/guide/figure-1.png b/doc/cxx/parser/guide/figure-1.png Binary files differnew file mode 100644 index 0000000..15d1723 --- /dev/null +++ b/doc/cxx/parser/guide/figure-1.png diff --git a/doc/cxx/parser/guide/figure-1.svg b/doc/cxx/parser/guide/figure-1.svg new file mode 100644 index 0000000..d994a79 --- /dev/null +++ b/doc/cxx/parser/guide/figure-1.svg @@ -0,0 +1,373 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg +   xmlns:dc="http://purl.org/dc/elements/1.1/" +   xmlns:cc="http://web.resource.org/cc/" +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" +   xmlns:svg="http://www.w3.org/2000/svg" +   xmlns="http://www.w3.org/2000/svg" +   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" +   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" +   width="744.09448819" +   height="1052.3622047" +   id="svg2" +   sodipodi:version="0.32" +   inkscape:version="0.44.1" +   sodipodi:docbase="/tmp" +   sodipodi:docname="figure-1.svg" +   inkscape:export-filename="/home/boris/tmp/figure-1.png" +   inkscape:export-xdpi="76.195885" +   inkscape:export-ydpi="76.195885"> +  <defs +     id="defs4"> +    <marker +       inkscape:stockid="Arrow1Lend" +       orient="auto" +       refY="0.0" +       refX="0.0" +       id="Arrow1Lend" +       style="overflow:visible;"> +      <path +         id="path2934" +         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;" +         transform="scale(0.8) rotate(180) translate(12.5,0)" /> +    </marker> +    <marker +       inkscape:stockid="Dot_l" +       orient="auto" +       refY="0.0" +       refX="0.0" +       id="Dot_l" +       style="overflow:visible"> +      <path +         id="path2875" +         d="M -2.5,-1.0 C -2.5,1.7600000 -4.7400000,4.0 -7.5,4.0 C -10.260000,4.0 -12.5,1.7600000 -12.5,-1.0 C -12.5,-3.7600000 -10.260000,-6.0 -7.5,-6.0 C -4.7400000,-6.0 -2.5,-3.7600000 -2.5,-1.0 z " +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;marker-end:none" +         transform="scale(0.8) translate(7.4, 1)" /> +    </marker> +    <marker +       inkscape:stockid="Arrow1Mend" +       orient="auto" +       refY="0.0" +       refX="0.0" +       id="Arrow1Mend" +       style="overflow:visible;"> +      <path +         id="path2928" +         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;" +         transform="scale(0.4) rotate(180) translate(10,0)" /> +    </marker> +    <marker +       inkscape:stockid="Dot_m" +       orient="auto" +       refY="0.0" +       refX="0.0" +       id="Dot_m" +       style="overflow:visible"> +      <path +         id="path2872" +         d="M -2.5,-1.0 C -2.5,1.7600000 -4.7400000,4.0 -7.5,4.0 C -10.260000,4.0 -12.5,1.7600000 -12.5,-1.0 C -12.5,-3.7600000 -10.260000,-6.0 -7.5,-6.0 C -4.7400000,-6.0 -2.5,-3.7600000 -2.5,-1.0 z " +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;marker-end:none" +         transform="scale(0.4) translate(7.4, 1)" /> +    </marker> +    <marker +       inkscape:stockid="Arrow1Lstart" +       orient="auto" +       refY="0.0" +       refX="0.0" +       id="Arrow1Lstart" +       style="overflow:visible"> +      <path +         id="path2937" +         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " +         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none" +         transform="scale(0.8) translate(12.5,0)" /> +    </marker> +    <marker +       inkscape:stockid="Arrow2Mend" +       orient="auto" +       refY="0.0" +       refX="0.0" +       id="Arrow2Mend" +       style="overflow:visible;"> +      <path +         id="path2910" +         style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;" +         d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z " +         transform="scale(0.6) rotate(180) translate(0,0)" /> +    </marker> +  </defs> +  <sodipodi:namedview +     id="base" +     pagecolor="#ffffff" +     bordercolor="#666666" +     borderopacity="1.0" +     gridtolerance="10000" +     guidetolerance="10" +     objecttolerance="10" +     inkscape:pageopacity="0.0" +     inkscape:pageshadow="2" +     inkscape:zoom="0.98994949" +     inkscape:cx="328.23027" +     inkscape:cy="733.01096" +     inkscape:document-units="px" +     inkscape:current-layer="layer1" +     inkscape:window-width="1280" +     inkscape:window-height="991" +     inkscape:window-x="154" +     inkscape:window-y="44" /> +  <metadata +     id="metadata7"> +    <rdf:RDF> +      <cc:Work +         rdf:about=""> +        <dc:format>image/svg+xml</dc:format> +        <dc:type +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> +      </cc:Work> +    </rdf:RDF> +  </metadata> +  <g +     inkscape:label="Layer 1" +     inkscape:groupmode="layer" +     id="layer1"> +    <g +       id="g3902"> +      <rect +         y="194.64178" +         x="24.142784" +         height="106.2678" +         width="149.70432" +         id="rect1872" +         style="fill:#c5ddf8;fill-opacity:1;fill-rule:evenodd;stroke:#c5ddf8;stroke-width:5.29799986;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> +      <text +         sodipodi:linespacing="125%" +         id="text3038" +         y="219.99649" +         x="28.284279" +         style="font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;color:black;fill:black;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;font-family:Monospace" +         xml:space="preserve"><tspan +           y="219.99649" +           x="28.284279" +           id="tspan3064" +           sodipodi:role="line">class people_pimpl</tspan><tspan +           y="236.24649" +           x="28.284279" +           id="tspan3066" +           sodipodi:role="line">{</tspan><tspan +           y="252.49649" +           x="28.284279" +           id="tspan3068" +           sodipodi:role="line">  void </tspan><tspan +           y="268.74649" +           x="28.284279" +           id="tspan3070" +           sodipodi:role="line">  person ();</tspan><tspan +           y="284.99649" +           x="28.284279" +           id="tspan3072" +           sodipodi:role="line">};</tspan></text> +    </g> +    <g +       id="g3881"> +      <rect +         y="124.93772" +         x="252.43373" +         height="245.67592" +         width="180.01601" +         id="rect5750" +         style="fill:#c5ddf8;fill-opacity:1;fill-rule:evenodd;stroke:#c5ddf8;stroke-width:9.12976837;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> +      <text +         sodipodi:linespacing="100%" +         id="text5752" +         y="148.27567" +         x="257.5889" +         style="font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;color:black;fill:black;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;font-family:Monospace" +         xml:space="preserve"><tspan +           y="148.27567" +           x="257.5889" +           id="tspan5900" +           sodipodi:role="line">class person_pimpl</tspan><tspan +           y="161.27567" +           x="257.5889" +           id="tspan5902" +           sodipodi:role="line">{</tspan><tspan +           y="174.27567" +           x="257.5889" +           id="tspan5904" +           sodipodi:role="line">  void</tspan><tspan +           y="187.27567" +           x="257.5889" +           id="tspan5906" +           sodipodi:role="line">  first_name (string);</tspan><tspan +           y="200.27567" +           x="257.5889" +           id="tspan5908" +           sodipodi:role="line" /><tspan +           y="213.27567" +           x="257.5889" +           id="tspan5910" +           sodipodi:role="line">  void</tspan><tspan +           y="226.27567" +           x="257.5889" +           id="tspan5912" +           sodipodi:role="line">  last_name (string);</tspan><tspan +           y="239.27567" +           x="257.5889" +           id="tspan5914" +           sodipodi:role="line" /><tspan +           y="252.27567" +           x="257.5889" +           id="tspan5916" +           sodipodi:role="line">  void</tspan><tspan +           y="265.27567" +           x="257.5889" +           id="tspan5918" +           sodipodi:role="line">  gender ();</tspan><tspan +           y="278.27567" +           x="257.5889" +           id="tspan5920" +           sodipodi:role="line" /><tspan +           y="291.27567" +           x="257.5889" +           id="tspan5922" +           sodipodi:role="line">  void</tspan><tspan +           y="304.27567" +           x="257.5889" +           id="tspan5924" +           sodipodi:role="line">  age (short);</tspan><tspan +           y="317.27567" +           x="257.5889" +           id="tspan5926" +           sodipodi:role="line">  </tspan><tspan +           y="330.27567" +           x="257.5889" +           id="tspan5928" +           sodipodi:role="line">  void</tspan><tspan +           y="343.27567" +           x="257.5889" +           id="tspan5930" +           sodipodi:role="line">  post_person ();</tspan><tspan +           y="356.27567" +           x="257.5889" +           id="tspan5932" +           sodipodi:role="line">};</tspan></text> +    </g> +    <g +       id="g3845"> +      <rect +         y="77.741814" +         x="506.28357" +         height="99.610825" +         width="151.1286" +         id="rect5955" +         style="fill:#c5ddf8;fill-opacity:1;fill-rule:evenodd;stroke:#c5ddf8;stroke-width:5.69227886;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> +      <flowRoot +         transform="translate(-5.050762,12.10153)" +         style="font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Monospace" +         id="flowRoot5957" +         xml:space="preserve"><flowRegion +           id="flowRegion5959"><rect +             style="font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Monospace" +             y="74.534515" +             x="516.18793" +             height="88.893425" +             width="143.44167" +             id="rect5961" /></flowRegion><flowPara +           id="flowPara5965">class string_pimpl</flowPara><flowPara +           id="flowPara5967">{</flowPara><flowPara +           id="flowPara5969">  string</flowPara><flowPara +           id="flowPara5971">  post_string ();</flowPara><flowPara +           id="flowPara5973">};</flowPara><flowPara +           id="flowPara5975" /></flowRoot>    </g> +    <g +       id="g3857"> +      <rect +         style="fill:#c5ddf8;fill-opacity:1;fill-rule:evenodd;stroke:#c5ddf8;stroke-width:5.69227886;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" +         id="rect5977" +         width="151.1286" +         height="99.610825" +         x="506.28357" +         y="316.15808" /> +      <flowRoot +         xml:space="preserve" +         id="flowRoot5979" +         style="font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Monospace" +         transform="translate(-5.050761,250.5178)" +         inkscape:export-filename="/tmp/figure-1.png" +         inkscape:export-xdpi="546.53815" +         inkscape:export-ydpi="546.53815"><flowRegion +           id="flowRegion5981"><rect +             id="rect5983" +             width="143.44167" +             height="88.893425" +             x="516.18793" +             y="74.534515" +             style="font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Monospace" /></flowRegion><flowPara +           id="flowPara5985">class short_pimpl</flowPara><flowPara +           id="flowPara5987">{</flowPara><flowPara +           id="flowPara5989">  short</flowPara><flowPara +           id="flowPara5991">  post_short ();</flowPara><flowPara +           id="flowPara5993">};</flowPara><flowPara +           id="flowPara5995" /></flowRoot>    </g> +    <g +       id="g3869"> +      <rect +         style="fill:#c5ddf8;fill-opacity:1;fill-rule:evenodd;stroke:#c5ddf8;stroke-width:5.69227886;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" +         id="rect6023" +         width="151.1286" +         height="99.610825" +         x="505.7785" +         y="196.93977" /> +      <flowRoot +         xml:space="preserve" +         id="flowRoot6025" +         style="font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Monospace" +         transform="translate(-5.555838,129.2792)"><flowRegion +           id="flowRegion6027"><rect +             id="rect6029" +             width="143.44167" +             height="88.893425" +             x="516.18793" +             y="74.534515" +             style="font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Monospace" /></flowRegion><flowPara +           id="flowPara6031">class gender_pimpl</flowPara><flowPara +           id="flowPara6033">{</flowPara><flowPara +           id="flowPara6035">  void</flowPara><flowPara +           id="flowPara6037">  post_gender ();</flowPara><flowPara +           id="flowPara6039">};</flowPara><flowPara +           id="flowPara6041" /></flowRoot>    </g> +    <path +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;marker-start:url(#Dot_l);marker-end:url(#Arrow1Lend)" +       d="M 265.67011,339.69956 L 210.41811,339.34242 L 210.77124,264.14332 L 127.7843,264.4432" +       id="path6051" +       inkscape:connector-type="polyline" +       sodipodi:nodetypes="cccs" /> +    <path +       sodipodi:nodetypes="cccc" +       inkscape:connector-type="polyline" +       id="path6077" +       d="M 518.20825,383.6412 L 471.23616,384.14628 L 471.4887,300.55615 L 368.70568,300.80869" +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Dot_l);marker-end:url(#Arrow1Lend);stroke-opacity:1;display:inline" /> +    <path +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Dot_l);marker-end:url(#Arrow1Lend);stroke-opacity:1;display:inline" +       d="M 517.1981,262.42289 L 353.55339,262.42289" +       id="path6081" +       inkscape:connector-type="polyline" +       sodipodi:nodetypes="cccs" /> +    <path +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Dot_l);marker-end:url(#Arrow1Lend);stroke-opacity:1;display:inline" +       d="M 518.57143,145.93361 L 470.35714,146.14281 L 470.53572,183.07646 L 431.42857,183.79075" +       id="path6089" +       inkscape:connector-type="polyline" +       sodipodi:nodetypes="cccc" /> +    <path +       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1;display:inline" +       d="M 470.46175,178.43361 L 470.89286,222.36218 L 423.21428,222.71932" +       id="path6091" +       inkscape:connector-type="polyline" +       sodipodi:nodetypes="ccc" /> +  </g> +</svg> diff --git a/doc/cxx/parser/guide/guide.html2ps.in b/doc/cxx/parser/guide/guide.html2ps.in new file mode 100644 index 0000000..8131487 --- /dev/null +++ b/doc/cxx/parser/guide/guide.html2ps.in @@ -0,0 +1,65 @@ +@@html2ps { +  option { +    toc: hb; +    colour: 1; +    hyphenate: 1; +    titlepage: 1; +  } + +  datefmt: "%B %Y"; + +  titlepage { +    content: " +<div align=center> +  <h1><big>C++/Parser Mapping</big></h1> +  <h1><big>Getting Started Guide</big></h1> +  <h1> </h1> +  <h1> </h1> +  <h1> </h1> +  <h1> </h1> +  <h1> </h1> +  <h1> </h1> +</div> +  <p>Copyright © @copyright@.</p> + +  <p>Permission is granted to copy, distribute and/or modify this +     document under the terms of the +     <a href='https://www.codesynthesis.com/licenses/fdl-1.2.txt'>GNU Free +     Documentation License, version 1.2</a>; with no Invariant Sections, +     no Front-Cover Texts and no Back-Cover Texts. +  </p> + +  <p>This document is available in the following formats: +     <a href='https://www.codesynthesis.com/projects/xsd/documentation/cxx/parser/guide/index.xhtml'>XHTML</a>, +     <a href='https://www.codesynthesis.com/projects/xsd/documentation/cxx/parser/guide/cxx-parser-guide.pdf'>PDF</a>, and +     <a href='https://www.codesynthesis.com/projects/xsd/documentation/cxx/parser/guide/cxx-parser-guide.ps'>PostScript</a>.</p>"; +  } + +  toc { +    indent: 2em; +  } + +  header { +    odd-right: $H; +    even-left: $H; +  } + +  footer { +    odd-left: $D; +    odd-center: $T; +    odd-right: $N; + +    even-left: $N; +    even-center: $T; +    even-right: $D; +  } +} + +body { +  font-size: 12pt; +  text-align: justify; +} + +pre { +  font-size: 10pt; +} diff --git a/doc/cxx/parser/guide/index.xhtml b/doc/cxx/parser/guide/index.xhtml new file mode 100644 index 0000000..6964a14 --- /dev/null +++ b/doc/cxx/parser/guide/index.xhtml @@ -0,0 +1,4163 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> + +<head> +  <title>C++/Parser Mapping Getting Started Guide</title> + +  <meta name="copyright" content="© 2005-2023 Code Synthesis"/> +  <meta name="keywords" content="xsd,xml,schema,c++,mapping,data,binding,parser,validation"/> +  <meta name="description" content="C++/Parser Mapping Getting Started Guide"/> + +  <link rel="stylesheet" type="text/css" href="../../../default.css" /> + +<style type="text/css"> +  pre { +    padding    : 0 0 0 0em; +    margin     : 0em 0em 0em 0; + +    font-size  : 102% +  } + +  body { +    min-width: 48em; +  } + +  h1 { +    font-weight: bold; +    font-size: 200%; +    line-height: 1.2em; +  } + +  h2 { +    font-weight : bold; +    font-size   : 150%; + +    padding-top : 0.8em; +  } + +  h3 { +    font-size   : 140%; +    padding-top : 0.8em; +  } + +  /* Adjust indentation for three levels. */ +  #container { +    max-width: 48em; +  } + +  #content { +    padding: 0 0.1em 0 4em; +    /*background-color: red;*/ +  } + +  #content h1 { +    margin-left: -2.06em; +  } + +  #content h2 { +    margin-left: -1.33em; +  } + +  /* Title page */ + +  #titlepage { +    padding: 2em 0 1em 0; +    border-bottom: 1px solid black; +  } + +  #titlepage .title { +    font-weight: bold; +    font-size: 200%; +    text-align: center; +  } + +  #titlepage #first-title { +    padding: 1em 0 0.4em 0; +  } + +  #titlepage #second-title { +    padding: 0.4em 0 2em 0; +  } + +  /* Lists */ +  ul.list li { +    padding-top      : 0.3em; +    padding-bottom   : 0.3em; +  } + +  ol.steps { +    padding-left     : 1.8em; +  } + +  ol.steps li { +    padding-top      : 0.3em; +    padding-bottom   : 0.3em; +  } + + +  div.img { +    text-align: center; +    padding: 2em 0 2em 0; +  } + +  /*  */ +  dl dt { +    padding   : 0.8em 0 0 0; +  } + +  /* Built-in table */ +  #builtin { +    margin: 2em 0 2em 0; + +    border-collapse   : collapse; +    border            : 1px solid; +    border-color      : #000000; + +    font-size        : 11px; +    line-height      : 14px; +  } + +  #builtin th, #builtin td { +    border: 1px solid; +    padding           : 0.9em 0.9em 0.7em 0.9em; +  } + +  #builtin th { +    background : #cde8f6; +  } + +  #builtin td { +    text-align: left; +  } + +  /* XML Schema features table. */ +  #features { +    margin: 2em 0 2em 0; + +    border-collapse   : collapse; +    border            : 1px solid; +    border-color      : #000000; + +    font-size        : 11px; +    line-height      : 14px; +  } + +  #features th, #features td { +    border: 1px solid; +    padding           : 0.6em 0.6em 0.6em 0.6em; +  } + +  #features th { +    background : #cde8f6; +  } + +  #features td { +    text-align: left; +  } + + +  /* TOC */ +  table.toc { +    border-style      : none; +    border-collapse   : separate; +    border-spacing    : 0; + +    margin            : 0.2em 0 0.2em 0; +    padding           : 0 0 0 0; +  } + +  table.toc tr { +    padding           : 0 0 0 0; +    margin            : 0 0 0 0; +  } + +  table.toc * td, table.toc * th { +    border-style      : none; +    margin            : 0 0 0 0; +    vertical-align    : top; +  } + +  table.toc * th { +    font-weight       : normal; +    padding           : 0em 0.1em 0em 0; +    text-align        : left; +    white-space       : nowrap; +  } + +  table.toc * table.toc th { +    padding-left      : 1em; +  } + +  table.toc * td { +    padding           : 0em 0 0em 0.7em; +    text-align        : left; +  } +</style> + + +</head> + +<body> +<div id="container"> +  <div id="content"> + +  <div class="noprint"> + +  <div id="titlepage"> +    <div class="title" id="first-title">C++/Parser Mapping</div> +    <div class="title" id="second-title">Getting Started Guide</div> + +  <p>Copyright © 2005-2023 Code Synthesis.</p> + +  <p>Permission is granted to copy, distribute and/or modify this +     document under the terms of the +     <a href="https://www.codesynthesis.com/licenses/fdl-1.2.txt">GNU Free +     Documentation License, version 1.2</a>; with no Invariant Sections, +     no Front-Cover Texts and no Back-Cover Texts. +  </p> + +  <p>This document is available in the following formats: +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/parser/guide/index.xhtml">XHTML</a>, +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/parser/guide/cxx-parser-guide.pdf">PDF</a>, and +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/parser/guide/cxx-parser-guide.ps">PostScript</a>.</p> + +  </div> + +  <h1>Table of Contents</h1> + +  <table class="toc"> +    <tr> +      <th></th><td><a href="#0">Preface</a> +        <table class="toc"> +          <tr><th></th><td><a href="#0.1">About This Document</a></td></tr> +          <tr><th></th><td><a href="#0.2">More Information</a></td></tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>1</th><td><a href="#1">Introduction</a> +        <table class="toc"> +          <tr><th>1.1</th><td><a href="#1.1">Mapping Overview</a></td></tr> +          <tr><th>1.2</th><td><a href="#1.2">Benefits</a></td></tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>2</th><td><a href="#2">Hello World Example</a> +        <table class="toc"> +          <tr><th>2.1</th><td><a href="#2.1">Writing XML Document and Schema</a></td></tr> +          <tr><th>2.2</th><td><a href="#2.2">Translating Schema to C++</a></td></tr> +          <tr><th>2.3</th><td><a href="#2.3">Implementing Application Logic</a></td></tr> +          <tr><th>2.4</th><td><a href="#2.4">Compiling and Running</a></td></tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>3</th><td><a href="#3">Parser Skeletons</a> +        <table class="toc"> +          <tr><th>3.1</th><td><a href="#3.1">Implementing the Gender Parser</a></td></tr> +          <tr><th>3.2</th><td><a href="#3.2">Implementing the Person Parser</a></td></tr> +          <tr><th>3.3</th><td><a href="#3.3">Implementing the People Parser</a></td></tr> +          <tr><th>3.4</th><td><a href="#3.4">Connecting the Parsers Together</a></td></tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>4</th><td><a href="#4">Type Maps</a> +        <table class="toc"> +          <tr><th>4.1</th><td><a href="#4.1">Object Model</a></td></tr> +          <tr><th>4.2</th><td><a href="#4.2">Type Map File Format</a></td></tr> +          <tr><th>4.3</th><td><a href="#4.3">Parser Implementations</a></td></tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>5</th><td><a href="#5">Mapping Configuration</a> +        <table class="toc"> +          <tr><th>5.1</th><td><a href="#5.1">C++ Standard</a></td></tr> +          <tr><th>5.2</th><td><a href="#5.2">Character Type and Encoding</a></td></tr> +          <tr><th>5.3</th><td><a href="#5.3">Underlying XML Parser</a></td></tr> +	  <tr><th>5.4</th><td><a href="#5.4">XML Schema Validation</a></td></tr> +	  <tr><th>5.5</th><td><a href="#5.5">Support for Polymorphism</a></td></tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>6</th><td><a href="#6">Built-In XML Schema Type Parsers</a> +        <table class="toc"> +          <tr><th>6.1</th><td><a href="#6.1"><code>QName</code> Parser</a></td></tr> +          <tr><th>6.2</th><td><a href="#6.2"><code>NMTOKENS</code> and <code>IDREFS</code> Parsers</a></td></tr> +          <tr><th>6.3</th><td><a href="#6.3"><code>base64Binary</code> and <code>hexBinary</code> Parsers</a></td></tr> +	  <tr><th>6.4</th><td><a href="#6.4">Time Zone Representation</a></td></tr> +	  <tr><th>6.5</th><td><a href="#6.5"><code>date</code> Parser</a></td></tr> +	  <tr><th>6.6</th><td><a href="#6.6"><code>dateTime</code> Parser</a></td></tr> +	  <tr><th>6.7</th><td><a href="#6.7"><code>duration</code> Parser</a></td></tr> +	  <tr><th>6.8</th><td><a href="#6.8"><code>gDay</code> Parser</a></td></tr> +	  <tr><th>6.9</th><td><a href="#6.9"><code>gMonth</code> Parser</a></td></tr> +	  <tr><th>6.10</th><td><a href="#6.10"><code>gMonthDay</code> Parser</a></td></tr> +	  <tr><th>6.11</th><td><a href="#6.11"><code>gYear</code> Parser</a></td></tr> +	  <tr><th>6.12</th><td><a href="#6.12"><code>gYearMonth</code> Parser</a></td></tr> +	  <tr><th>6.13</th><td><a href="#6.13"><code>time</code> Parser</a></td></tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>7</th><td><a href="#7">Document Parser and Error Handling</a> +        <table class="toc"> +          <tr><th>7.1</th><td><a href="#7.1">Xerces-C++ Document Parser</a></td></tr> +          <tr><th>7.2</th><td><a href="#7.2">Expat Document Parser</a></td></tr> +          <tr><th>7.3</th><td><a href="#7.3">Error Handling</a></td></tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th></th><td><a href="#A">Appendix A — Supported XML Schema Constructs</a></td> +    </tr> + +  </table> +  </div> + +  <h1><a name="0">Preface</a></h1> + +  <h2><a name="0.1">About This Document</a></h2> + +  <p>The goal of this document is to provide you with an understanding of +     the C++/Parser programming model and allow you to efficiently evaluate +     XSD against your project's technical requirements. As such, this +     document is intended for C++ developers and software architects +     who are looking for an XML processing solution. Prior experience +     with XML and C++ is required to understand this document. Basic +     understanding of XML Schema is advantageous but not expected +     or required. +  </p> + + +  <h2><a name="0.2">More Information</a></h2> + +  <p>Beyond this guide, you may also find the following sources of +     information useful:</p> + +  <ul class="list"> +    <li><a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD +        Compiler Command Line Manual</a></li> + +    <li>The <code>cxx/parser/</code> directory in the +        <a href="https://cppget.org/xsd-examples">xsd-examples</a> package +        contains a collection of examples and a README file with an overview +        of each example.</li> + +    <li>The <code>README</code> file in the +        <a href="https://cppget.org/xsd-examples">xsd-examples</a> package +        explains how to build the examples.</li> + +    <li>The <a href="https://www.codesynthesis.com/mailman/listinfo/xsd-users">xsd-users</a> +        mailing list is the place to ask technical questions about XSD and the C++/Parser mapping. +        Furthermore, the <a href="https://www.codesynthesis.com/pipermail/xsd-users/">archives</a> +        may already have answers to some of your questions.</li> + +  </ul> + +  <!-- Introduction --> + +  <h1><a name="1">1 Introduction</a></h1> + +  <p>Welcome to CodeSynthesis XSD and the C++/Parser mapping. XSD is a +     cross-platform W3C XML Schema to C++ data binding compiler. C++/Parser +     is a W3C XML Schema to C++ mapping that represents an XML vocabulary +     as a set of parser skeletons which you can implement to perform XML +     processing as required by your application logic. +  </p> + +  <h2><a name="1.1">1.1 Mapping Overview</a></h2> + +  <p>The C++/Parser mapping provides event-driven, stream-oriented +     XML parsing, XML Schema validation, and C++ data binding. It was +     specifically designed and optimized for high performance and +     small footprint. Based on the static analysis of the schemas, XSD +     generates compact, highly-optimized hierarchical state machines +     that combine data extraction, validation, and even dispatching +     in a single step. As a result, the generated code is typically +     2-10 times faster than general-purpose validating XML parsers +     while maintaining the lowest static and dynamic memory footprints. +  </p> + +  <p>To speed up application development, the C++/Parser mapping +     can be instructed to generate sample parser implementations +     and a test driver which can then be filled with the application +     logic code. The mapping also provides a wide range of +     mechanisms for controlling and customizing the generated code.</p> + +  <p>The next chapter shows how to create a simple application that uses +     the C++/Parser mapping to parse, validate, and extract data from a +     simple XML document. The following chapters show how to +     use the C++/Parser mapping in more detail.</p> + +  <h2><a name="1.2">1.2 Benefits</a></h2> + +  <p>Traditional XML access APIs such as Document Object Model (DOM) +     or Simple API for XML (SAX) have a number of drawbacks that +     make them less suitable for creating robust and maintainable +     XML processing applications. These drawbacks include: +  </p> + +  <ul class="list"> +    <li>Generic representation of XML in terms of elements, attributes, +        and text forces an application developer to write a substantial +        amount of bridging code that identifies and transforms pieces +        of information encoded in XML to a representation more suitable +        for consumption by the application logic.</li> + +    <li>String-based flow control defers error detection to runtime. +        It also reduces code readability and maintainability.</li> + +    <li>Lack of type safety because the data is represented +        as text.</li> + +    <li>Resulting applications are hard to debug, change, and +        maintain.</li> +  </ul> + +  <p>In contrast, statically-typed, vocabulary-specific parser +     skeletons produced by the C++/Parser mapping allow you to +     operate in your domain terms instead of the generic elements, +     attributes, and text. Static typing helps catch errors at +     compile-time rather than at run-time. Automatic code generation +     frees you for more interesting tasks (such as doing something +     useful with the information stored in the XML documents) and +     minimizes the effort needed to adapt your applications to +     changes in the document structure. To summarize, the C++/Parser +     mapping has the following key advantages over generic XML +     access APIs:</p> + +  <ul class="list"> +    <li><b>Ease of use.</b> The generated code hides all the complexity +        associated with recreating the document structure, maintaining the +        dispatch state, and converting the data from the text representation +        to data types suitable for manipulation by the application logic. +        Parser skeletons also provide a convenient mechanism for building +        custom in-memory representations.</li> + +    <li><b>Natural representation.</b> The generated parser skeletons +        implement parser callbacks as virtual functions with names +        corresponding to elements and attributes in XML. As a result, +        you process the XML data using your domain vocabulary instead +        of generic elements, attributes, and text. +    </li> + +    <li><b>Concise code.</b> With a separate parser skeleton for each +        XML Schema type, the application implementation is +        simpler and thus easier to read and understand.</li> + +    <li><b>Safety.</b> The XML data is delivered to parser callbacks as +        statically typed objects. The parser callbacks themselves are virtual +        functions. This helps catch programming errors at compile-time +        rather than at runtime.</li> + +    <li><b>Maintainability.</b> Automatic code generation minimizes the +        effort needed to adapt the application to changes in the +        document structure. With static typing, the C++ compiler +        can pin-point the places in the application code that need to be +        changed.</li> + +   <li><b>Efficiency.</b> The generated parser skeletons combine +       data extraction, validation, and even dispatching in a single +       step. This makes them much more efficient than traditional +       architectures with separate stages for validation and data +       extraction/dispatch.</li> +  </ul> + +  <!-- Hello World Parser --> + + +  <h1><a name="2">2 Hello World Example</a></h1> + +  <p>In this chapter we will examine how to parse a very simple XML +     document using the XSD-generated C++/Parser skeletons. +     The code presented in this chapter is based on the <code>hello</code> +     example which can be found in the <code>cxx/parser/</code> directory in +     the <a href="https://cppget.org/xsd-examples">xsd-examples</a> +     package.</p> + +  <h2><a name="2.1">2.1 Writing XML Document and Schema</a></h2> + +  <p>First, we need to get an idea about the structure +     of the XML documents we are going to process. Our +     <code>hello.xml</code>, for example, could look like this:</p> + +  <pre class="xml"> +<?xml version="1.0"?> +<hello> + +  <greeting>Hello</greeting> + +  <name>sun</name> +  <name>moon</name> +  <name>world</name> + +</hello> +  </pre> + +  <p>Then we can write a description of the above XML in the +     XML Schema language and save it into <code>hello.xsd</code>:</p> + +  <pre class="xml"> +<?xml version="1.0"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + +  <xs:complexType name="hello"> +    <xs:sequence> +      <xs:element name="greeting" type="xs:string"/> +      <xs:element name="name" type="xs:string" maxOccurs="unbounded"/> +    </xs:sequence> +  </xs:complexType> + +  <xs:element name="hello" type="hello"/> + +</xs:schema> +  </pre> + +  <p>Even if you are not familiar with XML Schema, it +     should be easy to connect declarations in <code>hello.xsd</code> +     to elements in <code>hello.xml</code>. The <code>hello</code> type +     is defined as a sequence of the nested <code>greeting</code> and +     <code>name</code> elements. Note that the term sequence in XML +     Schema means that elements should appear in a particular order +     as opposed to appearing multiple times. The <code>name</code> +     element has its <code>maxOccurs</code> property set to +     <code>unbounded</code> which means it can appear multiple times +     in an XML document. Finally, the globally-defined <code>hello</code> +     element prescribes the root element for our vocabulary. For an +     easily-approachable introduction to XML Schema refer to +     <a href="http://www.w3.org/TR/xmlschema-0/">XML Schema Part 0: +     Primer</a>.</p> + +  <p>The above schema is a specification of our XML vocabulary; it tells +     everybody what valid documents of our XML-based language should look +     like. The next step is to compile this schema to generate +     the object model and parsing functions.</p> + +  <h2><a name="2.2">2.2 Translating Schema to C++</a></h2> + +  <p>Now we are ready to translate our <code>hello.xsd</code> to C++ parser +     skeletons. To do this we invoke the XSD compiler from a terminal +     (UNIX) or a command prompt (Windows): +  </p> + +  <pre class="terminal"> +$ xsd cxx-parser --xml-parser expat hello.xsd +  </pre> + +  <p>The <code>--xml-parser</code> option indicates that we want to +     use Expat as the underlying XML parser (see <a href="#5.3">Section +     5.3, "Underlying XML Parser"</a>). The XSD compiler produces two +     C++ files: <code>hello-pskel.hxx</code> and <code>hello-pskel.cxx</code>. +     The following code fragment is taken from <code>hello-pskel.hxx</code>; +     it should give you an idea about what gets generated: +  </p> + +  <pre class="c++"> +class hello_pskel +{ +public: +  // Parser callbacks. Override them in your implementation. +  // +  virtual void +  pre (); + +  virtual void +  greeting (const std::string&); + +  virtual void +  name (const std::string&); + +  virtual void +  post_hello (); + +  // Parser construction API. +  // +  void +  greeting_parser (xml_schema::string_pskel&); + +  void +  name_parser (xml_schema::string_pskel&); + +  void +  parsers (xml_schema::string_pskel& /* greeting */, +           xml_schema::string_pskel& /* name */); + +private: +  ... +}; +  </pre> + +  <p>The first four member functions shown above are called parser +     callbacks. You would normally override them in your implementation +     of the parser to do something useful. Let's go through all of +     them one by one.</p> + +  <p>The <code>pre()</code> function is an initialization callback. It is +    called when a new element of type <code>hello</code> is about +    to be parsed. You would normally use this function to allocate a new +    instance of the resulting type or clear accumulators that are used +    to gather information during parsing. The default implementation +    of this function does nothing.</p> + +  <p>The <code>post_hello()</code> function is a finalization callback. Its +     name is constructed by adding the parser skeleton name to the +     <code>post_</code> prefix. The finalization callback is called when +     parsing of the element is complete and the result, if any, should +     be returned. Note that in our case the return type of +     <code>post_hello()</code> is <code>void</code> which means there +     is nothing to return. More on parser return types later. +  </p> + +  <p>You may be wondering why the finalization callback is called +     <code>post_hello()</code> instead of <code>post()</code> just +     like <code>pre()</code>. The reason for this is that +     finalization callbacks can have different return types and +     result in function signature clashes across inheritance +     hierarchies. To prevent this the signatures of finalization +     callbacks are made unique by adding the type name to their names.</p> + +  <p>The <code>greeting()</code> and <code>name()</code> functions are +     called when the <code>greeting</code> and <code>name</code> elements +     have been parsed, respectively. Their arguments are of type +     <code>std::string</code> and contain the data extracted from XML.</p> + +  <p>The last three functions are for connecting parsers to each other. +     For example, there is a predefined parser for built-in XML Schema type +     <code>string</code> in the XSD runtime. We will be using +     it to parse the contents of <code>greeting</code> and +     <code>name</code> elements, as shown in the next section.</p> + +  <h2><a name="2.3">2.3 Implementing Application Logic</a></h2> + +  <p>At this point we have all the parts we need to do something useful +     with the information stored in our XML document. The first step is +     to implement the parser: +  </p> + +  <pre class="c++"> +#include <iostream> +#include "hello-pskel.hxx" + +class hello_pimpl: public hello_pskel +{ +public: +  virtual void +  greeting (const std::string& g) +  { +    greeting_ = g; +  } + +  virtual void +  name (const std::string& n) +  { +    std::cout << greeting_ << ", " << n << "!" << std::endl; +  } + +private: +  std::string greeting_; +}; +  </pre> + +  <p>We left both <code>pre()</code> and <code>post_hello()</code> with the +     default implementations; we don't have anything to initialize or +     return. The rest is pretty straightforward: we store the greeting +     in a member variable and later, when parsing names, use it to +     say hello.</p> + +  <p>An observant reader my ask what happens if the <code>name</code> +     element comes before <code>greeting</code>? Don't we need to +     make sure <code>greeting_</code> was initialized and report +     an error otherwise? The answer is no, we don't have to do +     any of this. The <code>hello_pskel</code> parser skeleton +     performs validation of XML according to the schema from which +     it was generated. As a result, it will check the order +     of the <code>greeting</code> and <code>name</code> elements +     and report an error if it is violated.</p> + +  <p>Now it is time to put this parser implementation to work:</p> + +  <pre class="c++"> +using namespace std; + +int +main (int argc, char* argv[]) +{ +  try +  { +    // Construct the parser. +    // +    xml_schema::string_pimpl string_p; +    hello_pimpl hello_p; + +    hello_p.greeting_parser (string_p); +    hello_p.name_parser (string_p); + +    // Parse the XML instance. +    // +    xml_schema::document doc_p (hello_p, "hello"); + +    hello_p.pre (); +    doc_p.parse (argv[1]); +    hello_p.post_hello (); +  } +  catch (const xml_schema::exception& e) +  { +    cerr << e << endl; +    return 1; +  } +} +  </pre> + +  <p>The first part of this code snippet instantiates individual parsers +     and assembles them into a complete vocabulary parser. +     <code>xml_schema::string_pimpl</code> is an implementation of a parser +     for built-in XML Schema type <code>string</code>. It is provided by +     the XSD runtime along with parsers for other built-in types (for +     more information on the built-in parsers see <a href="#6">Chapter 6, +     "Built-In XML Schema Type Parsers"</a>). We use <code>string_pimpl</code> +     to parse the <code>greeting</code> and <code>name</code> elements as +     indicated by the calls to <code>greeting_parser()</code> and +     <code>name_parser()</code>. +  </p> + +  <p>Then we instantiate a document parser (<code>doc_p</code>). The +     first argument to its constructor is the parser for +     the root element (<code>hello_p</code> in our case). The +     second argument is the root element name. +   </p> + +  <p>The final piece is the calls to <code>pre()</code>, <code>parse()</code>, +     and <code>post_hello()</code>. The call to <code>parse()</code> +     perform the actual XML parsing while the calls to <code>pre()</code> and +     <code>post_hello()</code> make sure that the parser for the root +     element can perform proper initialization and cleanup.</p> + +  <p>While our parser implementation and test driver are pretty small and +     easy to write by hand, for bigger XML vocabularies it can be a +     substantial effort. To help with this task XSD can automatically +     generate sample parser implementations and a test driver from your +     schemas. You can request the generation of a sample implementation with +     empty function bodies by specifying the <code>--generate-noop-impl</code> +     option. Or you can generate a sample implementation that prints the +     data store in XML by using the <code>--generate-print-impl</code> +     option. To request the generation of a test driver you can use the +     <code>--generate-test-driver</code> option. For more information +     on these options refer to the +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD +     Compiler Command Line Manual</a>. The <code>'generated'</code> example +     in the <a href="https://cppget.org/xsd-examples">xsd-examples</a> package +     shows the sample implementation generation feature in action.</p> + + +  <h2><a name="2.4">2.4 Compiling and Running</a></h2> + +  <p>After saving all the parts from the previous section in +     <code>driver.cxx</code>, we are ready to compile our first +     application and run it on the test XML document. On a UNIX +     system this can be done with the following commands: +  </p> + +  <pre class="terminal"> +$ c++ -std=c++11 -I.../libxsd -c driver.cxx hello-pskel.cxx +$ c++ -std=c++11 -o driver driver.o hello-pskel.o -lexpat +$ ./driver hello.xml +Hello, sun! +Hello, moon! +Hello, world! +  </pre> + +  <p>Here <code>.../libxsd</code> represents the path to the +     <a href="https://cppget.org/libxsd">libxsd</a> package root +     directory. We can also test the error handling. To test XML +     well-formedness checking, we can try to parse +     <code>hello-pskel.hxx</code>:</p> + +  <pre class="terminal"> +$ ./driver hello-pskel.hxx +hello-pskel.hxx:1:0: not well-formed (invalid token) +  </pre> + +  <p>We can also try to parse a valid XML but not from our +     vocabulary, for example <code>hello.xsd</code>:</p> + +  <pre class="terminal"> +$ ./driver hello.xsd +hello.xsd:2:0: expected element 'hello' instead of +'http://www.w3.org/2001/XMLSchema#schema' +  </pre> + + +  <!-- Chapater 3 --> + + +  <h1><a name="3">3 Parser Skeletons</a></h1> + +  <p>As we have seen in the previous chapter, the XSD compiler generates +     a parser skeleton class for each type defined in XML Schema. In +     this chapter we will take a closer look at different functions +     that comprise a parser skeleton as well as the way to connect +     our implementations of these parser skeletons to create a complete +     parser.</p> + +  <p>In this and subsequent chapters we will use the following schema +     that describes a collection of person records. We save it in +     <code>people.xsd</code>:</p> + +  <pre class="xml"> +<?xml version="1.0"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + +  <xs:simpleType name="gender"> +    <xs:restriction base="xs:string"> +      <xs:enumeration value="male"/> +      <xs:enumeration value="female"/> +    </xs:restriction> +  </xs:simpleType> + +  <xs:complexType name="person"> +    <xs:sequence> +      <xs:element name="first-name" type="xs:string"/> +      <xs:element name="last-name" type="xs:string"/> +      <xs:element name="gender" type="gender"/> +      <xs:element name="age" type="xs:short"/> +    </xs:sequence> +  </xs:complexType> + +  <xs:complexType name="people"> +    <xs:sequence> +      <xs:element name="person" type="person" maxOccurs="unbounded"/> +    </xs:sequence> +  </xs:complexType> + +  <xs:element name="people" type="people"/> + +</xs:schema> +  </pre> + +  <p>A sample XML instance to go along with this schema is saved +     in <code>people.xml</code>:</p> + +  <pre class="xml"> +<?xml version="1.0"?> +<people> +  <person> +    <first-name>John</first-name> +    <last-name>Doe</last-name> +    <gender>male</gender> +    <age>32</age> +  </person> +  <person> +    <first-name>Jane</first-name> +    <last-name>Doe</last-name> +    <gender>female</gender> +    <age>28</age> +  </person> +</people> +  </pre> + +  <p>Compiling <code>people.xsd</code> with the XSD compiler results +     in three parser skeletons being generated: <code>gender_pskel</code>, +     <code>person_pskel</code>, and <code>people_pskel</code>. We are going +     to examine and implement each of them in the subsequent sections.</p> + +  <h2><a name="3.1">3.1 Implementing the Gender Parser</a></h2> + +  <p>The generated <code>gender_pskel</code> parser skeleton looks like +     this:</p> + +  <pre class="c++"> +class gender_pskel: public virtual xml_schema::string_pskel +{ +public: +  // Parser callbacks. Override them in your implementation. +  // +  virtual void +  pre (); + +  virtual void +  post_gender (); +}; +  </pre> + +  <p>Notice that <code>gender_pskel</code> inherits from +     <code>xml_schema::string_skel</code> which is a parser skeleton +     for built-in XML Schema type <code>string</code> and is +     predefined in the XSD runtime library. This is an example +     of the general rule that parser skeletons follow: if a type +     in XML Schema inherits from another then there will be an +     equivalent inheritance between the corresponding parser +     skeleton classes.</p> + +  <p>The <code>pre()</code> and <code>post_gender()</code> callbacks +     should look familiar from the previous chapter. Let's now +     implement the parser. Our implementation will simply print +     the gender to <code>cout</code>:</p> + + +  <pre class="c++"> +class gender_pimpl: public gender_pskel, +                    public xml_schema::string_pimpl +{ +public: +  virtual void +  post_gender () +  { +    std::string s = post_string (); +    cout << "gender: " << s << endl; +  } +}; +  </pre> + +  <p>While the code is quite short, there is a lot going on. First, +     notice that we are inheriting from <code>gender_pskel</code> <em>and</em> +     from <code>xml_schema::string_pimpl</code>. We've encountered +     <code>xml_schema::string_pimpl</code> already; it is an +     implementation of the <code>xml_schema::string_pskel</code> parser +     skeleton for built-in XML Schema type <code>string</code>.</p> + +  <p>This is another common theme in the C++/Parser programming model: +     reusing implementations of the base parsers in the derived ones with +     the C++ mixin idiom. In our case, <code>string_pimpl</code> will +     do all the dirty work of extracting the data and we can just get +     it at the end with the call to <code>post_string()</code>.</p> + +  <p>In case you are curious, here is what +     <code>xml_schema::string_pskel</code> and +     <code>xml_schema::string_pimpl</code> look like:</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class string_pskel: public simple_content +  { +  public: +    virtual std::string +    post_string () = 0; +  }; + +  class string_pimpl: public virtual string_pskel +  { +  public: +    virtual void +    _pre (); + +    virtual void +    _characters (const xml_schema::ro_string&); + +    virtual std::string +    post_string (); + +  protected: +    std::string str_; +  }; +} +  </pre> + +  <p>There are three new pieces in this code that we haven't seen yet. +     They are the <code>simple_content</code> class as well as +     the <code>_pre()</code> and <code>_characters()</code> functions. +     The <code>simple_content</code> class is defined in the XSD +     runtime and is a base class for all parser skeletons that conform +     to the simple content model in XML Schema. Types with the +     simple content model cannot have nested elements—only text +     and attributes. There is also the <code>complex_content</code> +     class which corresponds to the complex content mode (types with +     nested elements, for example, <code>person</code> from +     <code>people.xsd</code>).</p> + +  <p>The <code>_pre()</code> function is a parser callback. Remember we +     talked about the <code>pre()</code> and <code>post_*()</code> callbacks +     in the previous chapter? There are actually two more callbacks +     with similar roles: <code>_pre()</code> and <code>_post ()</code>. +     As a result, each parser skeleton has four special callbacks:</p> + +  <pre class="c++"> +  virtual void +  pre (); + +  virtual void +  _pre (); + +  virtual void +  _post (); + +  virtual void +  post_name (); +  </pre> + +  <p><code>pre()</code> and <code>_pre()</code> are initialization +     callbacks. They get called in that order before a new instance of the type +     is about to be parsed. The difference between <code>pre()</code> and +     <code>_pre()</code> is conventional: <code>pre()</code> can +     be completely overridden by a derived parser. The derived +     parser can also override <code>_pre()</code> but has to always call +     the original version. This allows you to partition initialization +     into customizable and required parts.</p> + +  <p>Similarly, <code>_post()</code> and <code>post_name()</code> are +     finalization callbacks with exactly the same semantics: +    <code>post_name()</code> can be completely overridden by the derived +     parser while the original <code>_post()</code> should always be called. +  </p> + +  <p>The final bit we need to discuss in this section is the +     <code>_characters()</code> function. As you might have guessed, it +     is also a callback. A low-level one that delivers raw character content +     for the type being parsed. You will seldom need to use this callback +     directly. Using implementations for the built-in parsers provided by +     the XSD runtime is usually a simpler and more convenient +     alternative.</p> + +  <p>At this point you might be wondering why some <code>post_*()</code> +     callbacks, for example <code>post_string()</code>, return some data +     while others, for example <code>post_gender()</code>, have +     <code>void</code> as a return type. This is a valid concern +     and it will be addressed in the next chapter.</p> + +  <h2><a name="3.2">3.2 Implementing the Person Parser</a></h2> + +  <p>The generated <code>person_pskel</code> parser skeleton looks like +     this:</p> + +  <pre class="c++"> +class person_pskel: public xml_schema::complex_content +{ +public: +  // Parser callbacks. Override them in your implementation. +  // +  virtual void +  pre (); + +  virtual void +  first_name (const std::string&); + +  virtual void +  last_name (const std::string&); + +  virtual void +  gender (); + +  virtual void +  age (short); + +  virtual void +  post_person (); + +  // Parser construction API. +  // +  void +  first_name_parser (xml_schema::string_pskel&); + +  void +  last_name_parser (xml_schema::string_pskel&); + +  void +  gender_parser (gender_pskel&); + +  void +  age_parser (xml_schema::short_pskel&); + +  void +  parsers (xml_schema::string_pskel& /* first-name */, +           xml_schema::string_pskel& /* last-name */, +           gender_pskel&             /* gender */, +           xml_schema::short_pskel&  /* age */); +}; +  </pre> + + +  <p>As you can see, we have a parser callback for each of the nested +     elements found in the <code>person</code> XML Schema type. +     The implementation of this parser is straightforward:</p> + +  <pre class="c++"> +class person_pimpl: public person_pskel +{ +public: +  virtual void +  first_name (const std::string& n) +  { +    cout << "first: " << f << endl; +  } + +  virtual void +  last_name (const std::string& l) +  { +    cout << "last: " << l << endl; +  } + +  virtual void +  age (short a) +  { +    cout << "age: " << a << endl; +  } +}; +  </pre> + +  <p>Notice that we didn't override the <code>gender()</code> callback +     because all the printing is done by <code>gender_pimpl</code>.</p> + + +  <h2><a name="3.3">3.3 Implementing the People Parser</a></h2> + +  <p>The generated <code>people_pskel</code> parser skeleton looks like +     this:</p> + +  <pre class="c++"> +class people_pskel: public xml_schema::complex_content +{ +public: +  // Parser callbacks. Override them in your implementation. +  // +  virtual void +  pre (); + +  virtual void +  person (); + +  virtual void +  post_people (); + +  // Parser construction API. +  // +  void +  person_parser (person_pskel&); + +  void +  parsers (person_pskel& /* person */); +}; +  </pre> + +  <p>The <code>person()</code> callback will be called after parsing each +     <code>person</code> element. While <code>person_pimpl</code> does +     all the printing, one useful thing we can do in this callback is to +     print an extra newline after each person record so that our +     output is more readable:</p> + +  <pre class="c++"> +class people_pimpl: public people_pskel +{ +public: +  virtual void +  person () +  { +    cout << endl; +  } +}; +  </pre> + +  <p>Now it is time to put everything together.</p> + + +  <h2><a name="3.4">3.4 Connecting the Parsers Together</a></h2> + +  <p>At this point we have all the individual parsers implemented +     and can proceed to assemble them into a complete parser +     for our XML vocabulary. The first step is to instantiate +     all the individual parsers that we will need:</p> + +  <pre class="c++"> +xml_schema::short_pimpl short_p; +xml_schema::string_pimpl string_p; + +gender_pimpl gender_p; +person_pimpl person_p; +people_pimpl people_p; +  </pre> + +  <p>Notice that our schema uses two built-in XML Schema types: +     <code>string</code> for the <code>first-name</code> and +     <code>last-name</code> elements as well as <code>short</code> +     for <code>age</code>. We will use predefined parsers that +     come with the XSD runtime to handle these types. The next +     step is to connect all the individual parsers. We do this +     with the help of functions defined in the parser +     skeletons and marked with the "Parser Construction API" +     comment. One way to do it is to connect each individual +     parser by calling the <code>*_parser()</code> functions:</p> + +  <pre class="c++"> +person_p.first_name_parser (string_p); +person_p.last_name_parser (string_p); +person_p.gender_parser (gender_p); +person_p.age_parser (short_p); + +people_p.person_parser (person_p); +  </pre> + +  <p>You might be wondering what happens if you do not provide +     a parser by not calling one of the <code>*_parser()</code> functions. +     In that case the corresponding XML content will be skipped, +     including validation. This is an efficient way to ignore parts +     of the document that you are not interested in.</p> + + +  <p>An alternative, shorter, way to connect the parsers is by using +     the <code>parsers()</code> functions which connects all the parsers +     for a given type at once:</p> + +  <pre class="c++"> +person_p.parsers (string_p, string_p, gender_p, short_p); +people_p.parsers (person_p); +  </pre> + +  <p>The following figure illustrates the resulting connections. Notice +     the correspondence between return types of the <code>post_*()</code> +     functions and argument types of element callbacks that are connected +     by the arrows.</p> + +  <!-- align=center is needed for html2ps --> +  <div class="img" align="center"><img src="figure-1.png"/></div> + +  <p>The last step is the construction of the document parser and +     invocation of the complete parser on our sample XML instance:</p> + +  <pre class="c++"> +xml_schema::document doc_p (people_p, "people"); + +people_p.pre (); +doc_p.parse ("people.xml"); +people_p.post_people (); +  </pre> + +  <p>Let's consider <code>xml_schema::document</code> in +     more detail. While the exact definition of this class +     varies depending on the underlying parser selected, +     here is the common part:</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class document +  { +  public: +    document (xml_schema::parser_base&, +              const std::string& root_element_name, +              bool polymorphic = false); + +    document (xml_schema::parser_base&, +              const std::string& root_element_namespace, +              const std::string& root_element_name, +              bool polymorphic = false); + +    void +    parse (const std::string& file); + +    void +    parse (std::istream&); + +    ... + +  }; +} +  </pre> + +   <p><code>xml_schema::document</code> is a root parser for +     the vocabulary. The first argument to its constructors is the +     parser for the type of the root element (<code>people_impl</code> +     in our case). Because a type parser is only concerned with +     the element's content and not with the element's name, we need +     to specify the root element's name somewhere. That's +     what is passed as the second and third arguments to the +     <code>document</code>'s constructors.</p> + +   <p>There are also two overloaded <code>parse()</code> functions +      defined in the <code>document</code> class (there are actually +      more but the others are specific to the underlying XML parser). +      The first version parses a local file identified by a name. The +      second version reads the data from an input stream. For more +      information on the <code>xml_schema::document</code> class +      refer to <a href="#7">Chapter 7, "Document Parser and Error +      Handling"</a>.</p> + +   <p>Let's now consider a step-by-step list of actions that happen +      as we parse through <code>people.xml</code>. The content of +      <code>people.xml</code> is repeated below for convenience.</p> + +  <pre class="xml"> +<?xml version="1.0"?> +<people> +  <person> +    <first-name>John</first-name> +    <last-name>Doe</last-name> +    <gender>male</gender> +    <age>32</age> +  </person> +  <person> +    <first-name>Jane</first-name> +    <last-name>Doe</last-name> +    <gender>female</gender> +    <age>28</age> +  </person> +</people> +  </pre> + + +   <ol class="steps"> +     <li><code>people_p.pre()</code> is called from +         <code>main()</code>. We did not provide any implementation +         for this callback so this call is a no-op.</li> + +     <li><code>doc_p.parse("people.xml")</code> is called from +         <code>main()</code>. The parser opens the file and starts +         parsing its content.</li> + +     <li>The parser encounters the root element. <code>doc_p</code> +         verifies that the root element is correct and calls +         <code>_pre()</code> on <code>people_p</code> which is also +         a no-op. Parsing is now delegated to <code>people_p</code>.</li> + +     <li>The parser encounters the <code>person</code> element. +         <code>people_p</code> determines that <code>person_p</code> +         is responsible for parsing this element. <code>pre()</code> +         and <code>_pre()</code> callbacks are called on <code>person_p</code>. +         Parsing is now delegated to <code>person_p</code>.</li> + +     <li>The parser encounters the <code>first-name</code> element. +         <code>person_p</code> determines that <code>string_p</code> +         is responsible for parsing this element. <code>pre()</code> +         and <code>_pre()</code> callbacks are called on <code>string_p</code>. +         Parsing is now delegated to <code>string_p</code>.</li> + +     <li>The parser encounters character content consisting of +         <code>"John"</code>. The <code>_characters()</code> callback is +         called on <code>string_p</code>.</li> + +     <li>The parser encounters the end of <code>first-name</code> +         element. The <code>_post()</code> and <code>post_string()</code> +         callbacks are called on <code>string_p</code>. The +         <code>first_name()</code> callback is called on <code>person_p</code> +         with the return value of <code>post_string()</code>. The +         <code>first_name()</code> implementation prints +         <code>"first: John"</code> to <code>cout</code>. +         Parsing is now returned to <code>person_p</code>.</li> + +     <li>Steps analogous to 5-7 are performed for the <code>last-name</code>, +         <code>gender</code>, and <code>age</code> elements.</li> + +     <li>The parser encounters the end of <code>person</code> +         element. The <code>_post()</code> and <code>post_person()</code> +         callbacks are called on <code>person_p</code>. The +         <code>person()</code> callback is called on <code>people_p</code>. +         The <code>person()</code> implementation prints a new line +         to <code>cout</code>. Parsing is now returned to +         <code>people_p</code>.</li> + +     <li>Steps 4-9 are performed for the second <code>person</code> +         element.</li> + +     <li>The parser encounters the end of <code>people</code> +         element. The <code>_post()</code> callback is called on +         <code>people_p</code>. The <code>doc_p.parse("people.xml")</code> +         call returns to <code>main()</code>.</li> + +     <li><code>people_p.post_people()</code> is called from +         <code>main()</code> which is a no-op.</li> + +   </ol> + + +  <!-- Chpater 4 --> + + +  <h1><a name="4">4 Type Maps</a></h1> + +  <p>There are many useful things you can do inside parser callbacks as they +     are right now. There are, however, times when you want to propagate +     some information from one parser to another or to the caller of the +     parser. One common task that would greatly benefit from such a +     possibility is building a tree-like in-memory object model of the +     data stored in XML. During execution, each individual sub-parser +     would create a sub-tree and return it to its <em>parent</em> parser +     which can then incorporate this sub-tree into the whole tree.</p> + +  <p>In this chapter we will discuss the mechanisms offered by the +     C++/Parser mapping for returning information from individual +     parsers and see how to use them to build an object model +     of our people vocabulary.</p> + +  <h2><a name="4.1">4.1 Object Model</a></h2> + +  <p>An object model for our person record example could +     look like this (saved in the <code>people.hxx</code> file):</p> + +  <pre class="c++"> +#include <string> +#include <vector> + +enum gender +{ +  male, +  female +}; + +class person +{ +public: +  person (const std::string& first, +          const std::string& last, +          ::gender gender, +          short age) +    : first_ (first), last_ (last), +      gender_ (gender), age_ (age) +  { +  } + +  const std::string& +  first () const +  { +    return first_; +  } + +  const std::string& +  last () const +  { +    return last_; +  } + +  ::gender +  gender () const +  { +    return gender_; +  } + +  short +  age () const +  { +    return age_; +  } + +private: +  std::string first_; +  std::string last_; +  ::gender gender_; +  short age_; +}; + +typedef std::vector<person> people; +  </pre> + +  <p>While it is clear which parser is responsible for which part of +     the object model, it is not exactly clear how, for +     example, <code>gender_pimpl</code> will deliver <code>gender</code> +     to <code>person_pimpl</code>. You might have noticed that +     <code>string_pimpl</code> manages to deliver its value to the +     <code>first_name()</code> callback of <code>person_pimpl</code>. Let's +     see how we can utilize the same mechanism to propagate our +     own data.</p> + +  <p>There is a way to tell the XSD compiler that you want to +     exchange data between parsers. More precisely, for each +     type defined in XML Schema, you can tell the compiler two things. +     First, the return type of the <code>post_*()</code> callback +     in the parser skeleton generated for this type. And, second, +     the argument type for callbacks corresponding to elements and +     attributes of this type. For example, for XML Schema type +     <code>gender</code> we can specify the return type for +     <code>post_gender()</code> in the <code>gender_pskel</code> +     skeleton and the argument type for the <code>gender()</code> callback +     in the <code>person_pskel</code> skeleton. As you might have guessed, +     the generated code will then pass the return value from the +     <code>post_*()</code> callback as an argument to the element or +     attribute callback.</p> + +  <p>The way to tell the XSD compiler about these XML Schema to +     C++ mappings is with type map files. Here is a simple type +     map for the <code>gender</code> type from the previous paragraph:</p> + +  <pre class="type-map"> +include "people.hxx"; +gender ::gender ::gender; +  </pre> + +  <p>The first line indicates that the generated code must include +     <code>people.hxx</code> in order to get the definition for the +     <code>gender</code> type. The second line specifies that both +     argument and return types for the <code>gender</code> +     XML Schema type should be the <code>::gender</code> C++ enum +     (we use fully-qualified C++ names to avoid name clashes). +     The next section will describe the type map format in detail. +     We save this type map in <code>people.map</code> and +     then translate our schemas with the <code>--type-map</code> +     option to let the XSD compiler know about our type map:</p> + +  <pre class="terminal"> +$ xsd cxx-parser --type-map people.map people.xsd +  </pre> + +  <p>If we now look at the generated <code>people-pskel.hxx</code>, +     we will see the following changes in the <code>gender_pskel</code> and +     <code>person_pskel</code> skeletons:</p> + +  <pre class="c++"> +#include "people.hxx" + +class gender_pskel: public virtual xml_schema::string_pskel +{ +  virtual ::gender +  post_gender () = 0; + +  ... +}; + +class person_pskel: public xml_schema::complex_content +{ +  virtual void +  gender (::gender); + +  ... +}; +  </pre> + +  <p>Notice that <code>#include "people.hxx"</code> was added to +     the generated header file from the type map to provide the +     definition for the <code>gender</code> enum.</p> + +  <h2><a name="4.2">4.2 Type Map File Format</a></h2> + +  <p>Type map files are used to define a mapping between XML Schema +     and C++ types. The compiler uses this information +     to determine return types of <code>post_*()</code> +     callbacks in parser skeletons corresponding to XML Schema +     types as well as argument types for callbacks corresponding +     to elements and attributes of these types.</p> + +  <p>The compiler has a set of predefined mapping rules that map +     the built-in XML Schema types to suitable C++ types (discussed +     below) and all other types to <code>void</code>. +     By providing your own type maps you can override these predefined +     rules. The format of the type map file is presented below: +  </p> + +  <pre class="type-map"> +namespace <schema-namespace> [<cxx-namespace>] +{ +  (include <file-name>;)* +  ([type] <schema-type> <cxx-ret-type> [<cxx-arg-type>];)* +} +  </pre> + +  <p>Both <code><i><schema-namespace></i></code> and +     <code><i><schema-type></i></code> are regex patterns while +     <code><i><cxx-namespace></i></code>, +     <code><i><cxx-ret-type></i></code>, and +     <code><i><cxx-arg-type></i></code> are regex pattern +     substitutions. All names can be optionally enclosed in +     <code>" "</code>, for example, to include white-spaces.</p> + +  <p><code><i><schema-namespace></i></code> determines XML +     Schema namespace. Optional <code><i><cxx-namespace></i></code> +     is prefixed to every C++ type name in this namespace declaration. +     <code><i><cxx-ret-type></i></code> is a C++ type name that is +     used as a return type for the <code>post_*()</code> callback. +     Optional <code><i><cxx-arg-type></i></code> is an argument +     type for callbacks corresponding to elements and attributes +     of this type. If <code><i><cxx-arg-type></i></code> is not +     specified, it defaults to <code><i><cxx-ret-type></i></code> +     if <code><i><cxx-ret-type></i></code> ends with <code>*</code> or +     <code>&</code> (that is, it is a pointer or a reference) and +     <code>const <i><cxx-ret-type></i>&</code> +     otherwise. +     <code><i><file-name></i></code> is a file name either in the +     <code>" "</code> or <code>< ></code> format +     and is added with the <code>#include</code> directive to +     the generated code.</p> + +  <p>The <code><b>#</b></code> character starts a comment that ends +     with a new line or end of file. To specify a name that contains +     <code><b>#</b></code> enclose it in <code><b>" "</b></code>. +     For example:</p> + +  <pre> +namespace http://www.example.com/xmlns/my my +{ +  include "my.hxx"; + +  # Pass apples by value. +  # +  apple apple; + +  # Pass oranges as pointers. +  # +  orange orange_t*; +} +  </pre> + +  <p>In the example above, for the +     <code>http://www.example.com/xmlns/my#orange</code> +     XML Schema type, the <code>my::orange_t*</code> C++ type will +     be used as both return and argument types.</p> + +  <p>Several namespace declarations can be specified in a single +     file. The namespace declaration can also be completely +     omitted to map types in a schema without a namespace. For +     instance:</p> + +  <pre class="type-map"> +include "my.hxx"; +apple apple; + +namespace http://www.example.com/xmlns/my +{ +  orange "const orange_t*"; +} +  </pre> + +  <p>The compiler has a number of predefined mapping rules for +     the built-in XML Schema types which can be presented as the +     following map files. The string-based XML Schema types are +     mapped to either <code>std::string</code> or +     <code>std::wstring</code> depending on the character type +     selected (see <a href="#5.2"> Section 5.2, "Character Type and +     Encoding"</a> for more information). The binary XML Schema +     types are mapped to either <code>std::unique_ptr<xml_schema::buffer></code> +     or <code>std::auto_ptr<xml_schema::buffer></code> +     depending on the C++ standard selected (C++11 or C++98, +     respectively; refer to the <code>--std</code> XSD compiler +     command line option for details).</p> + +  <pre class="type-map"> +namespace http://www.w3.org/2001/XMLSchema +{ +  boolean bool bool; + +  byte "signed char" "signed char"; +  unsignedByte "unsigned char" "unsigned char"; + +  short short short; +  unsignedShort "unsigned short" "unsigned short"; + +  int int int; +  unsignedInt "unsigned int" "unsigned int"; + +  long "long long" "long long"; +  unsignedLong "unsigned long long" "unsigned long long"; + +  integer "long long" "long long"; + +  negativeInteger "long long" "long long"; +  nonPositiveInteger "long long" "long long"; + +  positiveInteger "unsigned long long" "unsigned long long"; +  nonNegativeInteger "unsigned long long" "unsigned long long"; + +  float float float; +  double double double; +  decimal double double; + +  string std::string; +  normalizedString std::string; +  token std::string; +  Name std::string; +  NMTOKEN std::string; +  NCName std::string; +  ID std::string; +  IDREF std::string; +  language std::string; +  anyURI std::string; + +  NMTOKENS xml_schema::string_sequence; +  IDREFS xml_schema::string_sequence; + +  QName xml_schema::qname; + +  base64Binary std::[unique|auto]_ptr<xml_schema::buffer> +               std::[unique|auto]_ptr<xml_schema::buffer>; +  hexBinary std::[unique|auto]_ptr<xml_schema::buffer> +            std::[unique|auto]_ptr<xml_schema::buffer>; + +  date xml_schema::date; +  dateTime xml_schema::date_time; +  duration xml_schema::duration; +  gDay xml_schema::gday; +  gMonth xml_schema::gmonth; +  gMonthDay xml_schema::gmonth_day; +  gYear xml_schema::gyear; +  gYearMonth xml_schema::gyear_month; +  time xml_schema::time; +} +  </pre> + +  <p>For more information about the mapping of the built-in XML Schema types +     to C++ types refer to <a href="#6">Chapter 6, "Built-In XML Schema Type +     Parsers"</a>. The last predefined rule maps anything that wasn't +     mapped by previous rules to <code>void</code>:</p> + +  <pre class="type-map"> +namespace .* +{ +  .* void void; +} +  </pre> + + +  <p>When you provide your own type maps with the +     <code>--type-map</code> option, they are evaluated first. This +     allows you to selectively override any of the predefined rules. +     Note also that if you change the mapping +     of a built-in XML Schema type then it becomes your responsibility +     to provide the corresponding parser skeleton and implementation +     in the <code>xml_schema</code> namespace. You can include the +     custom definitions into the generated header file using the +     <code>--hxx-prologue-*</code> options.</p> + +  <h2><a name="4.3">4.3 Parser Implementations</a></h2> + +  <p>With the knowledge from the previous section, we can proceed +     with creating a type map that maps types in the <code>people.xsd</code> +     schema to our object model classes in +     <code>people.hxx</code>. In fact, we already have the beginning +     of our type map file in <code>people.map</code>. Let's extend +     it with the rest of the types:</p> + +  <pre class="type-map"> +include "people.hxx"; + +gender ::gender ::gender; +person ::person; +people ::people; +  </pre> + +  <p>There are a few things to note about this type map. We did not +     provide the argument types for <code>person</code> and +     <code>people</code> because the default constant reference is +     exactly what we need. We also did not provide any mappings +     for built-in XML Schema types <code>string</code> and +     <code>short</code> because they are handled by the predefined +     rules and we are happy with the result. Note also that +     all C++ types are fully qualified. This is done to avoid +     potential name conflicts in the generated code. Now we can +     recompile our schema and move on to implementing the parsers:</p> + +  <pre class="terminal"> +$ xsd cxx-parser --xml-parser expat --type-map people.map people.xsd +  </pre> + +  <p>Here is the implementation of our three parsers in full. One +     way to save typing when implementing your own parsers is +     to open the generated code and copy the signatures of parser +     callbacks into your code. Or you could always auto generate the +     sample implementations and fill them with your code.</p> + + +  <pre class="c++"> +#include "people-pskel.hxx" + +class gender_pimpl: public gender_pskel, +                    public xml_schema::string_pimpl +{ +public: +  virtual ::gender +  post_gender () +  { +    return post_string () == "male" ? male : female; +  } +}; + +class person_pimpl: public person_pskel +{ +public: +  virtual void +  first_name (const std::string& f) +  { +    first_ = f; +  } + +  virtual void +  last_name (const std::string& l) +  { +    last_ = l; +  } + +  virtual void +  gender (::gender g) +  { +    gender_ = g; +  } + +  virtual void +  age (short a) +  { +    age_ = a; +  } + +  virtual ::person +  post_person () +  { +    return ::person (first_, last_, gender_, age_); +  } + +private: +  std::string first_; +  std::string last_; +  ::gender gender_; +  short age_; +}; + +class people_pimpl: public people_pskel +{ +public: +  virtual void +  person (const ::person& p) +  { +    people_.push_back (p); +  } + +  virtual ::people +  post_people () +  { +    ::people r; +    r.swap (people_); +    return r; +  } + +private: +  ::people people_; +}; +  </pre> + +  <p>This code fragment should look familiar by now. Just note that +     all the <code>post_*()</code> callbacks now have return types instead +     of <code>void</code>. Here is the implementation of the test +     driver for this example:</p> + +  <pre class="c++"> +#include <iostream> + +using namespace std; + +int +main (int argc, char* argv[]) +{ +  // Construct the parser. +  // +  xml_schema::short_pimpl short_p; +  xml_schema::string_pimpl string_p; + +  gender_pimpl gender_p; +  person_pimpl person_p; +  people_pimpl people_p; + +  person_p.parsers (string_p, string_p, gender_p, short_p); +  people_p.parsers (person_p); + +  // Parse the document to obtain the object model. +  // +  xml_schema::document doc_p (people_p, "people"); + +  people_p.pre (); +  doc_p.parse (argv[1]); +  people ppl = people_p.post_people (); + +  // Print the object model. +  // +  for (people::iterator i (ppl.begin ()); i != ppl.end (); ++i) +  { +    cout << "first:  " << i->first () << endl +         << "last:   " << i->last () << endl +         << "gender: " << (i->gender () == male ? "male" : "female") << endl +         << "age:    " << i->age () << endl +         << endl; +  } +} +  </pre> + +  <p>The parser creation and assembly part is exactly the same as in +     the previous chapter. The parsing part is a bit different: +     <code>post_people()</code> now has a return value which is the +     complete object model. We store it in the +     <code>ppl</code> variable. The last bit of the code simply iterates +     over the <code>people</code> vector and prints the information +     for each person. We save the last two code fragments to +     <code>driver.cxx</code> and proceed to compile and test +     our new application:</p> + + +  <pre class="terminal"> +$ c++ -std=c++11 -I.../libxsd -c driver.cxx people-pskel.cxx +$ c++ -std=c++11 -o driver driver.o people-pskel.o -lexpat +$ ./driver people.xml +first:  John +last:   Doe +gender: male +age:    32 + +first:  Jane +last:   Doe +gender: female +age:    28 +  </pre> + + +  <!-- Mapping Configuration --> + + +  <h1><a name="5">5 Mapping Configuration</a></h1> + +  <p>The C++/Parser mapping has a number of configuration parameters that +     determine the overall properties and behavior of the generated code. +     Configuration parameters are specified with the XSD command line +     options and include the C++ standard, the character type that is used +     by the generated code, the underlying XML parser, whether the XML Schema +     validation is performed in the generated code, and support for XML Schema +     polymorphism. This chapter describes these configuration +     parameters in more detail. For more ways to configure the generated +     code refer to the +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD +     Compiler Command Line Manual</a>. +  </p> + +  <h2><a name="5.1">5.1 C++ Standard</a></h2> + +  <p>The C++/Parser mapping provides support for ISO/IEC C++ 2011 (C++11) +     and ISO/IEC C++ 1998/2003 (C++98). To select the C++ standard for the +     generated code we use the <code>--std</code> XSD compiler command +     line option. While the majority of the examples in this guide use +     C++11, the document explains the C++11/98 usage difference and so +     they can easily be converted to C++98.</p> + +  <h2><a name="5.2">5.2 Character Type and Encoding</a></h2> + +  <p>The C++/Parser mapping has built-in support for two character types: +    <code>char</code> and <code>wchar_t</code>. You can select the +    character type with the <code>--char-type</code> command line +    option. The default character type is <code>char</code>. The +    string-based built-in XML Schema types are returned as either +    <code>std::string</code> or <code>std::wstring</code> depending +    on the character type selected.</p> + +  <p>Another aspect of the mapping that depends on the character type +     is character encoding. For the <code>char</code> character type +     the default encoding is UTF-8. Other supported encodings are +     ISO-8859-1, Xerces-C++ Local Code Page (LPC), as well as +     custom encodings. You can select which encoding should be used +     in the object model with the <code>--char-encoding</code> command +     line option.</p> + +  <p>For the <code>wchar_t</code> character type the encoding is +     automatically selected between UTF-16 and UTF-32/UCS-4 depending +     on the size of the <code>wchar_t</code> type. On some platforms +     (for example, Windows with Visual C++ and AIX with IBM XL C++) +     <code>wchar_t</code> is 2 bytes long. For these platforms the +     encoding is UTF-16. On other platforms <code>wchar_t</code> is 4 bytes +     long and UTF-32/UCS-4 is used.</p> + +  <p>Note also that the character encoding that is used in the object model +     is independent of the encodings used in input and output XML. In fact, +     all three (object mode, input XML, and output XML) can have different +     encodings.</p> + +  <h2><a name="5.3">5.3 Underlying XML Parser</a></h2> + +  <p>The C++/Parser mapping can be used with either Xerces-C++ or Expat +     as the underlying XML parser. You can select the XML parser with +     the <code>--xml-parser</code> command line option. Valid values +     for this option are <code>xerces</code> and <code>expat</code>. +     The default XML parser is Xerces-C++.</p> + +  <p>The generated code is identical for both parsers except for the +     <code>xml_schema::document</code> class in which some of the +     <code>parse()</code> functions are parser-specific as described +     in <a href="#7">Chapter 7, "Document Parser and Error Handling"</a>.</p> + + +  <h2><a name="5.4">5.4 XML Schema Validation</a></h2> + +  <p>The C++/Parser mapping provides support for validating a +     commonly-used subset of W3C XML Schema in the generated code. +     For the list of supported XML Schema constructs refer to +     <a href="#A">Appendix A, "Supported XML Schema Constructs"</a>.</p> + +  <p>By default validation in the generated code is disabled if +     the underlying XML parser is validating (Xerces-C++) and +     enabled otherwise (Expat). See <a href="#5.3">Section 5.3, +     "Underlying XML Parser"</a> for more information about +     the underlying XML parser. You can override the default +     behavior with the <code>--generate-validation</code> +     and <code>--suppress-validation</code> command line options.</p> + + +  <h2><a name="5.5">5.5 Support for Polymorphism</a></h2> + +  <p>By default the XSD compiler generates non-polymorphic code. If your +     vocabulary uses XML Schema polymorphism in the form of <code>xsi:type</code> +     and/or substitution groups, then you will need to compile your schemas +     with the <code>--generate-polymorphic</code> option to produce +     polymorphism-aware code as well as pass <code>true</code> as the last +     argument to the <code>xml_schema::document</code>'s constructors.</p> + +  <p>When using the polymorphism-aware generated code, you can specify +     several parsers for a single element by passing a parser map +     instead of an individual parser to the parser connection function +     for the element. One of the parsers will then be looked up and used +     depending on the <code>xsi:type</code> attribute value or an element +     name from a substitution group. Consider the following schema as an +     example:</p> + +  <pre class="xml"> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + +  <xs:complexType name="person"> +    <xs:sequence> +      <xs:element name="name" type="xs:string"/> +    </xs:sequence> +  </xs:complexType> + +  <!-- substitution group root --> +  <xs:element name="person" type="person"/> + +  <xs:complexType name="superman"> +    <xs:complexContent> +      <xs:extension base="person"> +        <xs:attribute name="can-fly" type="xs:boolean"/> +      </xs:extension> +    </xs:complexContent> +  </xs:complexType> + +  <xs:element name="superman" +              type="superman" +              substitutionGroup="person"/> + +  <xs:complexType name="batman"> +    <xs:complexContent> +      <xs:extension base="superman"> +        <xs:attribute name="wing-span" type="xs:unsignedInt"/> +      </xs:extension> +    </xs:complexContent> +  </xs:complexType> + +  <xs:element name="batman" +              type="batman" +              substitutionGroup="superman"/> + +  <xs:complexType name="supermen"> +    <xs:sequence> +      <xs:element ref="person" maxOccurs="unbounded"/> +    </xs:sequence> +  </xs:complexType> + +  <xs:element name="supermen" type="supermen"/> + +</xs:schema> +  </pre> + +  <p>Conforming XML documents can use the <code>superman</code> +     and <code>batman</code> types in place of the <code>person</code> +     type either by specifying the type with the <code>xsi:type</code> +     attributes or by using the elements from the substitution +     group, for instance:</p> + + +  <pre class="xml"> +<supermen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + +  <person> +    <name>John Doe</name> +  </person> + +  <superman can-fly="false"> +    <name>James "007" Bond</name> +  </superman> + +  <superman can-fly="true" wing-span="10" xsi:type="batman"> +    <name>Bruce Wayne</name> +  </superman> + +</supermen> +  </pre> + +  <p>To print the data stored in such XML documents we can implement +     the parsers as follows:</p> + +  <pre class="c++"> +class person_pimpl: public virtual person_pskel +{ +public: +  virtual void +  pre () +  { +    cout << "starting to parse person" << endl; +  } + +  virtual void +  name (const std::string& v) +  { +    cout << "name: " << v << endl; +  } + +  virtual void +  post_person () +  { +    cout << "finished parsing person" << endl; +  } +}; + +class superman_pimpl: public virtual superman_pskel, +                      public person_pimpl +{ +public: +  virtual void +  pre () +  { +    cout << "starting to parse superman" << endl; +  } + +  virtual void +  can_fly (bool v) +  { +    cout << "can-fly: " << v << endl; +  } + +  virtual void +  post_person () +  { +    post_superman (); +  } + +  virtual void +  post_superman () +  { +    cout << "finished parsing superman" << endl +  } +}; + +class batman_pimpl: public virtual batman_pskel, +                    public superman_pimpl +{ +public: +  virtual void +  pre () +  { +    cout << "starting to parse batman" << endl; +  } + +  virtual void +  wing_span (unsigned int v) +  { +    cout << "wing-span: " << v << endl; +  } + +  virtual void +  post_superman () +  { +    post_batman (); +  } + +  virtual void +  post_batman () +  { +    cout << "finished parsing batman" << endl; +  } +}; +  </pre> + +  <p>Note that because the derived type parsers (<code>superman_pskel</code> +     and <code>batman_pskel</code>) are called via the <code>person_pskel</code> +     interface, we have to override the <code>post_person()</code> +     virtual function in <code>superman_pimpl</code> to call +     <code>post_superman()</code> and the <code>post_superman()</code> +     virtual function in <code>batman_pimpl</code> to call +     <code>post_batman()</code>.</p> + +  <p>The following code fragment shows how to connect the parsers together. +     Notice that for the <code>person</code> element in the <code>supermen_p</code> +     parser we specify a parser map instead of a specific parser and we pass +     <code>true</code> as the last argument to the document parser constructor +     to indicate that we are parsing potentially-polymorphic XML documents:</p> + +  <pre class="c++"> +int +main (int argc, char* argv[]) +{ +  // Construct the parser. +  // +  xml_schema::string_pimpl string_p; +  xml_schema::boolean_pimpl boolean_p; +  xml_schema::unsigned_int_pimpl unsigned_int_p; + +  person_pimpl person_p; +  superman_pimpl superman_p; +  batman_pimpl batman_p; + +  xml_schema::parser_map_impl person_map; +  supermen_pimpl supermen_p; + +  person_p.parsers (string_p); +  superman_p.parsers (string_p, boolean_p); +  batman_p.parsers (string_p, boolean_p, unsigned_int_p); + +  // Here we are specifying a parser map which containes several +  // parsers that can be used to parse the person element. +  // +  person_map.insert (person_p); +  person_map.insert (superman_p); +  person_map.insert (batman_p); + +  supermen_p.person_parser (person_map); + +  // Parse the XML document. The last argument to the document's +  // constructor indicates that we are parsing polymorphic XML +  // documents. +  // +  xml_schema::document doc_p (supermen_p, "supermen", true); + +  supermen_p.pre (); +  doc_p.parse (argv[1]); +  supermen_p.post_supermen (); +} +  </pre> + +  <p>When polymorphism-aware code is generated, each element's +     <code>*_parser()</code> function is overloaded to also accept +     an object of the <code>xml_schema::parser_map</code> type. +     For example, the <code>supermen_pskel</code> class from the +     above example looks like this:</p> + +  <pre class="c++"> +class supermen_pskel: public xml_schema::parser_complex_content +{ +public: + +  ... + +  // Parser construction API. +  // +  void +  parsers (person_pskel&); + +  // Individual element parsers. +  // +  void +  person_parser (person_pskel&); + +  void +  person_parser (const xml_schema::parser_map&); + +  ... +}; +  </pre> + +  <p>Note that you can specify both the individual (static) parser and +     the parser map. The individual parser will be used when the static +     element type and the dynamic type of the object being parsed are +     the same. This is the case, for example, when there is no +     <code>xsi:type</code> attribute and the element hasn't been +     substituted. Because the individual parser for an element is +     cached and no map lookup is necessary, it makes sense to specify +     both the individual parser and the parser map when most of the +     objects being parsed are of the static type and optimal +     performance is important. The following code fragment shows +     how to change the above example to set both the individual +     parser and the parser map:</p> + +  <pre class="c++"> +int +main (int argc, char* argv[]) +{ +  ... + +  person_map.insert (superman_p); +  person_map.insert (batman_p); + +  supermen_p.person_parser (person_p); +  supermen_p.person_parser (person_map); + +  ... +} +  </pre> + + +  <p>The <code>xml_schema::parser_map</code> interface and the +     <code>xml_schema::parser_map_impl</code> default implementation +     are presented below:</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class parser_map +  { +  public: +    virtual parser_base* +    find (const ro_string* type) const = 0; +  }; + +  class parser_map_impl: public parser_map +  { +  public: +    void +    insert (parser_base&); + +    virtual parser_base* +    find (const ro_string* type) const; + +  private: +    parser_map_impl (const parser_map_impl&); + +    parser_map_impl& +    operator= (const parser_map_impl&); + +    ... +  }; +} +  </pre> + +  <p>The <code>type</code> argument in the <code>find()</code> virtual +     function is the type name and namespace from the xsi:type attribute +     (the namespace prefix is resolved to the actual XML namespace) +     or the type of an element from the substitution group in the form +     <code>"<name> <namespace>"</code> with the space and the +     namespace part absent if the type does not have a namespace. +     You can obtain a parser's dynamic type in the same format +     using the <code>_dynamic_type()</code> function. The static +     type can be obtained by calling the static <code>_static_type()</code> +     function, for example <code>person_pskel::_static_type()</code>. +     Both functions return a C string (<code>const char*</code> or +     <code>const wchar_t*</code>, depending on the character type +     used) which is valid for as long as the application is running. +     The following example shows how we can implement our own parser +     map using <code>std::map</code>:</p> + + +  <pre class="c++"> +#include <map> +#include <string> + +class parser_map: public xml_schema::parser_map +{ +public: + void + insert (xml_schema::parser_base& p) + { +   map_[p._dynamic_type ()] = &p; + } + + virtual xml_schema::parser_base* + find (const xml_schema::ro_string* type) const + { +   map::const_iterator i = map_.find (type); +   return i != map_.end () ? i->second : 0; + } + +private: +  typedef std::map<std::string, xml_schema::parser_base*> map; +  map map_; +}; +  </pre> + +  <p>Most of code presented in this section is taken from the +     <code>polymorphism</code> example which can be found in the +     <code>cxx/parser/</code> directory in the +     <a href="https://cppget.org/xsd-examples">xsd-examples</a> package. +     Handling of <code>xsi:type</code> and substitution groups when used on +     root elements requires a number of special actions as shown in +     the <code>polyroot</code> example.</p> + + +  <!-- Built-in XML Schema Type Parsers --> + + +  <h1><a name="6">6 Built-In XML Schema Type Parsers</a></h1> + +  <p>The XSD runtime provides parser implementations for all built-in +     XML Schema types as summarized in the following table. Declarations +     for these types are automatically included into each generated +     header file. As a result you don't need to include any headers +     to gain access to these parser implementations. Note that some +     parsers return either <code>std::string</code> or +     <code>std::wstring</code> depending on the character type selected.</p> + +  <!-- border="1" is necessary for html2ps --> +  <table id="builtin" border="1"> +    <tr> +      <th>XML Schema type</th> +      <th>Parser implementation in the <code>xml_schema</code> namespace</th> +      <th>Parser return type</th> +    </tr> + +    <tr> +      <th colspan="3">anyType and anySimpleType types</th> +    </tr> +    <tr> +      <td><code>anyType</code></td> +      <td><code>any_type_pimpl</code></td> +      <td><code>void</code></td> +    </tr> +    <tr> +      <td><code>anySimpleType</code></td> +      <td><code>any_simple_type_pimpl</code></td> +      <td><code>void</code></td> +    </tr> + +    <tr> +      <th colspan="3">fixed-length integral types</th> +    </tr> +    <!-- 8-bit --> +    <tr> +      <td><code>byte</code></td> +      <td><code>byte_pimpl</code></td> +      <td><code>signed char</code></td> +    </tr> +    <tr> +      <td><code>unsignedByte</code></td> +      <td><code>unsigned_byte_pimpl</code></td> +      <td><code>unsigned char</code></td> +    </tr> + +    <!-- 16-bit --> +    <tr> +      <td><code>short</code></td> +      <td><code>short_pimpl</code></td> +      <td><code>short</code></td> +    </tr> +    <tr> +      <td><code>unsignedShort</code></td> +      <td><code>unsigned_short_pimpl</code></td> +      <td><code>unsigned short</code></td> +    </tr> + +    <!-- 32-bit --> +    <tr> +      <td><code>int</code></td> +      <td><code>int_pimpl</code></td> +      <td><code>int</code></td> +    </tr> +    <tr> +      <td><code>unsignedInt</code></td> +      <td><code>unsigned_int_pimpl</code></td> +      <td><code>unsigned int</code></td> +    </tr> + +    <!-- 64-bit --> +    <tr> +      <td><code>long</code></td> +      <td><code>long_pimpl</code></td> +      <td><code>long long</code></td> +    </tr> +    <tr> +      <td><code>unsignedLong</code></td> +      <td><code>unsigned_long_pimpl</code></td> +      <td><code>unsigned long long</code></td> +    </tr> + +    <tr> +      <th colspan="3">arbitrary-length integral types</th> +    </tr> +    <tr> +      <td><code>integer</code></td> +      <td><code>integer_pimpl</code></td> +      <td><code>long long</code></td> +    </tr> +    <tr> +      <td><code>nonPositiveInteger</code></td> +      <td><code>non_positive_integer_pimpl</code></td> +      <td><code>long long</code></td> +    </tr> +    <tr> +      <td><code>nonNegativeInteger</code></td> +      <td><code>non_negative_integer_pimpl</code></td> +      <td><code>unsigned long long</code></td> +    </tr> +    <tr> +      <td><code>positiveInteger</code></td> +      <td><code>positive_integer_pimpl</code></td> +      <td><code>unsigned long long</code></td> +    </tr> +    <tr> +      <td><code>negativeInteger</code></td> +      <td><code>negative_integer_pimpl</code></td> +      <td><code>long long</code></td> +    </tr> + +    <tr> +      <th colspan="3">boolean types</th> +    </tr> +    <tr> +      <td><code>boolean</code></td> +      <td><code>boolean_pimpl</code></td> +      <td><code>bool</code></td> +    </tr> + +    <tr> +      <th colspan="3">fixed-precision floating-point types</th> +    </tr> +    <tr> +      <td><code>float</code></td> +      <td><code>float_pimpl</code></td> +      <td><code>float</code></td> +    </tr> +    <tr> +      <td><code>double</code></td> +      <td><code>double_pimpl</code></td> +      <td><code>double</code></td> +    </tr> + +    <tr> +      <th colspan="3">arbitrary-precision floating-point types</th> +    </tr> +    <tr> +      <td><code>decimal</code></td> +      <td><code>decimal_pimpl</code></td> +      <td><code>double</code></td> +    </tr> + +    <tr> +      <th colspan="3">string-based types</th> +    </tr> +    <tr> +      <td><code>string</code></td> +      <td><code>string_pimpl</code></td> +      <td><code>std::string</code> or <code>std::wstring</code></td> +    </tr> +    <tr> +      <td><code>normalizedString</code></td> +      <td><code>normalized_string_pimpl</code></td> +      <td><code>std::string</code> or <code>std::wstring</code></td> +    </tr> +    <tr> +      <td><code>token</code></td> +      <td><code>token_pimpl</code></td> +      <td><code>std::string</code> or <code>std::wstring</code></td> +    </tr> +    <tr> +      <td><code>Name</code></td> +      <td><code>name_pimpl</code></td> +      <td><code>std::string</code> or <code>std::wstring</code></td> +    </tr> +    <tr> +      <td><code>NMTOKEN</code></td> +      <td><code>nmtoken_pimpl</code></td> +      <td><code>std::string</code> or <code>std::wstring</code></td> +    </tr> +    <tr> +      <td><code>NCName</code></td> +      <td><code>ncname_pimpl</code></td> +      <td><code>std::string</code> or <code>std::wstring</code></td> +    </tr> + +    <tr> +      <td><code>language</code></td> +      <td><code>language_pimpl</code></td> +      <td><code>std::string</code> or <code>std::wstring</code></td> +    </tr> + +    <tr> +      <th colspan="3">qualified name</th> +    </tr> +    <tr> +      <td><code>QName</code></td> +      <td><code>qname_pimpl</code></td> +      <td><code>xml_schema::qname</code><br/><a href="#6.1">Section 6.1, +          "<code>QName</code> Parser"</a></td> +    </tr> + +    <tr> +      <th colspan="3">ID/IDREF types</th> +    </tr> +    <tr> +      <td><code>ID</code></td> +      <td><code>id_pimpl</code></td> +      <td><code>std::string</code> or <code>std::wstring</code></td> +    </tr> +    <tr> +      <td><code>IDREF</code></td> +      <td><code>idref_pimpl</code></td> +      <td><code>std::string</code> or <code>std::wstring</code></td> +    </tr> + +    <tr> +      <th colspan="3">list types</th> +    </tr> +    <tr> +      <td><code>NMTOKENS</code></td> +      <td><code>nmtokens_pimpl</code></td> +      <td><code>xml_schema::string_sequence</code><br/><a href="#6.2">Section +          6.2, "<code>NMTOKENS</code> and <code>IDREFS</code> Parsers"</a></td> +    </tr> +    <tr> +      <td><code>IDREFS</code></td> +      <td><code>idrefs_pimpl</code></td> +      <td><code>xml_schema::string_sequence</code><br/><a href="#6.2">Section +          6.2, "<code>NMTOKENS</code> and <code>IDREFS</code> Parsers"</a></td> +    </tr> + +    <tr> +      <th colspan="3">URI types</th> +    </tr> +    <tr> +      <td><code>anyURI</code></td> +      <td><code>uri_pimpl</code></td> +      <td><code>std::string</code> or <code>std::wstring</code></td> +    </tr> + +    <tr> +      <th colspan="3">binary types</th> +    </tr> +    <tr> +      <td><code>base64Binary</code></td> +      <td><code>base64_binary_pimpl</code></td> +      <td><code>std::[unique|auto]_ptr< xml_schema::buffer></code><br/> +          <a href="#6.3">Section 6.3, "<code>base64Binary</code> and +          <code>hexBinary</code> Parsers"</a></td> +    </tr> +    <tr> +      <td><code>hexBinary</code></td> +      <td><code>hex_binary_pimpl</code></td> +      <td><code>std::[unique|auto]_ptr< xml_schema::buffer></code><br/> +          <a href="#6.3">Section 6.3, "<code>base64Binary</code> and +          <code>hexBinary</code> Parsers"</a></td> +    </tr> + +    <tr> +      <th colspan="3">date/time types</th> +    </tr> +    <tr> +      <td><code>date</code></td> +      <td><code>date_pimpl</code></td> +      <td><code>xml_schema::date</code><br/><a href="#6.5">Section 6.5, +          "<code>date</code> Parser"</a></td> +    </tr> +    <tr> +      <td><code>dateTime</code></td> +      <td><code>date_time_pimpl</code></td> +      <td><code>xml_schema::date_time</code><br/><a href="#6.6">Section 6.6, +          "<code>dateTime</code> Parser"</a></td> +    </tr> +    <tr> +      <td><code>duration</code></td> +      <td><code>duration_pimpl</code></td> +      <td><code>xml_schema::duration</code><br/><a href="#6.7">Section 6.7, +          "<code>duration</code> Parser"</a></td> +    </tr> +    <tr> +      <td><code>gDay</code></td> +      <td><code>gday_pimpl</code></td> +      <td><code>xml_schema::gday</code><br/><a href="#6.8">Section 6.8, +          "<code>gDay</code> Parser"</a></td> +    </tr> +    <tr> +      <td><code>gMonth</code></td> +      <td><code>gmonth_pimpl</code></td> +      <td><code>xml_schema::gmonth</code><br/><a href="#6.9">Section 6.9, +          "<code>gMonth</code> Parser"</a></td> +    </tr> +    <tr> +      <td><code>gMonthDay</code></td> +      <td><code>gmonth_day_pimpl</code></td> +      <td><code>xml_schema::gmonth_day</code><br/><a href="#6.10">Section 6.10, +          "<code>gMonthDay</code> Parser"</a></td> +    </tr> +    <tr> +      <td><code>gYear</code></td> +      <td><code>gyear_pimpl</code></td> +      <td><code>xml_schema::gyear</code><br/><a href="#6.11">Section 6.11, +          "<code>gYear</code> Parser"</a></td> +    </tr> +    <tr> +      <td><code>gYearMonth</code></td> +      <td><code>gyear_month_pimpl</code></td> +      <td><code>xml_schema::gyear_month</code><br/><a href="#6.12">Section +          6.12, "<code>gYearMonth</code> Parser"</a></td> +    </tr> +    <tr> +      <td><code>time</code></td> +      <td><code>time_pimpl</code></td> +      <td><code>xml_schema::time</code><br/><a href="#6.13">Section 6.13, +          "<code>time</code> Parser"</a></td> +    </tr> + +  </table> + +  <h2><a name="6.1">6.1 <code>QName</code> Parser</a></h2> + +  <p>The return type of the <code>qname_pimpl</code> parser implementation +     is <code>xml_schema::qname</code> which represents an XML qualified +     name. Its interface is presented below. +     Note that the <code>std::string</code> type in the interface becomes +     <code>std::wstring</code> if the selected character type is +     <code>wchar_t</code>.</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class qname +  { +  public: +    explicit +    qname (const std::string& name); +    qname (const std::string& prefix, const std::string& name); + +    const std::string& +    prefix () const; + +    void +    prefix (const std::string&); + +    const std::string& +    name () const; + +    void +    name (const std::string&); +  }; + +  bool +  operator== (const qname&, const qname&); + +  bool +  operator!= (const qname&, const qname&); +} +  </pre> + + +  <h2><a name="6.2">6.2 <code>NMTOKENS</code> and <code>IDREFS</code> Parsers</a></h2> + +  <p>The return type of the <code>nmtokens_pimpl</code> and +     <code>idrefs_pimpl</code> parser implementations is +     <code>xml_schema::string_sequence</code> which represents a +     sequence of strings. Its interface is presented below. +     Note that the <code>std::string</code> type in the interface becomes +     <code>std::wstring</code> if the selected character type is +     <code>wchar_t</code>.</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class string_sequence: public std::vector<std::string> +  { +  public: +    string_sequence (); + +    explicit +    string_sequence (std::vector<std::string>::size_type n, +                     const std::string& x = std::string ()); + +    template <typename I> +    string_sequence (const I& begin, const I& end); +  }; + +  bool +  operator== (const string_sequence&, const string_sequence&); + +  bool +  operator!= (const string_sequence&, const string_sequence&); +} +  </pre> + + +  <h2><a name="6.3">6.3 <code>base64Binary</code> and <code>hexBinary</code> Parsers</a></h2> + +  <p>The return type of the <code>base64_binary_pimpl</code> and +     <code>hex_binary_pimpl</code> parser implementations is either +     <code>std::unique_ptr<xml_schema::buffer></code> (C++11) or +     <code>std::auto_ptr<xml_schema::buffer></code> (C++98), +     depending on the C++ standard selected (<code>--std</code> XSD +     compiler option). The <code>xml_schema::buffer</code> type +     represents a binary buffer and its interface is presented below.</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class buffer +  { +  public: +    typedef std::size_t size_t; + +    class bounds {}; // Out of bounds exception. + +  public: +    explicit +    buffer (size_t size = 0); +    buffer (size_t size, size_t capacity); +    buffer (const void* data, size_t size); +    buffer (const void* data, size_t size, size_t capacity); +    buffer (void* data, +            size_t size, +            size_t capacity, +            bool assume_ownership); + +  public: +    buffer (const buffer&); + +    buffer& +    operator= (const buffer&); + +    void +    swap (buffer&); + +  public: +    size_t +    capacity () const; + +    bool +    capacity (size_t); + +  public: +    size_t +    size () const; + +    bool +    size (size_t); + +  public: +    const char* +    data () const; + +    char* +    data (); + +    const char* +    begin () const; + +    char* +    begin (); + +    const char* +    end () const; + +    char* +    end (); +  }; + +  bool +  operator== (const buffer&, const buffer&); + +  bool +  operator!= (const buffer&, const buffer&); +} +  </pre> + +  <p>If the <code>assume_ownership</code> argument to the constructor +     is <code>true</code>, the instance assumes the ownership of the +     memory block pointed to by the <code>data</code> argument and will +     eventually release it by calling <code>operator delete()</code>. The +     <code>capacity()</code> and <code>size()</code> modifier functions +     return <code>true</code> if the underlying buffer has moved. +  </p> + +  <p>The <code>bounds</code> exception is thrown if the constructor +     arguments violate the <code>(size <= capacity)</code> +     constraint.</p> + + +  <h2><a name="6.4">6.4 Time Zone Representation</a></h2> + +  <p>The <code>date</code>, <code>dateTime</code>, <code>gDay</code>, +     <code>gMonth</code>, <code>gMonthDay</code>, <code>gYear</code>, +     <code>gYearMonth</code>, and <code>time</code> XML Schema built-in +     types all include an optional time zone component. The following +     <code>xml_schema::time_zone</code> base class is used to represent +     this information:</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class time_zone +  { +  public: +    time_zone (); +    time_zone (short hours, short minutes); + +    bool +    zone_present () const; + +    void +    zone_reset (); + +    short +    zone_hours () const; + +    void +    zone_hours (short); + +    short +    zone_minutes () const; + +    void +    zone_minutes (short); +  }; + +  bool +  operator== (const time_zone&, const time_zone&); + +  bool +  operator!= (const time_zone&, const time_zone&); +} +  </pre> + +  <p>The <code>zone_present()</code> accessor function returns <code>true</code> +     if the time zone is specified. The <code>zone_reset()</code> modifier +     function resets the time zone object to the <em>not specified</em> +     state. If the time zone offset is negative then both hours and +     minutes components are represented as negative integers.</p> + + +  <h2><a name="6.5">6.5 <code>date</code> Parser</a></h2> + + <p>The return type of the <code>date_pimpl</code> parser implementation +     is <code>xml_schema::date</code> which represents a year, a day, and a month +     with an optional time zone. Its interface is presented below. +     For more information on the base <code>xml_schema::time_zone</code> +     class refer to <a href="#6.4">Section 6.4, "Time Zone +     Representation"</a>.</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class date +  { +  public: +    date (int year, unsigned short month, unsigned short day); +    date (int year, unsigned short month, unsigned short day, +          short zone_hours, short zone_minutes); + +    int +    year () const; + +    void +    year (int); + +    unsigned short +    month () const; + +    void +    month (unsigned short); + +    unsigned short +    day () const; + +    void +    day (unsigned short); +  }; + +  bool +  operator== (const date&, const date&); + +  bool +  operator!= (const date&, const date&); +} +  </pre> + +  <h2><a name="6.6">6.6 <code>dateTime</code> Parser</a></h2> + +  <p>The return type of the <code>date_time_pimpl</code> parser implementation +     is <code>xml_schema::date_time</code> which represents a year, a month, a day, +     hours, minutes, and seconds with an optional time zone. Its interface +     is presented below. +     For more information on the base <code>xml_schema::time_zone</code> +     class refer to <a href="#6.4">Section 6.4, "Time Zone +     Representation"</a>.</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class date_time +  { +  public: +    date_time (int year, unsigned short month, unsigned short day, +               unsigned short hours, unsigned short minutes, +               double seconds); + +    date_time (int year, unsigned short month, unsigned short day, +               unsigned short hours, unsigned short minutes, +               double seconds, short zone_hours, short zone_minutes); + +    int +    year () const; + +    void +    year (int); + +    unsigned short +    month () const; + +    void +    month (unsigned short); + +    unsigned short +    day () const; + +    void +    day (unsigned short); + +    unsigned short +    hours () const; + +    void +    hours (unsigned short); + +    unsigned short +    minutes () const; + +    void +    minutes (unsigned short); + +    double +    seconds () const; + +    void +    seconds (double); +  }; + +  bool +  operator== (const date_time&, const date_time&); + +  bool +  operator!= (const date_time&, const date_time&); +} +  </pre> + +  <h2><a name="6.7">6.7 <code>duration</code> Parser</a></h2> + +  <p>The return type of the <code>duration_pimpl</code> parser implementation +     is <code>xml_schema::duration</code> which represents a potentially +     negative duration in the form of years, months, days, hours, minutes, +     and seconds. Its interface is presented below.</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class duration +  { +  public: +    duration (bool negative, +              unsigned int years, unsigned int months, unsigned int days, +              unsigned int hours, unsigned int minutes, double seconds); + +    bool +    negative () const; + +    void +    negative (bool); + +    unsigned int +    years () const; + +    void +    years (unsigned int); + +    unsigned int +    months () const; + +    void +    months (unsigned int); + +    unsigned int +    days () const; + +    void +    days (unsigned int); + +    unsigned int +    hours () const; + +    void +    hours (unsigned int); + +    unsigned int +    minutes () const; + +    void +    minutes (unsigned int); + +    double +    seconds () const; + +    void +    seconds (double); +  }; + +  bool +  operator== (const duration&, const duration&); + +  bool +  operator!= (const duration&, const duration&); +} +  </pre> + + +  <h2><a name="6.8">6.8 <code>gDay</code> Parser</a></h2> + +  <p>The return type of the <code>gday_pimpl</code> parser implementation +     is <code>xml_schema::gday</code> which represents a day of the month with +     an optional time zone. Its interface is presented below. +     For more information on the base <code>xml_schema::time_zone</code> +     class refer to <a href="#6.4">Section 6.4, "Time Zone +     Representation"</a>.</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class gday +  { +  public: +    explicit +    gday (unsigned short day); +    gday (unsigned short day, short zone_hours, short zone_minutes); + +    unsigned short +    day () const; + +    void +    day (unsigned short); +  }; + +  bool +  operator== (const gday&, const gday&); + +  bool +  operator!= (const gday&, const gday&); +} +  </pre> + +  <h2><a name="6.9">6.9 <code>gMonth</code> Parser</a></h2> + +  <p>The return type of the <code>gmonth_pimpl</code> parser implementation +     is <code>xml_schema::gmonth</code> which represents a month of the year +     with an optional time zone. Its interface is presented below. +     For more information on the base <code>xml_schema::time_zone</code> +     class refer to <a href="#6.4">Section 6.4, "Time Zone +     Representation"</a>.</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class gmonth +  { +  public: +    explicit +    gmonth (unsigned short month); +    gmonth (unsigned short month, short zone_hours, short zone_minutes); + +    unsigned short +    month () const; + +    void +    month (unsigned short); +  }; + +  bool +  operator== (const gmonth&, const gmonth&); + +  bool +  operator!= (const gmonth&, const gmonth&); +} +  </pre> + +  <h2><a name="6.10">6.10 <code>gMonthDay</code> Parser</a></h2> + +  <p>The return type of the <code>gmonth_day_pimpl</code> parser implementation +     is <code>xml_schema::gmonth_day</code> which represents a day and a month +     of the year with an optional time zone. Its interface is presented below. +     For more information on the base <code>xml_schema::time_zone</code> +     class refer to <a href="#6.4">Section 6.4, "Time Zone +     Representation"</a>.</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class gmonth_day +  { +  public: +    gmonth_day (unsigned short month, unsigned short day); +    gmonth_day (unsigned short month, unsigned short day, +                short zone_hours, short zone_minutes); + +    unsigned short +    month () const; + +    void +    month (unsigned short); + +    unsigned short +    day () const; + +    void +    day (unsigned short); +  }; + +  bool +  operator== (const gmonth_day&, const gmonth_day&); + +  bool +  operator!= (const gmonth_day&, const gmonth_day&); +} +  </pre> + +  <h2><a name="6.11">6.11 <code>gYear</code> Parser</a></h2> + +  <p>The return type of the <code>gyear_pimpl</code> parser implementation +     is <code>xml_schema::gyear</code> which represents a year with +     an optional time zone. Its interface is presented below. +     For more information on the base <code>xml_schema::time_zone</code> +     class refer to <a href="#6.4">Section 6.4, "Time Zone +     Representation"</a>.</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class gyear +  { +  public: +    explicit +    gyear (int year); +    gyear (int year, short zone_hours, short zone_minutes); + +    int +    year () const; + +    void +    year (int); +  }; + +  bool +  operator== (const gyear&, const gyear&); + +  bool +  operator!= (const gyear&, const gyear&); +} +  </pre> + +  <h2><a name="6.12">6.12 <code>gYearMonth</code> Parser</a></h2> + +  <p>The return type of the <code>gyear_month_pimpl</code> parser implementation +     is <code>xml_schema::gyear_month</code> which represents a year and a month +     with an optional time zone. Its interface is presented below. +     For more information on the base <code>xml_schema::time_zone</code> +     class refer to <a href="#6.4">Section 6.4, "Time Zone +     Representation"</a>.</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class gyear_month +  { +  public: +    gyear_month (int year, unsigned short month); +    gyear_month (int year, unsigned short month, +                 short zone_hours, short zone_minutes); + +    int +    year () const; + +    void +    year (int); + +    unsigned short +    month () const; + +    void +    month (unsigned short); +  }; + +  bool +  operator== (const gyear_month&, const gyear_month&); + +  bool +  operator!= (const gyear_month&, const gyear_month&); +} +  </pre> + + +  <h2><a name="6.13">6.13 <code>time</code> Parser</a></h2> + + <p>The return type of the <code>time_pimpl</code> parser implementation +     is <code>xml_schema::time</code> which represents hours, minutes, +     and seconds with an optional time zone. Its interface is presented below. +     For more information on the base <code>xml_schema::time_zone</code> +     class refer to <a href="#6.4">Section 6.4, "Time Zone +     Representation"</a>.</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class time +  { +  public: +    time (unsigned short hours, unsigned short minutes, double seconds); +    time (unsigned short hours, unsigned short minutes, double seconds, +          short zone_hours, short zone_minutes); + +    unsigned short +    hours () const; + +    void +    hours (unsigned short); + +    unsigned short +    minutes () const; + +    void +    minutes (unsigned short); + +    double +    seconds () const; + +    void +    seconds (double); +  }; + +  bool +  operator== (const time&, const time&); + +  bool +  operator!= (const time&, const time&); +} +  </pre> + + +  <!-- Error Handling --> + + +  <h1><a name="7">7 Document Parser and Error Handling</a></h1> + +  <p>In this chapter we will discuss the <code>xml_schema::document</code> +     type as well as the error handling mechanisms provided by the mapping +     in more detail. As mentioned in <a href="#3.4">Section 3.4, +     "Connecting the Parsers Together"</a>, the interface of +     <code>xml_schema::document</code> depends on the underlying XML +     parser selected (<a href="#5.3">Section 5.3, "Underlying XML +     Parser"</a>). The following sections describe the +     <code>document</code> type interface for Xerces-C++ and +     Expat as underlying parsers.</p> + +  <h2><a name="7.1">7.1 Xerces-C++ Document Parser</a></h2> + +  <p>When Xerces-C++ is used as the underlying XML parser, the +     <code>document</code> type has the following interface. Note that +     if the character type is <code>wchar_t</code>, then the string type +     in the interface becomes <code>std::wstring</code> +     (see <a href="#5.2">Section 5.2, "Character Type and Encoding"</a>).</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class parser_base; +  class error_handler; + +  class flags +  { +  public: +    // Do not validate XML documents with the Xerces-C++ validator. +    // +    static const unsigned long dont_validate; + +    // Do not initialize the Xerces-C++ runtime. +    // +    static const unsigned long dont_initialize; + +    // Disable handling of subsequent imports for the same namespace +    // in Xerces-C++ 3.1.0 and later. +    // +    static const unsigned long no_multiple_imports; +  }; + +  class properties +  { +  public: +    // Add a location for a schema with a target namespace. +    // +    void +    schema_location (const std::string& namespace_, +                     const std::string& location); + +    // Add a location for a schema without a target namespace. +    // +    void +    no_namespace_schema_location (const std::string& location); +  }; + +  class document +  { +  public: +    document (parser_base& root, +              const std::string& root_element_name, +	      bool polymorphic = false); + +    document (parser_base& root, +              const std::string& root_element_namespace, +              const std::string& root_element_name, +	      bool polymorphic = false); + +  public: +    // Parse URI or a local file. +    // +    void +    parse (const std::string& uri, +           flags = 0, +           const properties& = properties ()); + +    // Parse URI or a local file with a user-provided error_handler +    // object. +    // +    void +    parse (const std::string& uri, +           error_handler&, +           flags = 0, +           const properties& = properties ()); + +    // Parse URI or a local file with a user-provided ErrorHandler +    // object. Note that you must initialize the Xerces-C++ runtime +    // before calling this function. +    // +    void +    parse (const std::string& uri, +           xercesc::ErrorHandler&, +           flags = 0, +           const properties& = properties ()); + +    // Parse URI or a local file using a user-provided SAX2XMLReader +    // object. Note that you must initialize the Xerces-C++ runtime +    // before calling this function. +    // +    void +    parse (const std::string& uri, +           xercesc::SAX2XMLReader&, +           flags = 0, +           const properties& = properties ()); + +  public: +    // Parse std::istream. +    // +    void +    parse (std::istream&, +           flags = 0, +           const properties& = properties ()); + +    // Parse std::istream with a user-provided error_handler object. +    // +    void +    parse (std::istream&, +           error_handler&, +           flags = 0, +           const properties& = properties ()); + +    // Parse std::istream with a user-provided ErrorHandler object. +    // Note that you must initialize the Xerces-C++ runtime before +    // calling this function. +    // +    void +    parse (std::istream&, +           xercesc::ErrorHandler&, +           flags = 0, +           const properties& = properties ()); + +    // Parse std::istream using a user-provided SAX2XMLReader object. +    // Note that you must initialize the Xerces-C++ runtime before +    // calling this function. +    // +    void +    parse (std::istream&, +           xercesc::SAX2XMLReader&, +           flags = 0, +           const properties& = properties ()); + +  public: +    // Parse std::istream with a system id. +    // +    void +    parse (std::istream&, +           const std::string& system_id, +           flags = 0, +           const properties& = properties ()); + +    // Parse std::istream with a system id and a user-provided +    // error_handler object. +    // +    void +    parse (std::istream&, +           const std::string& system_id, +           error_handler&, +           flags = 0, +           const properties& = properties ()); + +    // Parse std::istream with a system id and a user-provided +    // ErrorHandler object. Note that you must initialize the +    // Xerces-C++ runtime before calling this function. +    // +    void +    parse (std::istream&, +           const std::string& system_id, +           xercesc::ErrorHandler&, +           flags = 0, +           const properties& = properties ()); + +    // Parse std::istream with a system id using a user-provided +    // SAX2XMLReader object. Note that you must initialize the +    // Xerces-C++ runtime before calling this function. +    // +    void +    parse (std::istream&, +           const std::string& system_id, +           xercesc::SAX2XMLReader&, +           flags = 0, +           const properties& = properties ()); + +  public: +    // Parse std::istream with system and public ids. +    // +    void +    parse (std::istream&, +           const std::string& system_id, +           const std::string& public_id, +           flags = 0, +           const properties& = properties ()); + +    // Parse std::istream with system and public ids and a user-provided +    // error_handler object. +    // +    void +    parse (std::istream&, +           const std::string& system_id, +           const std::string& public_id, +           error_handler&, +           flags = 0, +           const properties& = properties ()); + +    // Parse std::istream with system and public ids and a user-provided +    // ErrorHandler object. Note that you must initialize the Xerces-C++ +    // runtime before calling this function. +    // +    void +    parse (std::istream&, +           const std::string& system_id, +           const std::string& public_id, +           xercesc::ErrorHandler&, +           flags = 0, +           const properties& = properties ()); + +    // Parse std::istream with system and public ids using a user- +    // provided SAX2XMLReader object. Note that you must initialize +    // the Xerces-C++ runtime before calling this function. +    // +    void +    parse (std::istream&, +           const std::string& system_id, +           const std::string& public_id, +           xercesc::SAX2XMLReader&, +           flags = 0, +           const properties& = properties ()); + +  public: +    // Parse InputSource. Note that you must initialize the Xerces-C++ +    // runtime before calling this function. +    // +    void +    parse (const xercesc::InputSource&, +           flags = 0, +           const properties& = properties ()); + +    // Parse InputSource with a user-provided error_handler object. +    // Note that you must initialize the Xerces-C++ runtime before +    // calling this function. +    // +    void +    parse (const xercesc::InputSource&, +           error_handler&, +           flags = 0, +           const properties& = properties ()); + +    // Parse InputSource with a user-provided ErrorHandler object. +    // Note that you must initialize the Xerces-C++ runtime before +    // calling this function. +    // +    void +    parse (const xercesc::InputSource&, +           xercesc::ErrorHandler&, +           flags = 0, +           const properties& = properties ()); + +    // Parse InputSource using a user-provided SAX2XMLReader object. +    // Note that you must initialize the Xerces-C++ runtime before +    // calling this function. +    // +    void +    parse (const xercesc::InputSource&, +           xercesc::SAX2XMLReader&, +           flags = 0, +           const properties& = properties ()); +  }; +} +  </pre> + +  <p>The <code>document</code> class is a root parser for +     the vocabulary. The first argument to its constructors is the +     parser for the type of the root element. The <code>parser_base</code> +     class is the base type for all parser skeletons. The second and +     third arguments to the <code>document</code>'s constructors are +     the root element's name and namespace. The last argument, +     <code>polymorphic</code>, specifies whether the XML documents +     being parsed use polymorphism. For more information on support +     for XML Schema polymorphism in the C++/Parser mapping refer +     to <a href="#5.5">Section 5.5, "Support for Polymorphism"</a>.</p> + +  <p>The rest of the <code>document</code> interface consists of overloaded +     <code>parse()</code> functions. The last two arguments in each of these +     functions are <code>flags</code> and <code>properties</code>. The +     <code>flags</code> argument allows you to modify the default behavior +     of the parsing functions. The <code>properties</code> argument allows +     you to override the schema location attributes specified in XML +     documents. Note that the schema location paths are relative to an +     XML document unless they are complete URIs. For example if you want +     to use a local schema file then you will need to use a URI in the +     form <code>file:///absolute/path/to/your/schema</code>.</p> + +  <p>A number of overloaded <code>parse()</code> functions have the +     <code>system_id</code> and <code>public_id</code> arguments. The +     system id is a <em>system</em> identifier of the resources being +     parsed (for example, URI or a full file path). The public id is a +     <em>public</em> identifier of the resource (for example, an +     application-specific name or a relative file path). The system id +     is used to resolve relative paths (for example, schema paths). In +     diagnostics messages the public id is used if it is available. +     Otherwise the system id is used.</p> + +  <p>The error handling mechanisms employed by the <code>document</code> +     parser are described in <a href="#7.3">Section 7.3, "Error +     Handling"</a>.</p> + +  <h2><a name="7.2">7.2 Expat Document Parser</a></h2> + +  <p>When Expat is used as the underlying XML parser, the +     <code>document</code> type has the following interface. Note that +     if the character type is <code>wchar_t</code>, then the string type +     in the interface becomes <code>std::wstring</code> +     (see <a href="#5.2">Section 5.2, "Character Type and Encoding"</a>).</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class parser_base; +  class error_handler; + +  class document +  { +  public: +    document (parser_base&, +              const std::string& root_element_name, +              bool polymorphic = false); + +    document (parser_base&, +              const std::string& root_element_namespace, +              const std::string& root_element_name, +              bool polymorphic = false); + +  public: +    // Parse a local file. The file is accessed with std::ifstream +    // in binary mode. The std::ios_base::failure exception is used +    // to report io errors (badbit and failbit). +    void +    parse (const std::string& file); + +    // Parse a local file with a user-provided error_handler +    // object. The file is accessed with std::ifstream in binary +    // mode. The std::ios_base::failure exception is used to report +    // io errors (badbit and failbit). +    // +    void +    parse (const std::string& file, error_handler&); + +  public: +    // Parse std::istream. +    // +    void +    parse (std::istream&); + +    // Parse std::istream with a user-provided error_handler object. +    // +    void +    parse (std::istream&, error_handler&); + +    // Parse std::istream with a system id. +    // +    void +    parse (std::istream&, const std::string& system_id); + +    // Parse std::istream with a system id and a user-provided +    // error_handler object. +    // +    void +    parse (std::istream&, +           const std::string& system_id, +           error_handler&); + +    // Parse std::istream with system and public ids. +    // +    void +    parse (std::istream&, +           const std::string& system_id, +           const std::string& public_id); + +    // Parse std::istream with system and public ids and a user-provided +    // error_handler object. +    // +    void +    parse (std::istream&, +           const std::string& system_id, +           const std::string& public_id, +           error_handler&); + +  public: +    // Parse a chunk of input. You can call these functions multiple +    // times with the last call having the last argument true. +    // +    void +    parse (const void* data, std::size_t size, bool last); + +    void +    parse (const void* data, std::size_t size, bool last, +           error_handler&); + +    void +    parse (const void* data, std::size_t size, bool last, +           const std::string& system_id); + +    void +    parse (const void* data, std::size_t size, bool last, +           const std::string& system_id, +           error_handler&); + +    void +    parse (const void* data, std::size_t size, bool last, +           const std::string& system_id, +           const std::string& public_id); + +    void +    parse (const void* data, std::size_t size, bool last, +           const std::string& system_id, +           const std::string& public_id, +           error_handler&); + +  public: +    // Low-level Expat-specific parsing API. +    // +    void +    parse_begin (XML_Parser); + +    void +    parse_begin (XML_Parser, const std::string& public_id); + +    void +    parse_begin (XML_Parser, error_handler&); + +    void +    parse_begin (XML_Parser, +                 const std::string& public_id, +                 error_handler&); +    void +    parse_end (); +  }; +} +  </pre> + +  <p>The <code>document</code> class is a root parser for +     the vocabulary. The first argument to its constructors is the +     parser for the type of the root element. The <code>parser_base</code> +     class is the base type for all parser skeletons. The second and +     third arguments to the <code>document</code>'s constructors are +     the root element's name and namespace. The last argument, +     <code>polymorphic</code>, specifies whether the XML documents +     being parsed use polymorphism. For more information on support +     for XML Schema polymorphism in the C++/Parser mapping refer +     to <a href="#5.5">Section 5.5, "Support for Polymorphism"</a>.</p> + +  <p>A number of overloaded <code>parse()</code> functions have the +     <code>system_id</code> and <code>public_id</code> arguments. The +     system id is a <em>system</em> identifier of the resources being +     parsed (for example, URI or a full file path). The public id is a +     <em>public</em> identifier of the resource (for example, an +     application-specific name or a relative file path). The system id +     is used to resolve relative paths. In diagnostics messages the +     public id is used if it is available. Otherwise the system id +     is used.</p> + +  <p>The <code>parse_begin()</code> and <code>parse_end()</code> functions +     present a low-level, Expat-specific parsing API for maximum control. +     A typical use-case would look like this (pseudo-code):</p> + +  <pre class="c++"> +xxx_pimpl root_p; +document doc_p (root_p, "root"); + +root_p.pre (); +doc_p.parse_begin (xml_parser, "file.xml"); + +while (more_data_to_parse) +{ +  // Call XML_Parse or XML_ParseBuffer. + +  if (status == XML_STATUS_ERROR) +    break; +} + +// Call parse_end even in case of an error to translate +// XML and Schema errors to exceptions or error_handler +// calls. +// +doc.parse_end (); +result_type result (root_p.post_xxx ()); +  </pre> + +  <p>Note that if your vocabulary uses XML namespaces, the +     <code>XML_ParserCreateNS()</code> functions should be used to create +     the XML parser. Space (<code>XML_Char (' ')</code>) should be used +     as a separator (the second argument to <code>XML_ParserCreateNS()</code>). +  </p> + +  <p>The error handling mechanisms employed by the <code>document</code> +     parser are described in <a href="#7.3">Section 7.3, "Error +     Handling"</a>.</p> + + +  <h2><a name="7.3">7.3 Error Handling</a></h2> + +  <p>There are three categories of errors that can result from running +     a parser on an XML document: System, XML, and Application. +     The System category contains memory allocation and file/stream +     operation errors. The XML category covers XML parsing and +     well-formedness checking as well as XML Schema validation errors. +     Finally, the Application category is for application logic errors +     that you may want to propagate from parser implementations to the +     caller of the parser. +  </p> + +  <p>The System errors are mapped to the standard exceptions. The +     out of memory condition is indicated by throwing an instance +     of <code>std::bad_alloc</code>. The stream operation errors +     are reported either by throwing an instance of +     <code>std::ios_base::failure</code> if exceptions are enabled +     or by setting the stream state.</p> + +  <p>Note that if you are parsing <code>std::istream</code> on +     which exceptions are not enabled, then you will need to +     check the stream state before calling the <code>post()</code> +     callback, as shown in the following example:</p> + +  <pre class="c++"> +int +main (int argc, char* argv[]) +{ +  ... + +  std::ifstream ifs (argv[1]); + +  if (ifs.fail ()) +  { +    cerr << argv[1] << ": unable to open" << endl; +    return 1; +  } + +  root_p.pre (); +  doc_p.parse (ifs); + +  if (ifs.fail ()) +  { +    cerr << argv[1] << ": io failure" << endl; +    return 1; +  } + +  result_type result (root_p.post_xxx ()); +} +  </pre> + +  <p>The above example can be rewritten to use exceptions +     as shown below:</p> + +  <pre class="c++"> +int +main (int argc, char* argv[]) +{ +  try +  { +    ... + +    std::ifstream ifs; +    ifs.exceptions (std::ifstream::badbit | std::ifstream::failbit); +    ifs.open (argv[1]); + +    root_p.pre (); +    doc_p.parse (ifs); +    result_type result (root_p.post_xxx ()); +  } +  catch (const std::ifstream::failure&) +  { +    cerr << argv[1] << ": unable to open or io failure" << endl; +    return 1; +  } +} +  </pre> + + +  <p>For reporting application errors from parsing callbacks, you +     can throw any exceptions of your choice. They are propagated to +     the caller of the parser without any alterations.</p> + +  <p>The XML errors can be reported either by throwing the +     <code>xml_schema::parsing</code> exception or by a callback +     to the <code>xml_schema::error_handler</code> object (and +     <code>xercesc::ErrorHandler</code> object in case of Xerces-C++).</p> + +  <p>The <code>xml_schema::parsing</code> exception contains +     a list of warnings and errors that were accumulated during +     parsing. Note that this exception is thrown only if there +     was an error. This makes it impossible to obtain warnings +     from an otherwise successful parsing using this mechanism. +     The following listing shows the definition of +     <code>xml_schema::parsing</code> exception. Note that if the +     character type is <code>wchar_t</code>, then the string type +     and output stream type in the definition become +     <code>std::wstring</code> and <code>std::wostream</code>, +     respectively (see <a href="#5.2">Section 5.2, "Character Type +     and Encoding"</a>).</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class exception: public std::exception +  { +  protected: +    virtual void +    print (std::ostream&) const = 0; +  }; + +  inline std::ostream& +  operator<< (std::ostream& os, const exception& e) +  { +    e.print (os); +    return os; +  } + + +  class severity +  { +  public: +    enum value +    { +      warning, +      error +    }; +  }; + + +  class error +  { +  public: +    error (xml_schema::severity, +           const std::string& id, +           unsigned long line, +           unsigned long column, +           const std::string& message); + +    xml_schema::severity +    severity () const; + +    const std::string& +    id () const; + +    unsigned long +    line () const; + +    unsigned long +    column () const; + +    const std::string& +    message () const; +  }; + +  std::ostream& +  operator<< (std::ostream&, const error&); + + +  class diagnostics: public std::vector<error> +  { +  }; + +  std::ostream& +  operator<< (std::ostream&, const diagnostics&); + + +  class parsing: public exception +  { +  public: +    parsing (); +    parsing (const xml_schema::diagnostics&); + +    const xml_schema::diagnostics& +    diagnostics () const; + +    virtual const char* +    what () const throw (); + +  protected: +    virtual void +    print (std::ostream&) const; +  }; +} +  </pre> + +  <p>The following example shows how we can catch and print this +     exception. The code will print diagnostics messages one per line +     in case of an error.</p> + +  <pre class="c++"> +int +main (int argc, char* argv[]) +{ +  try +  { +    // Parse. +  } +  catch (const xml_schema::parsing& e) +  { +    cerr << e << endl; +    return 1; +  } +} +  </pre> + +  <p>With the <code>error_handler</code> approach the diagnostics +     messages are delivered as parsing progresses. The following +     listing presents the definition of the <code>error_handler</code> +     interface. Note that if the character type is <code>wchar_t</code>, +     then the string type in the interface becomes <code>std::wstring</code> +     (see <a href="#5.2">Section 5.2, "Character Type and Encoding"</a>).</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class error_handler +  { +  public: +    class severity +    { +    public: +      enum value +      { +        warning, +        error, +        fatal +      }; +    }; + +    virtual bool +    handle (const std::string& id, +            unsigned long line, +            unsigned long column, +            severity, +            const std::string& message) = 0; +  }; +} +  </pre> + +  <p>The return value of the <code>handle()</code> function indicates whether +     parsing should continue if possible. The error with the fatal severity +     level terminates the parsing process regardless of the returned value. +     At the end of the parsing process with an error that was reported via +     the  <code>error_handler</code> object, an empty +     <code>xml_schema::parsing</code> exception is thrown to indicate +     the failure to the caller. You can alter this behavior by throwing +     your own exception from the <code>handle()</code> function.</p> + + +  <!-- Appendix A --> + + +  <h1><a name="A">Appendix A — Supported XML Schema Constructs</a></h1> + +  <p>The C++/Parser mapping supports validation of the following W3C XML +     Schema constructs in the generated code.</p> + +  <!-- border="1" is necessary for html2ps --> +  <table id="features" border="1"> +    <tr><th>Construct</th><th>Notes</th></tr> +    <tr><th colspan="2">Structure</th></tr> + +    <tr><td>element</td><td></td></tr> +    <tr><td>attribute</td><td></td></tr> + +    <tr><td>any</td><td></td></tr> +    <tr><td>anyAttribute</td><td></td></tr> + +    <tr><td>all</td><td></td></tr> +    <tr><td>sequence</td><td></td></tr> +    <tr><td>choice</td><td></td></tr> + +    <tr><td>complex type, empty content</td><td></td></tr> +    <tr><td>complex type, mixed content</td><td></td></tr> +    <tr><td>complex type, simple content extension</td><td></td></tr> +    <tr><td>complex type, simple content restriction</td> +        <td>Simple type facets are not validated.</td></tr> +    <tr><td>complex type, complex content extension</td><td></td></tr> +    <tr><td>complex type, complex content restriction</td><td></td></tr> + +    <tr><td>list</td><td></td></tr> + +    <tr><th colspan="2">Datatypes</th></tr> + +    <tr><td>byte</td><td></td></tr> +    <tr><td>unsignedByte</td><td></td></tr> +    <tr><td>short</td><td></td></tr> +    <tr><td>unsignedShort</td><td></td></tr> +    <tr><td>int</td><td></td></tr> +    <tr><td>unsignedInt</td><td></td></tr> +    <tr><td>long</td><td></td></tr> +    <tr><td>unsignedLong</td><td></td></tr> +    <tr><td>integer</td><td></td></tr> +    <tr><td>nonPositiveInteger</td><td></td></tr> +    <tr><td>nonNegativeInteger</td><td></td></tr> +    <tr><td>positiveInteger</td><td></td></tr> +    <tr><td>negativeInteger</td><td></td></tr> + +    <tr><td>boolean</td><td></td></tr> + +    <tr><td>float</td><td></td></tr> +    <tr><td>double</td><td></td></tr> +    <tr><td>decimal</td><td></td></tr> + +    <tr><td>string</td><td></td></tr> +    <tr><td>normalizedString</td><td></td></tr> +    <tr><td>token</td><td></td></tr> +    <tr><td>Name</td><td></td></tr> +    <tr><td>NMTOKEN</td><td></td></tr> +    <tr><td>NCName</td><td></td></tr> +    <tr><td>language</td><td></td></tr> +    <tr><td>anyURI</td><td></td></tr> + +    <tr><td>ID</td><td>Identity constraint is not enforced.</td></tr> +    <tr><td>IDREF</td><td>Identity constraint is not enforced.</td></tr> + +    <tr><td>NMTOKENS</td><td></td></tr> +    <tr><td>IDREFS</td><td>Identity constraint is not enforced.</td></tr> + +    <tr><td>QName</td><td></td></tr> + +    <tr><td>base64Binary</td><td></td></tr> +    <tr><td>hexBinary</td><td></td></tr> + +    <tr><td>date</td><td></td></tr> +    <tr><td>dateTime</td><td></td></tr> +    <tr><td>duration</td><td></td></tr> +    <tr><td>gDay</td><td></td></tr> +    <tr><td>gMonth</td><td></td></tr> +    <tr><td>gMonthDay</td><td></td></tr> +    <tr><td>gYear</td><td></td></tr> +    <tr><td>gYearMonth</td><td></td></tr> +    <tr><td>time</td><td></td></tr> +  </table> + + +  </div> +</div> + +</body> +</html> diff --git a/doc/cxx/parser/guide/index.xhtml.in b/doc/cxx/parser/guide/index.xhtml.in new file mode 100644 index 0000000..119f421 --- /dev/null +++ b/doc/cxx/parser/guide/index.xhtml.in @@ -0,0 +1,4163 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> + +<head> +  <title>C++/Parser Mapping Getting Started Guide</title> + +  <meta name="copyright" content="© @copyright@"/> +  <meta name="keywords" content="xsd,xml,schema,c++,mapping,data,binding,parser,validation"/> +  <meta name="description" content="C++/Parser Mapping Getting Started Guide"/> + +  <link rel="stylesheet" type="text/css" href="../../../default.css" /> + +<style type="text/css"> +  pre { +    padding    : 0 0 0 0em; +    margin     : 0em 0em 0em 0; + +    font-size  : 102% +  } + +  body { +    min-width: 48em; +  } + +  h1 { +    font-weight: bold; +    font-size: 200%; +    line-height: 1.2em; +  } + +  h2 { +    font-weight : bold; +    font-size   : 150%; + +    padding-top : 0.8em; +  } + +  h3 { +    font-size   : 140%; +    padding-top : 0.8em; +  } + +  /* Adjust indentation for three levels. */ +  #container { +    max-width: 48em; +  } + +  #content { +    padding: 0 0.1em 0 4em; +    /*background-color: red;*/ +  } + +  #content h1 { +    margin-left: -2.06em; +  } + +  #content h2 { +    margin-left: -1.33em; +  } + +  /* Title page */ + +  #titlepage { +    padding: 2em 0 1em 0; +    border-bottom: 1px solid black; +  } + +  #titlepage .title { +    font-weight: bold; +    font-size: 200%; +    text-align: center; +  } + +  #titlepage #first-title { +    padding: 1em 0 0.4em 0; +  } + +  #titlepage #second-title { +    padding: 0.4em 0 2em 0; +  } + +  /* Lists */ +  ul.list li { +    padding-top      : 0.3em; +    padding-bottom   : 0.3em; +  } + +  ol.steps { +    padding-left     : 1.8em; +  } + +  ol.steps li { +    padding-top      : 0.3em; +    padding-bottom   : 0.3em; +  } + + +  div.img { +    text-align: center; +    padding: 2em 0 2em 0; +  } + +  /*  */ +  dl dt { +    padding   : 0.8em 0 0 0; +  } + +  /* Built-in table */ +  #builtin { +    margin: 2em 0 2em 0; + +    border-collapse   : collapse; +    border            : 1px solid; +    border-color      : #000000; + +    font-size        : 11px; +    line-height      : 14px; +  } + +  #builtin th, #builtin td { +    border: 1px solid; +    padding           : 0.9em 0.9em 0.7em 0.9em; +  } + +  #builtin th { +    background : #cde8f6; +  } + +  #builtin td { +    text-align: left; +  } + +  /* XML Schema features table. */ +  #features { +    margin: 2em 0 2em 0; + +    border-collapse   : collapse; +    border            : 1px solid; +    border-color      : #000000; + +    font-size        : 11px; +    line-height      : 14px; +  } + +  #features th, #features td { +    border: 1px solid; +    padding           : 0.6em 0.6em 0.6em 0.6em; +  } + +  #features th { +    background : #cde8f6; +  } + +  #features td { +    text-align: left; +  } + + +  /* TOC */ +  table.toc { +    border-style      : none; +    border-collapse   : separate; +    border-spacing    : 0; + +    margin            : 0.2em 0 0.2em 0; +    padding           : 0 0 0 0; +  } + +  table.toc tr { +    padding           : 0 0 0 0; +    margin            : 0 0 0 0; +  } + +  table.toc * td, table.toc * th { +    border-style      : none; +    margin            : 0 0 0 0; +    vertical-align    : top; +  } + +  table.toc * th { +    font-weight       : normal; +    padding           : 0em 0.1em 0em 0; +    text-align        : left; +    white-space       : nowrap; +  } + +  table.toc * table.toc th { +    padding-left      : 1em; +  } + +  table.toc * td { +    padding           : 0em 0 0em 0.7em; +    text-align        : left; +  } +</style> + + +</head> + +<body> +<div id="container"> +  <div id="content"> + +  <div class="noprint"> + +  <div id="titlepage"> +    <div class="title" id="first-title">C++/Parser Mapping</div> +    <div class="title" id="second-title">Getting Started Guide</div> + +  <p>Copyright © @copyright@.</p> + +  <p>Permission is granted to copy, distribute and/or modify this +     document under the terms of the +     <a href="https://www.codesynthesis.com/licenses/fdl-1.2.txt">GNU Free +     Documentation License, version 1.2</a>; with no Invariant Sections, +     no Front-Cover Texts and no Back-Cover Texts. +  </p> + +  <p>This document is available in the following formats: +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/parser/guide/index.xhtml">XHTML</a>, +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/parser/guide/cxx-parser-guide.pdf">PDF</a>, and +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/parser/guide/cxx-parser-guide.ps">PostScript</a>.</p> + +  </div> + +  <h1>Table of Contents</h1> + +  <table class="toc"> +    <tr> +      <th></th><td><a href="#0">Preface</a> +        <table class="toc"> +          <tr><th></th><td><a href="#0.1">About This Document</a></td></tr> +          <tr><th></th><td><a href="#0.2">More Information</a></td></tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>1</th><td><a href="#1">Introduction</a> +        <table class="toc"> +          <tr><th>1.1</th><td><a href="#1.1">Mapping Overview</a></td></tr> +          <tr><th>1.2</th><td><a href="#1.2">Benefits</a></td></tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>2</th><td><a href="#2">Hello World Example</a> +        <table class="toc"> +          <tr><th>2.1</th><td><a href="#2.1">Writing XML Document and Schema</a></td></tr> +          <tr><th>2.2</th><td><a href="#2.2">Translating Schema to C++</a></td></tr> +          <tr><th>2.3</th><td><a href="#2.3">Implementing Application Logic</a></td></tr> +          <tr><th>2.4</th><td><a href="#2.4">Compiling and Running</a></td></tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>3</th><td><a href="#3">Parser Skeletons</a> +        <table class="toc"> +          <tr><th>3.1</th><td><a href="#3.1">Implementing the Gender Parser</a></td></tr> +          <tr><th>3.2</th><td><a href="#3.2">Implementing the Person Parser</a></td></tr> +          <tr><th>3.3</th><td><a href="#3.3">Implementing the People Parser</a></td></tr> +          <tr><th>3.4</th><td><a href="#3.4">Connecting the Parsers Together</a></td></tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>4</th><td><a href="#4">Type Maps</a> +        <table class="toc"> +          <tr><th>4.1</th><td><a href="#4.1">Object Model</a></td></tr> +          <tr><th>4.2</th><td><a href="#4.2">Type Map File Format</a></td></tr> +          <tr><th>4.3</th><td><a href="#4.3">Parser Implementations</a></td></tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>5</th><td><a href="#5">Mapping Configuration</a> +        <table class="toc"> +          <tr><th>5.1</th><td><a href="#5.1">C++ Standard</a></td></tr> +          <tr><th>5.2</th><td><a href="#5.2">Character Type and Encoding</a></td></tr> +          <tr><th>5.3</th><td><a href="#5.3">Underlying XML Parser</a></td></tr> +	  <tr><th>5.4</th><td><a href="#5.4">XML Schema Validation</a></td></tr> +	  <tr><th>5.5</th><td><a href="#5.5">Support for Polymorphism</a></td></tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>6</th><td><a href="#6">Built-In XML Schema Type Parsers</a> +        <table class="toc"> +          <tr><th>6.1</th><td><a href="#6.1"><code>QName</code> Parser</a></td></tr> +          <tr><th>6.2</th><td><a href="#6.2"><code>NMTOKENS</code> and <code>IDREFS</code> Parsers</a></td></tr> +          <tr><th>6.3</th><td><a href="#6.3"><code>base64Binary</code> and <code>hexBinary</code> Parsers</a></td></tr> +	  <tr><th>6.4</th><td><a href="#6.4">Time Zone Representation</a></td></tr> +	  <tr><th>6.5</th><td><a href="#6.5"><code>date</code> Parser</a></td></tr> +	  <tr><th>6.6</th><td><a href="#6.6"><code>dateTime</code> Parser</a></td></tr> +	  <tr><th>6.7</th><td><a href="#6.7"><code>duration</code> Parser</a></td></tr> +	  <tr><th>6.8</th><td><a href="#6.8"><code>gDay</code> Parser</a></td></tr> +	  <tr><th>6.9</th><td><a href="#6.9"><code>gMonth</code> Parser</a></td></tr> +	  <tr><th>6.10</th><td><a href="#6.10"><code>gMonthDay</code> Parser</a></td></tr> +	  <tr><th>6.11</th><td><a href="#6.11"><code>gYear</code> Parser</a></td></tr> +	  <tr><th>6.12</th><td><a href="#6.12"><code>gYearMonth</code> Parser</a></td></tr> +	  <tr><th>6.13</th><td><a href="#6.13"><code>time</code> Parser</a></td></tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>7</th><td><a href="#7">Document Parser and Error Handling</a> +        <table class="toc"> +          <tr><th>7.1</th><td><a href="#7.1">Xerces-C++ Document Parser</a></td></tr> +          <tr><th>7.2</th><td><a href="#7.2">Expat Document Parser</a></td></tr> +          <tr><th>7.3</th><td><a href="#7.3">Error Handling</a></td></tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th></th><td><a href="#A">Appendix A — Supported XML Schema Constructs</a></td> +    </tr> + +  </table> +  </div> + +  <h1><a name="0">Preface</a></h1> + +  <h2><a name="0.1">About This Document</a></h2> + +  <p>The goal of this document is to provide you with an understanding of +     the C++/Parser programming model and allow you to efficiently evaluate +     XSD against your project's technical requirements. As such, this +     document is intended for C++ developers and software architects +     who are looking for an XML processing solution. Prior experience +     with XML and C++ is required to understand this document. Basic +     understanding of XML Schema is advantageous but not expected +     or required. +  </p> + + +  <h2><a name="0.2">More Information</a></h2> + +  <p>Beyond this guide, you may also find the following sources of +     information useful:</p> + +  <ul class="list"> +    <li><a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD +        Compiler Command Line Manual</a></li> + +    <li>The <code>cxx/parser/</code> directory in the +        <a href="https://cppget.org/xsd-examples">xsd-examples</a> package +        contains a collection of examples and a README file with an overview +        of each example.</li> + +    <li>The <code>README</code> file in the +        <a href="https://cppget.org/xsd-examples">xsd-examples</a> package +        explains how to build the examples.</li> + +    <li>The <a href="https://www.codesynthesis.com/mailman/listinfo/xsd-users">xsd-users</a> +        mailing list is the place to ask technical questions about XSD and the C++/Parser mapping. +        Furthermore, the <a href="https://www.codesynthesis.com/pipermail/xsd-users/">archives</a> +        may already have answers to some of your questions.</li> + +  </ul> + +  <!-- Introduction --> + +  <h1><a name="1">1 Introduction</a></h1> + +  <p>Welcome to CodeSynthesis XSD and the C++/Parser mapping. XSD is a +     cross-platform W3C XML Schema to C++ data binding compiler. C++/Parser +     is a W3C XML Schema to C++ mapping that represents an XML vocabulary +     as a set of parser skeletons which you can implement to perform XML +     processing as required by your application logic. +  </p> + +  <h2><a name="1.1">1.1 Mapping Overview</a></h2> + +  <p>The C++/Parser mapping provides event-driven, stream-oriented +     XML parsing, XML Schema validation, and C++ data binding. It was +     specifically designed and optimized for high performance and +     small footprint. Based on the static analysis of the schemas, XSD +     generates compact, highly-optimized hierarchical state machines +     that combine data extraction, validation, and even dispatching +     in a single step. As a result, the generated code is typically +     2-10 times faster than general-purpose validating XML parsers +     while maintaining the lowest static and dynamic memory footprints. +  </p> + +  <p>To speed up application development, the C++/Parser mapping +     can be instructed to generate sample parser implementations +     and a test driver which can then be filled with the application +     logic code. The mapping also provides a wide range of +     mechanisms for controlling and customizing the generated code.</p> + +  <p>The next chapter shows how to create a simple application that uses +     the C++/Parser mapping to parse, validate, and extract data from a +     simple XML document. The following chapters show how to +     use the C++/Parser mapping in more detail.</p> + +  <h2><a name="1.2">1.2 Benefits</a></h2> + +  <p>Traditional XML access APIs such as Document Object Model (DOM) +     or Simple API for XML (SAX) have a number of drawbacks that +     make them less suitable for creating robust and maintainable +     XML processing applications. These drawbacks include: +  </p> + +  <ul class="list"> +    <li>Generic representation of XML in terms of elements, attributes, +        and text forces an application developer to write a substantial +        amount of bridging code that identifies and transforms pieces +        of information encoded in XML to a representation more suitable +        for consumption by the application logic.</li> + +    <li>String-based flow control defers error detection to runtime. +        It also reduces code readability and maintainability.</li> + +    <li>Lack of type safety because the data is represented +        as text.</li> + +    <li>Resulting applications are hard to debug, change, and +        maintain.</li> +  </ul> + +  <p>In contrast, statically-typed, vocabulary-specific parser +     skeletons produced by the C++/Parser mapping allow you to +     operate in your domain terms instead of the generic elements, +     attributes, and text. Static typing helps catch errors at +     compile-time rather than at run-time. Automatic code generation +     frees you for more interesting tasks (such as doing something +     useful with the information stored in the XML documents) and +     minimizes the effort needed to adapt your applications to +     changes in the document structure. To summarize, the C++/Parser +     mapping has the following key advantages over generic XML +     access APIs:</p> + +  <ul class="list"> +    <li><b>Ease of use.</b> The generated code hides all the complexity +        associated with recreating the document structure, maintaining the +        dispatch state, and converting the data from the text representation +        to data types suitable for manipulation by the application logic. +        Parser skeletons also provide a convenient mechanism for building +        custom in-memory representations.</li> + +    <li><b>Natural representation.</b> The generated parser skeletons +        implement parser callbacks as virtual functions with names +        corresponding to elements and attributes in XML. As a result, +        you process the XML data using your domain vocabulary instead +        of generic elements, attributes, and text. +    </li> + +    <li><b>Concise code.</b> With a separate parser skeleton for each +        XML Schema type, the application implementation is +        simpler and thus easier to read and understand.</li> + +    <li><b>Safety.</b> The XML data is delivered to parser callbacks as +        statically typed objects. The parser callbacks themselves are virtual +        functions. This helps catch programming errors at compile-time +        rather than at runtime.</li> + +    <li><b>Maintainability.</b> Automatic code generation minimizes the +        effort needed to adapt the application to changes in the +        document structure. With static typing, the C++ compiler +        can pin-point the places in the application code that need to be +        changed.</li> + +   <li><b>Efficiency.</b> The generated parser skeletons combine +       data extraction, validation, and even dispatching in a single +       step. This makes them much more efficient than traditional +       architectures with separate stages for validation and data +       extraction/dispatch.</li> +  </ul> + +  <!-- Hello World Parser --> + + +  <h1><a name="2">2 Hello World Example</a></h1> + +  <p>In this chapter we will examine how to parse a very simple XML +     document using the XSD-generated C++/Parser skeletons. +     The code presented in this chapter is based on the <code>hello</code> +     example which can be found in the <code>cxx/parser/</code> directory in +     the <a href="https://cppget.org/xsd-examples">xsd-examples</a> +     package.</p> + +  <h2><a name="2.1">2.1 Writing XML Document and Schema</a></h2> + +  <p>First, we need to get an idea about the structure +     of the XML documents we are going to process. Our +     <code>hello.xml</code>, for example, could look like this:</p> + +  <pre class="xml"> +<?xml version="1.0"?> +<hello> + +  <greeting>Hello</greeting> + +  <name>sun</name> +  <name>moon</name> +  <name>world</name> + +</hello> +  </pre> + +  <p>Then we can write a description of the above XML in the +     XML Schema language and save it into <code>hello.xsd</code>:</p> + +  <pre class="xml"> +<?xml version="1.0"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + +  <xs:complexType name="hello"> +    <xs:sequence> +      <xs:element name="greeting" type="xs:string"/> +      <xs:element name="name" type="xs:string" maxOccurs="unbounded"/> +    </xs:sequence> +  </xs:complexType> + +  <xs:element name="hello" type="hello"/> + +</xs:schema> +  </pre> + +  <p>Even if you are not familiar with XML Schema, it +     should be easy to connect declarations in <code>hello.xsd</code> +     to elements in <code>hello.xml</code>. The <code>hello</code> type +     is defined as a sequence of the nested <code>greeting</code> and +     <code>name</code> elements. Note that the term sequence in XML +     Schema means that elements should appear in a particular order +     as opposed to appearing multiple times. The <code>name</code> +     element has its <code>maxOccurs</code> property set to +     <code>unbounded</code> which means it can appear multiple times +     in an XML document. Finally, the globally-defined <code>hello</code> +     element prescribes the root element for our vocabulary. For an +     easily-approachable introduction to XML Schema refer to +     <a href="http://www.w3.org/TR/xmlschema-0/">XML Schema Part 0: +     Primer</a>.</p> + +  <p>The above schema is a specification of our XML vocabulary; it tells +     everybody what valid documents of our XML-based language should look +     like. The next step is to compile this schema to generate +     the object model and parsing functions.</p> + +  <h2><a name="2.2">2.2 Translating Schema to C++</a></h2> + +  <p>Now we are ready to translate our <code>hello.xsd</code> to C++ parser +     skeletons. To do this we invoke the XSD compiler from a terminal +     (UNIX) or a command prompt (Windows): +  </p> + +  <pre class="terminal"> +$ xsd cxx-parser --xml-parser expat hello.xsd +  </pre> + +  <p>The <code>--xml-parser</code> option indicates that we want to +     use Expat as the underlying XML parser (see <a href="#5.3">Section +     5.3, "Underlying XML Parser"</a>). The XSD compiler produces two +     C++ files: <code>hello-pskel.hxx</code> and <code>hello-pskel.cxx</code>. +     The following code fragment is taken from <code>hello-pskel.hxx</code>; +     it should give you an idea about what gets generated: +  </p> + +  <pre class="c++"> +class hello_pskel +{ +public: +  // Parser callbacks. Override them in your implementation. +  // +  virtual void +  pre (); + +  virtual void +  greeting (const std::string&); + +  virtual void +  name (const std::string&); + +  virtual void +  post_hello (); + +  // Parser construction API. +  // +  void +  greeting_parser (xml_schema::string_pskel&); + +  void +  name_parser (xml_schema::string_pskel&); + +  void +  parsers (xml_schema::string_pskel& /* greeting */, +           xml_schema::string_pskel& /* name */); + +private: +  ... +}; +  </pre> + +  <p>The first four member functions shown above are called parser +     callbacks. You would normally override them in your implementation +     of the parser to do something useful. Let's go through all of +     them one by one.</p> + +  <p>The <code>pre()</code> function is an initialization callback. It is +    called when a new element of type <code>hello</code> is about +    to be parsed. You would normally use this function to allocate a new +    instance of the resulting type or clear accumulators that are used +    to gather information during parsing. The default implementation +    of this function does nothing.</p> + +  <p>The <code>post_hello()</code> function is a finalization callback. Its +     name is constructed by adding the parser skeleton name to the +     <code>post_</code> prefix. The finalization callback is called when +     parsing of the element is complete and the result, if any, should +     be returned. Note that in our case the return type of +     <code>post_hello()</code> is <code>void</code> which means there +     is nothing to return. More on parser return types later. +  </p> + +  <p>You may be wondering why the finalization callback is called +     <code>post_hello()</code> instead of <code>post()</code> just +     like <code>pre()</code>. The reason for this is that +     finalization callbacks can have different return types and +     result in function signature clashes across inheritance +     hierarchies. To prevent this the signatures of finalization +     callbacks are made unique by adding the type name to their names.</p> + +  <p>The <code>greeting()</code> and <code>name()</code> functions are +     called when the <code>greeting</code> and <code>name</code> elements +     have been parsed, respectively. Their arguments are of type +     <code>std::string</code> and contain the data extracted from XML.</p> + +  <p>The last three functions are for connecting parsers to each other. +     For example, there is a predefined parser for built-in XML Schema type +     <code>string</code> in the XSD runtime. We will be using +     it to parse the contents of <code>greeting</code> and +     <code>name</code> elements, as shown in the next section.</p> + +  <h2><a name="2.3">2.3 Implementing Application Logic</a></h2> + +  <p>At this point we have all the parts we need to do something useful +     with the information stored in our XML document. The first step is +     to implement the parser: +  </p> + +  <pre class="c++"> +#include <iostream> +#include "hello-pskel.hxx" + +class hello_pimpl: public hello_pskel +{ +public: +  virtual void +  greeting (const std::string& g) +  { +    greeting_ = g; +  } + +  virtual void +  name (const std::string& n) +  { +    std::cout << greeting_ << ", " << n << "!" << std::endl; +  } + +private: +  std::string greeting_; +}; +  </pre> + +  <p>We left both <code>pre()</code> and <code>post_hello()</code> with the +     default implementations; we don't have anything to initialize or +     return. The rest is pretty straightforward: we store the greeting +     in a member variable and later, when parsing names, use it to +     say hello.</p> + +  <p>An observant reader my ask what happens if the <code>name</code> +     element comes before <code>greeting</code>? Don't we need to +     make sure <code>greeting_</code> was initialized and report +     an error otherwise? The answer is no, we don't have to do +     any of this. The <code>hello_pskel</code> parser skeleton +     performs validation of XML according to the schema from which +     it was generated. As a result, it will check the order +     of the <code>greeting</code> and <code>name</code> elements +     and report an error if it is violated.</p> + +  <p>Now it is time to put this parser implementation to work:</p> + +  <pre class="c++"> +using namespace std; + +int +main (int argc, char* argv[]) +{ +  try +  { +    // Construct the parser. +    // +    xml_schema::string_pimpl string_p; +    hello_pimpl hello_p; + +    hello_p.greeting_parser (string_p); +    hello_p.name_parser (string_p); + +    // Parse the XML instance. +    // +    xml_schema::document doc_p (hello_p, "hello"); + +    hello_p.pre (); +    doc_p.parse (argv[1]); +    hello_p.post_hello (); +  } +  catch (const xml_schema::exception& e) +  { +    cerr << e << endl; +    return 1; +  } +} +  </pre> + +  <p>The first part of this code snippet instantiates individual parsers +     and assembles them into a complete vocabulary parser. +     <code>xml_schema::string_pimpl</code> is an implementation of a parser +     for built-in XML Schema type <code>string</code>. It is provided by +     the XSD runtime along with parsers for other built-in types (for +     more information on the built-in parsers see <a href="#6">Chapter 6, +     "Built-In XML Schema Type Parsers"</a>). We use <code>string_pimpl</code> +     to parse the <code>greeting</code> and <code>name</code> elements as +     indicated by the calls to <code>greeting_parser()</code> and +     <code>name_parser()</code>. +  </p> + +  <p>Then we instantiate a document parser (<code>doc_p</code>). The +     first argument to its constructor is the parser for +     the root element (<code>hello_p</code> in our case). The +     second argument is the root element name. +   </p> + +  <p>The final piece is the calls to <code>pre()</code>, <code>parse()</code>, +     and <code>post_hello()</code>. The call to <code>parse()</code> +     perform the actual XML parsing while the calls to <code>pre()</code> and +     <code>post_hello()</code> make sure that the parser for the root +     element can perform proper initialization and cleanup.</p> + +  <p>While our parser implementation and test driver are pretty small and +     easy to write by hand, for bigger XML vocabularies it can be a +     substantial effort. To help with this task XSD can automatically +     generate sample parser implementations and a test driver from your +     schemas. You can request the generation of a sample implementation with +     empty function bodies by specifying the <code>--generate-noop-impl</code> +     option. Or you can generate a sample implementation that prints the +     data store in XML by using the <code>--generate-print-impl</code> +     option. To request the generation of a test driver you can use the +     <code>--generate-test-driver</code> option. For more information +     on these options refer to the +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD +     Compiler Command Line Manual</a>. The <code>'generated'</code> example +     in the <a href="https://cppget.org/xsd-examples">xsd-examples</a> package +     shows the sample implementation generation feature in action.</p> + + +  <h2><a name="2.4">2.4 Compiling and Running</a></h2> + +  <p>After saving all the parts from the previous section in +     <code>driver.cxx</code>, we are ready to compile our first +     application and run it on the test XML document. On a UNIX +     system this can be done with the following commands: +  </p> + +  <pre class="terminal"> +$ c++ -std=c++11 -I.../libxsd -c driver.cxx hello-pskel.cxx +$ c++ -std=c++11 -o driver driver.o hello-pskel.o -lexpat +$ ./driver hello.xml +Hello, sun! +Hello, moon! +Hello, world! +  </pre> + +  <p>Here <code>.../libxsd</code> represents the path to the +     <a href="https://cppget.org/libxsd">libxsd</a> package root +     directory. We can also test the error handling. To test XML +     well-formedness checking, we can try to parse +     <code>hello-pskel.hxx</code>:</p> + +  <pre class="terminal"> +$ ./driver hello-pskel.hxx +hello-pskel.hxx:1:0: not well-formed (invalid token) +  </pre> + +  <p>We can also try to parse a valid XML but not from our +     vocabulary, for example <code>hello.xsd</code>:</p> + +  <pre class="terminal"> +$ ./driver hello.xsd +hello.xsd:2:0: expected element 'hello' instead of +'http://www.w3.org/2001/XMLSchema#schema' +  </pre> + + +  <!-- Chapater 3 --> + + +  <h1><a name="3">3 Parser Skeletons</a></h1> + +  <p>As we have seen in the previous chapter, the XSD compiler generates +     a parser skeleton class for each type defined in XML Schema. In +     this chapter we will take a closer look at different functions +     that comprise a parser skeleton as well as the way to connect +     our implementations of these parser skeletons to create a complete +     parser.</p> + +  <p>In this and subsequent chapters we will use the following schema +     that describes a collection of person records. We save it in +     <code>people.xsd</code>:</p> + +  <pre class="xml"> +<?xml version="1.0"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + +  <xs:simpleType name="gender"> +    <xs:restriction base="xs:string"> +      <xs:enumeration value="male"/> +      <xs:enumeration value="female"/> +    </xs:restriction> +  </xs:simpleType> + +  <xs:complexType name="person"> +    <xs:sequence> +      <xs:element name="first-name" type="xs:string"/> +      <xs:element name="last-name" type="xs:string"/> +      <xs:element name="gender" type="gender"/> +      <xs:element name="age" type="xs:short"/> +    </xs:sequence> +  </xs:complexType> + +  <xs:complexType name="people"> +    <xs:sequence> +      <xs:element name="person" type="person" maxOccurs="unbounded"/> +    </xs:sequence> +  </xs:complexType> + +  <xs:element name="people" type="people"/> + +</xs:schema> +  </pre> + +  <p>A sample XML instance to go along with this schema is saved +     in <code>people.xml</code>:</p> + +  <pre class="xml"> +<?xml version="1.0"?> +<people> +  <person> +    <first-name>John</first-name> +    <last-name>Doe</last-name> +    <gender>male</gender> +    <age>32</age> +  </person> +  <person> +    <first-name>Jane</first-name> +    <last-name>Doe</last-name> +    <gender>female</gender> +    <age>28</age> +  </person> +</people> +  </pre> + +  <p>Compiling <code>people.xsd</code> with the XSD compiler results +     in three parser skeletons being generated: <code>gender_pskel</code>, +     <code>person_pskel</code>, and <code>people_pskel</code>. We are going +     to examine and implement each of them in the subsequent sections.</p> + +  <h2><a name="3.1">3.1 Implementing the Gender Parser</a></h2> + +  <p>The generated <code>gender_pskel</code> parser skeleton looks like +     this:</p> + +  <pre class="c++"> +class gender_pskel: public virtual xml_schema::string_pskel +{ +public: +  // Parser callbacks. Override them in your implementation. +  // +  virtual void +  pre (); + +  virtual void +  post_gender (); +}; +  </pre> + +  <p>Notice that <code>gender_pskel</code> inherits from +     <code>xml_schema::string_skel</code> which is a parser skeleton +     for built-in XML Schema type <code>string</code> and is +     predefined in the XSD runtime library. This is an example +     of the general rule that parser skeletons follow: if a type +     in XML Schema inherits from another then there will be an +     equivalent inheritance between the corresponding parser +     skeleton classes.</p> + +  <p>The <code>pre()</code> and <code>post_gender()</code> callbacks +     should look familiar from the previous chapter. Let's now +     implement the parser. Our implementation will simply print +     the gender to <code>cout</code>:</p> + + +  <pre class="c++"> +class gender_pimpl: public gender_pskel, +                    public xml_schema::string_pimpl +{ +public: +  virtual void +  post_gender () +  { +    std::string s = post_string (); +    cout << "gender: " << s << endl; +  } +}; +  </pre> + +  <p>While the code is quite short, there is a lot going on. First, +     notice that we are inheriting from <code>gender_pskel</code> <em>and</em> +     from <code>xml_schema::string_pimpl</code>. We've encountered +     <code>xml_schema::string_pimpl</code> already; it is an +     implementation of the <code>xml_schema::string_pskel</code> parser +     skeleton for built-in XML Schema type <code>string</code>.</p> + +  <p>This is another common theme in the C++/Parser programming model: +     reusing implementations of the base parsers in the derived ones with +     the C++ mixin idiom. In our case, <code>string_pimpl</code> will +     do all the dirty work of extracting the data and we can just get +     it at the end with the call to <code>post_string()</code>.</p> + +  <p>In case you are curious, here is what +     <code>xml_schema::string_pskel</code> and +     <code>xml_schema::string_pimpl</code> look like:</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class string_pskel: public simple_content +  { +  public: +    virtual std::string +    post_string () = 0; +  }; + +  class string_pimpl: public virtual string_pskel +  { +  public: +    virtual void +    _pre (); + +    virtual void +    _characters (const xml_schema::ro_string&); + +    virtual std::string +    post_string (); + +  protected: +    std::string str_; +  }; +} +  </pre> + +  <p>There are three new pieces in this code that we haven't seen yet. +     They are the <code>simple_content</code> class as well as +     the <code>_pre()</code> and <code>_characters()</code> functions. +     The <code>simple_content</code> class is defined in the XSD +     runtime and is a base class for all parser skeletons that conform +     to the simple content model in XML Schema. Types with the +     simple content model cannot have nested elements—only text +     and attributes. There is also the <code>complex_content</code> +     class which corresponds to the complex content mode (types with +     nested elements, for example, <code>person</code> from +     <code>people.xsd</code>).</p> + +  <p>The <code>_pre()</code> function is a parser callback. Remember we +     talked about the <code>pre()</code> and <code>post_*()</code> callbacks +     in the previous chapter? There are actually two more callbacks +     with similar roles: <code>_pre()</code> and <code>_post ()</code>. +     As a result, each parser skeleton has four special callbacks:</p> + +  <pre class="c++"> +  virtual void +  pre (); + +  virtual void +  _pre (); + +  virtual void +  _post (); + +  virtual void +  post_name (); +  </pre> + +  <p><code>pre()</code> and <code>_pre()</code> are initialization +     callbacks. They get called in that order before a new instance of the type +     is about to be parsed. The difference between <code>pre()</code> and +     <code>_pre()</code> is conventional: <code>pre()</code> can +     be completely overridden by a derived parser. The derived +     parser can also override <code>_pre()</code> but has to always call +     the original version. This allows you to partition initialization +     into customizable and required parts.</p> + +  <p>Similarly, <code>_post()</code> and <code>post_name()</code> are +     finalization callbacks with exactly the same semantics: +    <code>post_name()</code> can be completely overridden by the derived +     parser while the original <code>_post()</code> should always be called. +  </p> + +  <p>The final bit we need to discuss in this section is the +     <code>_characters()</code> function. As you might have guessed, it +     is also a callback. A low-level one that delivers raw character content +     for the type being parsed. You will seldom need to use this callback +     directly. Using implementations for the built-in parsers provided by +     the XSD runtime is usually a simpler and more convenient +     alternative.</p> + +  <p>At this point you might be wondering why some <code>post_*()</code> +     callbacks, for example <code>post_string()</code>, return some data +     while others, for example <code>post_gender()</code>, have +     <code>void</code> as a return type. This is a valid concern +     and it will be addressed in the next chapter.</p> + +  <h2><a name="3.2">3.2 Implementing the Person Parser</a></h2> + +  <p>The generated <code>person_pskel</code> parser skeleton looks like +     this:</p> + +  <pre class="c++"> +class person_pskel: public xml_schema::complex_content +{ +public: +  // Parser callbacks. Override them in your implementation. +  // +  virtual void +  pre (); + +  virtual void +  first_name (const std::string&); + +  virtual void +  last_name (const std::string&); + +  virtual void +  gender (); + +  virtual void +  age (short); + +  virtual void +  post_person (); + +  // Parser construction API. +  // +  void +  first_name_parser (xml_schema::string_pskel&); + +  void +  last_name_parser (xml_schema::string_pskel&); + +  void +  gender_parser (gender_pskel&); + +  void +  age_parser (xml_schema::short_pskel&); + +  void +  parsers (xml_schema::string_pskel& /* first-name */, +           xml_schema::string_pskel& /* last-name */, +           gender_pskel&             /* gender */, +           xml_schema::short_pskel&  /* age */); +}; +  </pre> + + +  <p>As you can see, we have a parser callback for each of the nested +     elements found in the <code>person</code> XML Schema type. +     The implementation of this parser is straightforward:</p> + +  <pre class="c++"> +class person_pimpl: public person_pskel +{ +public: +  virtual void +  first_name (const std::string& n) +  { +    cout << "first: " << f << endl; +  } + +  virtual void +  last_name (const std::string& l) +  { +    cout << "last: " << l << endl; +  } + +  virtual void +  age (short a) +  { +    cout << "age: " << a << endl; +  } +}; +  </pre> + +  <p>Notice that we didn't override the <code>gender()</code> callback +     because all the printing is done by <code>gender_pimpl</code>.</p> + + +  <h2><a name="3.3">3.3 Implementing the People Parser</a></h2> + +  <p>The generated <code>people_pskel</code> parser skeleton looks like +     this:</p> + +  <pre class="c++"> +class people_pskel: public xml_schema::complex_content +{ +public: +  // Parser callbacks. Override them in your implementation. +  // +  virtual void +  pre (); + +  virtual void +  person (); + +  virtual void +  post_people (); + +  // Parser construction API. +  // +  void +  person_parser (person_pskel&); + +  void +  parsers (person_pskel& /* person */); +}; +  </pre> + +  <p>The <code>person()</code> callback will be called after parsing each +     <code>person</code> element. While <code>person_pimpl</code> does +     all the printing, one useful thing we can do in this callback is to +     print an extra newline after each person record so that our +     output is more readable:</p> + +  <pre class="c++"> +class people_pimpl: public people_pskel +{ +public: +  virtual void +  person () +  { +    cout << endl; +  } +}; +  </pre> + +  <p>Now it is time to put everything together.</p> + + +  <h2><a name="3.4">3.4 Connecting the Parsers Together</a></h2> + +  <p>At this point we have all the individual parsers implemented +     and can proceed to assemble them into a complete parser +     for our XML vocabulary. The first step is to instantiate +     all the individual parsers that we will need:</p> + +  <pre class="c++"> +xml_schema::short_pimpl short_p; +xml_schema::string_pimpl string_p; + +gender_pimpl gender_p; +person_pimpl person_p; +people_pimpl people_p; +  </pre> + +  <p>Notice that our schema uses two built-in XML Schema types: +     <code>string</code> for the <code>first-name</code> and +     <code>last-name</code> elements as well as <code>short</code> +     for <code>age</code>. We will use predefined parsers that +     come with the XSD runtime to handle these types. The next +     step is to connect all the individual parsers. We do this +     with the help of functions defined in the parser +     skeletons and marked with the "Parser Construction API" +     comment. One way to do it is to connect each individual +     parser by calling the <code>*_parser()</code> functions:</p> + +  <pre class="c++"> +person_p.first_name_parser (string_p); +person_p.last_name_parser (string_p); +person_p.gender_parser (gender_p); +person_p.age_parser (short_p); + +people_p.person_parser (person_p); +  </pre> + +  <p>You might be wondering what happens if you do not provide +     a parser by not calling one of the <code>*_parser()</code> functions. +     In that case the corresponding XML content will be skipped, +     including validation. This is an efficient way to ignore parts +     of the document that you are not interested in.</p> + + +  <p>An alternative, shorter, way to connect the parsers is by using +     the <code>parsers()</code> functions which connects all the parsers +     for a given type at once:</p> + +  <pre class="c++"> +person_p.parsers (string_p, string_p, gender_p, short_p); +people_p.parsers (person_p); +  </pre> + +  <p>The following figure illustrates the resulting connections. Notice +     the correspondence between return types of the <code>post_*()</code> +     functions and argument types of element callbacks that are connected +     by the arrows.</p> + +  <!-- align=center is needed for html2ps --> +  <div class="img" align="center"><img src="figure-1.png"/></div> + +  <p>The last step is the construction of the document parser and +     invocation of the complete parser on our sample XML instance:</p> + +  <pre class="c++"> +xml_schema::document doc_p (people_p, "people"); + +people_p.pre (); +doc_p.parse ("people.xml"); +people_p.post_people (); +  </pre> + +  <p>Let's consider <code>xml_schema::document</code> in +     more detail. While the exact definition of this class +     varies depending on the underlying parser selected, +     here is the common part:</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class document +  { +  public: +    document (xml_schema::parser_base&, +              const std::string& root_element_name, +              bool polymorphic = false); + +    document (xml_schema::parser_base&, +              const std::string& root_element_namespace, +              const std::string& root_element_name, +              bool polymorphic = false); + +    void +    parse (const std::string& file); + +    void +    parse (std::istream&); + +    ... + +  }; +} +  </pre> + +   <p><code>xml_schema::document</code> is a root parser for +     the vocabulary. The first argument to its constructors is the +     parser for the type of the root element (<code>people_impl</code> +     in our case). Because a type parser is only concerned with +     the element's content and not with the element's name, we need +     to specify the root element's name somewhere. That's +     what is passed as the second and third arguments to the +     <code>document</code>'s constructors.</p> + +   <p>There are also two overloaded <code>parse()</code> functions +      defined in the <code>document</code> class (there are actually +      more but the others are specific to the underlying XML parser). +      The first version parses a local file identified by a name. The +      second version reads the data from an input stream. For more +      information on the <code>xml_schema::document</code> class +      refer to <a href="#7">Chapter 7, "Document Parser and Error +      Handling"</a>.</p> + +   <p>Let's now consider a step-by-step list of actions that happen +      as we parse through <code>people.xml</code>. The content of +      <code>people.xml</code> is repeated below for convenience.</p> + +  <pre class="xml"> +<?xml version="1.0"?> +<people> +  <person> +    <first-name>John</first-name> +    <last-name>Doe</last-name> +    <gender>male</gender> +    <age>32</age> +  </person> +  <person> +    <first-name>Jane</first-name> +    <last-name>Doe</last-name> +    <gender>female</gender> +    <age>28</age> +  </person> +</people> +  </pre> + + +   <ol class="steps"> +     <li><code>people_p.pre()</code> is called from +         <code>main()</code>. We did not provide any implementation +         for this callback so this call is a no-op.</li> + +     <li><code>doc_p.parse("people.xml")</code> is called from +         <code>main()</code>. The parser opens the file and starts +         parsing its content.</li> + +     <li>The parser encounters the root element. <code>doc_p</code> +         verifies that the root element is correct and calls +         <code>_pre()</code> on <code>people_p</code> which is also +         a no-op. Parsing is now delegated to <code>people_p</code>.</li> + +     <li>The parser encounters the <code>person</code> element. +         <code>people_p</code> determines that <code>person_p</code> +         is responsible for parsing this element. <code>pre()</code> +         and <code>_pre()</code> callbacks are called on <code>person_p</code>. +         Parsing is now delegated to <code>person_p</code>.</li> + +     <li>The parser encounters the <code>first-name</code> element. +         <code>person_p</code> determines that <code>string_p</code> +         is responsible for parsing this element. <code>pre()</code> +         and <code>_pre()</code> callbacks are called on <code>string_p</code>. +         Parsing is now delegated to <code>string_p</code>.</li> + +     <li>The parser encounters character content consisting of +         <code>"John"</code>. The <code>_characters()</code> callback is +         called on <code>string_p</code>.</li> + +     <li>The parser encounters the end of <code>first-name</code> +         element. The <code>_post()</code> and <code>post_string()</code> +         callbacks are called on <code>string_p</code>. The +         <code>first_name()</code> callback is called on <code>person_p</code> +         with the return value of <code>post_string()</code>. The +         <code>first_name()</code> implementation prints +         <code>"first: John"</code> to <code>cout</code>. +         Parsing is now returned to <code>person_p</code>.</li> + +     <li>Steps analogous to 5-7 are performed for the <code>last-name</code>, +         <code>gender</code>, and <code>age</code> elements.</li> + +     <li>The parser encounters the end of <code>person</code> +         element. The <code>_post()</code> and <code>post_person()</code> +         callbacks are called on <code>person_p</code>. The +         <code>person()</code> callback is called on <code>people_p</code>. +         The <code>person()</code> implementation prints a new line +         to <code>cout</code>. Parsing is now returned to +         <code>people_p</code>.</li> + +     <li>Steps 4-9 are performed for the second <code>person</code> +         element.</li> + +     <li>The parser encounters the end of <code>people</code> +         element. The <code>_post()</code> callback is called on +         <code>people_p</code>. The <code>doc_p.parse("people.xml")</code> +         call returns to <code>main()</code>.</li> + +     <li><code>people_p.post_people()</code> is called from +         <code>main()</code> which is a no-op.</li> + +   </ol> + + +  <!-- Chpater 4 --> + + +  <h1><a name="4">4 Type Maps</a></h1> + +  <p>There are many useful things you can do inside parser callbacks as they +     are right now. There are, however, times when you want to propagate +     some information from one parser to another or to the caller of the +     parser. One common task that would greatly benefit from such a +     possibility is building a tree-like in-memory object model of the +     data stored in XML. During execution, each individual sub-parser +     would create a sub-tree and return it to its <em>parent</em> parser +     which can then incorporate this sub-tree into the whole tree.</p> + +  <p>In this chapter we will discuss the mechanisms offered by the +     C++/Parser mapping for returning information from individual +     parsers and see how to use them to build an object model +     of our people vocabulary.</p> + +  <h2><a name="4.1">4.1 Object Model</a></h2> + +  <p>An object model for our person record example could +     look like this (saved in the <code>people.hxx</code> file):</p> + +  <pre class="c++"> +#include <string> +#include <vector> + +enum gender +{ +  male, +  female +}; + +class person +{ +public: +  person (const std::string& first, +          const std::string& last, +          ::gender gender, +          short age) +    : first_ (first), last_ (last), +      gender_ (gender), age_ (age) +  { +  } + +  const std::string& +  first () const +  { +    return first_; +  } + +  const std::string& +  last () const +  { +    return last_; +  } + +  ::gender +  gender () const +  { +    return gender_; +  } + +  short +  age () const +  { +    return age_; +  } + +private: +  std::string first_; +  std::string last_; +  ::gender gender_; +  short age_; +}; + +typedef std::vector<person> people; +  </pre> + +  <p>While it is clear which parser is responsible for which part of +     the object model, it is not exactly clear how, for +     example, <code>gender_pimpl</code> will deliver <code>gender</code> +     to <code>person_pimpl</code>. You might have noticed that +     <code>string_pimpl</code> manages to deliver its value to the +     <code>first_name()</code> callback of <code>person_pimpl</code>. Let's +     see how we can utilize the same mechanism to propagate our +     own data.</p> + +  <p>There is a way to tell the XSD compiler that you want to +     exchange data between parsers. More precisely, for each +     type defined in XML Schema, you can tell the compiler two things. +     First, the return type of the <code>post_*()</code> callback +     in the parser skeleton generated for this type. And, second, +     the argument type for callbacks corresponding to elements and +     attributes of this type. For example, for XML Schema type +     <code>gender</code> we can specify the return type for +     <code>post_gender()</code> in the <code>gender_pskel</code> +     skeleton and the argument type for the <code>gender()</code> callback +     in the <code>person_pskel</code> skeleton. As you might have guessed, +     the generated code will then pass the return value from the +     <code>post_*()</code> callback as an argument to the element or +     attribute callback.</p> + +  <p>The way to tell the XSD compiler about these XML Schema to +     C++ mappings is with type map files. Here is a simple type +     map for the <code>gender</code> type from the previous paragraph:</p> + +  <pre class="type-map"> +include "people.hxx"; +gender ::gender ::gender; +  </pre> + +  <p>The first line indicates that the generated code must include +     <code>people.hxx</code> in order to get the definition for the +     <code>gender</code> type. The second line specifies that both +     argument and return types for the <code>gender</code> +     XML Schema type should be the <code>::gender</code> C++ enum +     (we use fully-qualified C++ names to avoid name clashes). +     The next section will describe the type map format in detail. +     We save this type map in <code>people.map</code> and +     then translate our schemas with the <code>--type-map</code> +     option to let the XSD compiler know about our type map:</p> + +  <pre class="terminal"> +$ xsd cxx-parser --type-map people.map people.xsd +  </pre> + +  <p>If we now look at the generated <code>people-pskel.hxx</code>, +     we will see the following changes in the <code>gender_pskel</code> and +     <code>person_pskel</code> skeletons:</p> + +  <pre class="c++"> +#include "people.hxx" + +class gender_pskel: public virtual xml_schema::string_pskel +{ +  virtual ::gender +  post_gender () = 0; + +  ... +}; + +class person_pskel: public xml_schema::complex_content +{ +  virtual void +  gender (::gender); + +  ... +}; +  </pre> + +  <p>Notice that <code>#include "people.hxx"</code> was added to +     the generated header file from the type map to provide the +     definition for the <code>gender</code> enum.</p> + +  <h2><a name="4.2">4.2 Type Map File Format</a></h2> + +  <p>Type map files are used to define a mapping between XML Schema +     and C++ types. The compiler uses this information +     to determine return types of <code>post_*()</code> +     callbacks in parser skeletons corresponding to XML Schema +     types as well as argument types for callbacks corresponding +     to elements and attributes of these types.</p> + +  <p>The compiler has a set of predefined mapping rules that map +     the built-in XML Schema types to suitable C++ types (discussed +     below) and all other types to <code>void</code>. +     By providing your own type maps you can override these predefined +     rules. The format of the type map file is presented below: +  </p> + +  <pre class="type-map"> +namespace <schema-namespace> [<cxx-namespace>] +{ +  (include <file-name>;)* +  ([type] <schema-type> <cxx-ret-type> [<cxx-arg-type>];)* +} +  </pre> + +  <p>Both <code><i><schema-namespace></i></code> and +     <code><i><schema-type></i></code> are regex patterns while +     <code><i><cxx-namespace></i></code>, +     <code><i><cxx-ret-type></i></code>, and +     <code><i><cxx-arg-type></i></code> are regex pattern +     substitutions. All names can be optionally enclosed in +     <code>" "</code>, for example, to include white-spaces.</p> + +  <p><code><i><schema-namespace></i></code> determines XML +     Schema namespace. Optional <code><i><cxx-namespace></i></code> +     is prefixed to every C++ type name in this namespace declaration. +     <code><i><cxx-ret-type></i></code> is a C++ type name that is +     used as a return type for the <code>post_*()</code> callback. +     Optional <code><i><cxx-arg-type></i></code> is an argument +     type for callbacks corresponding to elements and attributes +     of this type. If <code><i><cxx-arg-type></i></code> is not +     specified, it defaults to <code><i><cxx-ret-type></i></code> +     if <code><i><cxx-ret-type></i></code> ends with <code>*</code> or +     <code>&</code> (that is, it is a pointer or a reference) and +     <code>const <i><cxx-ret-type></i>&</code> +     otherwise. +     <code><i><file-name></i></code> is a file name either in the +     <code>" "</code> or <code>< ></code> format +     and is added with the <code>#include</code> directive to +     the generated code.</p> + +  <p>The <code><b>#</b></code> character starts a comment that ends +     with a new line or end of file. To specify a name that contains +     <code><b>#</b></code> enclose it in <code><b>" "</b></code>. +     For example:</p> + +  <pre> +namespace http://www.example.com/xmlns/my my +{ +  include "my.hxx"; + +  # Pass apples by value. +  # +  apple apple; + +  # Pass oranges as pointers. +  # +  orange orange_t*; +} +  </pre> + +  <p>In the example above, for the +     <code>http://www.example.com/xmlns/my#orange</code> +     XML Schema type, the <code>my::orange_t*</code> C++ type will +     be used as both return and argument types.</p> + +  <p>Several namespace declarations can be specified in a single +     file. The namespace declaration can also be completely +     omitted to map types in a schema without a namespace. For +     instance:</p> + +  <pre class="type-map"> +include "my.hxx"; +apple apple; + +namespace http://www.example.com/xmlns/my +{ +  orange "const orange_t*"; +} +  </pre> + +  <p>The compiler has a number of predefined mapping rules for +     the built-in XML Schema types which can be presented as the +     following map files. The string-based XML Schema types are +     mapped to either <code>std::string</code> or +     <code>std::wstring</code> depending on the character type +     selected (see <a href="#5.2"> Section 5.2, "Character Type and +     Encoding"</a> for more information). The binary XML Schema +     types are mapped to either <code>std::unique_ptr<xml_schema::buffer></code> +     or <code>std::auto_ptr<xml_schema::buffer></code> +     depending on the C++ standard selected (C++11 or C++98, +     respectively; refer to the <code>--std</code> XSD compiler +     command line option for details).</p> + +  <pre class="type-map"> +namespace http://www.w3.org/2001/XMLSchema +{ +  boolean bool bool; + +  byte "signed char" "signed char"; +  unsignedByte "unsigned char" "unsigned char"; + +  short short short; +  unsignedShort "unsigned short" "unsigned short"; + +  int int int; +  unsignedInt "unsigned int" "unsigned int"; + +  long "long long" "long long"; +  unsignedLong "unsigned long long" "unsigned long long"; + +  integer "long long" "long long"; + +  negativeInteger "long long" "long long"; +  nonPositiveInteger "long long" "long long"; + +  positiveInteger "unsigned long long" "unsigned long long"; +  nonNegativeInteger "unsigned long long" "unsigned long long"; + +  float float float; +  double double double; +  decimal double double; + +  string std::string; +  normalizedString std::string; +  token std::string; +  Name std::string; +  NMTOKEN std::string; +  NCName std::string; +  ID std::string; +  IDREF std::string; +  language std::string; +  anyURI std::string; + +  NMTOKENS xml_schema::string_sequence; +  IDREFS xml_schema::string_sequence; + +  QName xml_schema::qname; + +  base64Binary std::[unique|auto]_ptr<xml_schema::buffer> +               std::[unique|auto]_ptr<xml_schema::buffer>; +  hexBinary std::[unique|auto]_ptr<xml_schema::buffer> +            std::[unique|auto]_ptr<xml_schema::buffer>; + +  date xml_schema::date; +  dateTime xml_schema::date_time; +  duration xml_schema::duration; +  gDay xml_schema::gday; +  gMonth xml_schema::gmonth; +  gMonthDay xml_schema::gmonth_day; +  gYear xml_schema::gyear; +  gYearMonth xml_schema::gyear_month; +  time xml_schema::time; +} +  </pre> + +  <p>For more information about the mapping of the built-in XML Schema types +     to C++ types refer to <a href="#6">Chapter 6, "Built-In XML Schema Type +     Parsers"</a>. The last predefined rule maps anything that wasn't +     mapped by previous rules to <code>void</code>:</p> + +  <pre class="type-map"> +namespace .* +{ +  .* void void; +} +  </pre> + + +  <p>When you provide your own type maps with the +     <code>--type-map</code> option, they are evaluated first. This +     allows you to selectively override any of the predefined rules. +     Note also that if you change the mapping +     of a built-in XML Schema type then it becomes your responsibility +     to provide the corresponding parser skeleton and implementation +     in the <code>xml_schema</code> namespace. You can include the +     custom definitions into the generated header file using the +     <code>--hxx-prologue-*</code> options.</p> + +  <h2><a name="4.3">4.3 Parser Implementations</a></h2> + +  <p>With the knowledge from the previous section, we can proceed +     with creating a type map that maps types in the <code>people.xsd</code> +     schema to our object model classes in +     <code>people.hxx</code>. In fact, we already have the beginning +     of our type map file in <code>people.map</code>. Let's extend +     it with the rest of the types:</p> + +  <pre class="type-map"> +include "people.hxx"; + +gender ::gender ::gender; +person ::person; +people ::people; +  </pre> + +  <p>There are a few things to note about this type map. We did not +     provide the argument types for <code>person</code> and +     <code>people</code> because the default constant reference is +     exactly what we need. We also did not provide any mappings +     for built-in XML Schema types <code>string</code> and +     <code>short</code> because they are handled by the predefined +     rules and we are happy with the result. Note also that +     all C++ types are fully qualified. This is done to avoid +     potential name conflicts in the generated code. Now we can +     recompile our schema and move on to implementing the parsers:</p> + +  <pre class="terminal"> +$ xsd cxx-parser --xml-parser expat --type-map people.map people.xsd +  </pre> + +  <p>Here is the implementation of our three parsers in full. One +     way to save typing when implementing your own parsers is +     to open the generated code and copy the signatures of parser +     callbacks into your code. Or you could always auto generate the +     sample implementations and fill them with your code.</p> + + +  <pre class="c++"> +#include "people-pskel.hxx" + +class gender_pimpl: public gender_pskel, +                    public xml_schema::string_pimpl +{ +public: +  virtual ::gender +  post_gender () +  { +    return post_string () == "male" ? male : female; +  } +}; + +class person_pimpl: public person_pskel +{ +public: +  virtual void +  first_name (const std::string& f) +  { +    first_ = f; +  } + +  virtual void +  last_name (const std::string& l) +  { +    last_ = l; +  } + +  virtual void +  gender (::gender g) +  { +    gender_ = g; +  } + +  virtual void +  age (short a) +  { +    age_ = a; +  } + +  virtual ::person +  post_person () +  { +    return ::person (first_, last_, gender_, age_); +  } + +private: +  std::string first_; +  std::string last_; +  ::gender gender_; +  short age_; +}; + +class people_pimpl: public people_pskel +{ +public: +  virtual void +  person (const ::person& p) +  { +    people_.push_back (p); +  } + +  virtual ::people +  post_people () +  { +    ::people r; +    r.swap (people_); +    return r; +  } + +private: +  ::people people_; +}; +  </pre> + +  <p>This code fragment should look familiar by now. Just note that +     all the <code>post_*()</code> callbacks now have return types instead +     of <code>void</code>. Here is the implementation of the test +     driver for this example:</p> + +  <pre class="c++"> +#include <iostream> + +using namespace std; + +int +main (int argc, char* argv[]) +{ +  // Construct the parser. +  // +  xml_schema::short_pimpl short_p; +  xml_schema::string_pimpl string_p; + +  gender_pimpl gender_p; +  person_pimpl person_p; +  people_pimpl people_p; + +  person_p.parsers (string_p, string_p, gender_p, short_p); +  people_p.parsers (person_p); + +  // Parse the document to obtain the object model. +  // +  xml_schema::document doc_p (people_p, "people"); + +  people_p.pre (); +  doc_p.parse (argv[1]); +  people ppl = people_p.post_people (); + +  // Print the object model. +  // +  for (people::iterator i (ppl.begin ()); i != ppl.end (); ++i) +  { +    cout << "first:  " << i->first () << endl +         << "last:   " << i->last () << endl +         << "gender: " << (i->gender () == male ? "male" : "female") << endl +         << "age:    " << i->age () << endl +         << endl; +  } +} +  </pre> + +  <p>The parser creation and assembly part is exactly the same as in +     the previous chapter. The parsing part is a bit different: +     <code>post_people()</code> now has a return value which is the +     complete object model. We store it in the +     <code>ppl</code> variable. The last bit of the code simply iterates +     over the <code>people</code> vector and prints the information +     for each person. We save the last two code fragments to +     <code>driver.cxx</code> and proceed to compile and test +     our new application:</p> + + +  <pre class="terminal"> +$ c++ -std=c++11 -I.../libxsd -c driver.cxx people-pskel.cxx +$ c++ -std=c++11 -o driver driver.o people-pskel.o -lexpat +$ ./driver people.xml +first:  John +last:   Doe +gender: male +age:    32 + +first:  Jane +last:   Doe +gender: female +age:    28 +  </pre> + + +  <!-- Mapping Configuration --> + + +  <h1><a name="5">5 Mapping Configuration</a></h1> + +  <p>The C++/Parser mapping has a number of configuration parameters that +     determine the overall properties and behavior of the generated code. +     Configuration parameters are specified with the XSD command line +     options and include the C++ standard, the character type that is used +     by the generated code, the underlying XML parser, whether the XML Schema +     validation is performed in the generated code, and support for XML Schema +     polymorphism. This chapter describes these configuration +     parameters in more detail. For more ways to configure the generated +     code refer to the +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD +     Compiler Command Line Manual</a>. +  </p> + +  <h2><a name="5.1">5.1 C++ Standard</a></h2> + +  <p>The C++/Parser mapping provides support for ISO/IEC C++ 2011 (C++11) +     and ISO/IEC C++ 1998/2003 (C++98). To select the C++ standard for the +     generated code we use the <code>--std</code> XSD compiler command +     line option. While the majority of the examples in this guide use +     C++11, the document explains the C++11/98 usage difference and so +     they can easily be converted to C++98.</p> + +  <h2><a name="5.2">5.2 Character Type and Encoding</a></h2> + +  <p>The C++/Parser mapping has built-in support for two character types: +    <code>char</code> and <code>wchar_t</code>. You can select the +    character type with the <code>--char-type</code> command line +    option. The default character type is <code>char</code>. The +    string-based built-in XML Schema types are returned as either +    <code>std::string</code> or <code>std::wstring</code> depending +    on the character type selected.</p> + +  <p>Another aspect of the mapping that depends on the character type +     is character encoding. For the <code>char</code> character type +     the default encoding is UTF-8. Other supported encodings are +     ISO-8859-1, Xerces-C++ Local Code Page (LPC), as well as +     custom encodings. You can select which encoding should be used +     in the object model with the <code>--char-encoding</code> command +     line option.</p> + +  <p>For the <code>wchar_t</code> character type the encoding is +     automatically selected between UTF-16 and UTF-32/UCS-4 depending +     on the size of the <code>wchar_t</code> type. On some platforms +     (for example, Windows with Visual C++ and AIX with IBM XL C++) +     <code>wchar_t</code> is 2 bytes long. For these platforms the +     encoding is UTF-16. On other platforms <code>wchar_t</code> is 4 bytes +     long and UTF-32/UCS-4 is used.</p> + +  <p>Note also that the character encoding that is used in the object model +     is independent of the encodings used in input and output XML. In fact, +     all three (object mode, input XML, and output XML) can have different +     encodings.</p> + +  <h2><a name="5.3">5.3 Underlying XML Parser</a></h2> + +  <p>The C++/Parser mapping can be used with either Xerces-C++ or Expat +     as the underlying XML parser. You can select the XML parser with +     the <code>--xml-parser</code> command line option. Valid values +     for this option are <code>xerces</code> and <code>expat</code>. +     The default XML parser is Xerces-C++.</p> + +  <p>The generated code is identical for both parsers except for the +     <code>xml_schema::document</code> class in which some of the +     <code>parse()</code> functions are parser-specific as described +     in <a href="#7">Chapter 7, "Document Parser and Error Handling"</a>.</p> + + +  <h2><a name="5.4">5.4 XML Schema Validation</a></h2> + +  <p>The C++/Parser mapping provides support for validating a +     commonly-used subset of W3C XML Schema in the generated code. +     For the list of supported XML Schema constructs refer to +     <a href="#A">Appendix A, "Supported XML Schema Constructs"</a>.</p> + +  <p>By default validation in the generated code is disabled if +     the underlying XML parser is validating (Xerces-C++) and +     enabled otherwise (Expat). See <a href="#5.3">Section 5.3, +     "Underlying XML Parser"</a> for more information about +     the underlying XML parser. You can override the default +     behavior with the <code>--generate-validation</code> +     and <code>--suppress-validation</code> command line options.</p> + + +  <h2><a name="5.5">5.5 Support for Polymorphism</a></h2> + +  <p>By default the XSD compiler generates non-polymorphic code. If your +     vocabulary uses XML Schema polymorphism in the form of <code>xsi:type</code> +     and/or substitution groups, then you will need to compile your schemas +     with the <code>--generate-polymorphic</code> option to produce +     polymorphism-aware code as well as pass <code>true</code> as the last +     argument to the <code>xml_schema::document</code>'s constructors.</p> + +  <p>When using the polymorphism-aware generated code, you can specify +     several parsers for a single element by passing a parser map +     instead of an individual parser to the parser connection function +     for the element. One of the parsers will then be looked up and used +     depending on the <code>xsi:type</code> attribute value or an element +     name from a substitution group. Consider the following schema as an +     example:</p> + +  <pre class="xml"> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + +  <xs:complexType name="person"> +    <xs:sequence> +      <xs:element name="name" type="xs:string"/> +    </xs:sequence> +  </xs:complexType> + +  <!-- substitution group root --> +  <xs:element name="person" type="person"/> + +  <xs:complexType name="superman"> +    <xs:complexContent> +      <xs:extension base="person"> +        <xs:attribute name="can-fly" type="xs:boolean"/> +      </xs:extension> +    </xs:complexContent> +  </xs:complexType> + +  <xs:element name="superman" +              type="superman" +              substitutionGroup="person"/> + +  <xs:complexType name="batman"> +    <xs:complexContent> +      <xs:extension base="superman"> +        <xs:attribute name="wing-span" type="xs:unsignedInt"/> +      </xs:extension> +    </xs:complexContent> +  </xs:complexType> + +  <xs:element name="batman" +              type="batman" +              substitutionGroup="superman"/> + +  <xs:complexType name="supermen"> +    <xs:sequence> +      <xs:element ref="person" maxOccurs="unbounded"/> +    </xs:sequence> +  </xs:complexType> + +  <xs:element name="supermen" type="supermen"/> + +</xs:schema> +  </pre> + +  <p>Conforming XML documents can use the <code>superman</code> +     and <code>batman</code> types in place of the <code>person</code> +     type either by specifying the type with the <code>xsi:type</code> +     attributes or by using the elements from the substitution +     group, for instance:</p> + + +  <pre class="xml"> +<supermen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + +  <person> +    <name>John Doe</name> +  </person> + +  <superman can-fly="false"> +    <name>James "007" Bond</name> +  </superman> + +  <superman can-fly="true" wing-span="10" xsi:type="batman"> +    <name>Bruce Wayne</name> +  </superman> + +</supermen> +  </pre> + +  <p>To print the data stored in such XML documents we can implement +     the parsers as follows:</p> + +  <pre class="c++"> +class person_pimpl: public virtual person_pskel +{ +public: +  virtual void +  pre () +  { +    cout << "starting to parse person" << endl; +  } + +  virtual void +  name (const std::string& v) +  { +    cout << "name: " << v << endl; +  } + +  virtual void +  post_person () +  { +    cout << "finished parsing person" << endl; +  } +}; + +class superman_pimpl: public virtual superman_pskel, +                      public person_pimpl +{ +public: +  virtual void +  pre () +  { +    cout << "starting to parse superman" << endl; +  } + +  virtual void +  can_fly (bool v) +  { +    cout << "can-fly: " << v << endl; +  } + +  virtual void +  post_person () +  { +    post_superman (); +  } + +  virtual void +  post_superman () +  { +    cout << "finished parsing superman" << endl +  } +}; + +class batman_pimpl: public virtual batman_pskel, +                    public superman_pimpl +{ +public: +  virtual void +  pre () +  { +    cout << "starting to parse batman" << endl; +  } + +  virtual void +  wing_span (unsigned int v) +  { +    cout << "wing-span: " << v << endl; +  } + +  virtual void +  post_superman () +  { +    post_batman (); +  } + +  virtual void +  post_batman () +  { +    cout << "finished parsing batman" << endl; +  } +}; +  </pre> + +  <p>Note that because the derived type parsers (<code>superman_pskel</code> +     and <code>batman_pskel</code>) are called via the <code>person_pskel</code> +     interface, we have to override the <code>post_person()</code> +     virtual function in <code>superman_pimpl</code> to call +     <code>post_superman()</code> and the <code>post_superman()</code> +     virtual function in <code>batman_pimpl</code> to call +     <code>post_batman()</code>.</p> + +  <p>The following code fragment shows how to connect the parsers together. +     Notice that for the <code>person</code> element in the <code>supermen_p</code> +     parser we specify a parser map instead of a specific parser and we pass +     <code>true</code> as the last argument to the document parser constructor +     to indicate that we are parsing potentially-polymorphic XML documents:</p> + +  <pre class="c++"> +int +main (int argc, char* argv[]) +{ +  // Construct the parser. +  // +  xml_schema::string_pimpl string_p; +  xml_schema::boolean_pimpl boolean_p; +  xml_schema::unsigned_int_pimpl unsigned_int_p; + +  person_pimpl person_p; +  superman_pimpl superman_p; +  batman_pimpl batman_p; + +  xml_schema::parser_map_impl person_map; +  supermen_pimpl supermen_p; + +  person_p.parsers (string_p); +  superman_p.parsers (string_p, boolean_p); +  batman_p.parsers (string_p, boolean_p, unsigned_int_p); + +  // Here we are specifying a parser map which containes several +  // parsers that can be used to parse the person element. +  // +  person_map.insert (person_p); +  person_map.insert (superman_p); +  person_map.insert (batman_p); + +  supermen_p.person_parser (person_map); + +  // Parse the XML document. The last argument to the document's +  // constructor indicates that we are parsing polymorphic XML +  // documents. +  // +  xml_schema::document doc_p (supermen_p, "supermen", true); + +  supermen_p.pre (); +  doc_p.parse (argv[1]); +  supermen_p.post_supermen (); +} +  </pre> + +  <p>When polymorphism-aware code is generated, each element's +     <code>*_parser()</code> function is overloaded to also accept +     an object of the <code>xml_schema::parser_map</code> type. +     For example, the <code>supermen_pskel</code> class from the +     above example looks like this:</p> + +  <pre class="c++"> +class supermen_pskel: public xml_schema::parser_complex_content +{ +public: + +  ... + +  // Parser construction API. +  // +  void +  parsers (person_pskel&); + +  // Individual element parsers. +  // +  void +  person_parser (person_pskel&); + +  void +  person_parser (const xml_schema::parser_map&); + +  ... +}; +  </pre> + +  <p>Note that you can specify both the individual (static) parser and +     the parser map. The individual parser will be used when the static +     element type and the dynamic type of the object being parsed are +     the same. This is the case, for example, when there is no +     <code>xsi:type</code> attribute and the element hasn't been +     substituted. Because the individual parser for an element is +     cached and no map lookup is necessary, it makes sense to specify +     both the individual parser and the parser map when most of the +     objects being parsed are of the static type and optimal +     performance is important. The following code fragment shows +     how to change the above example to set both the individual +     parser and the parser map:</p> + +  <pre class="c++"> +int +main (int argc, char* argv[]) +{ +  ... + +  person_map.insert (superman_p); +  person_map.insert (batman_p); + +  supermen_p.person_parser (person_p); +  supermen_p.person_parser (person_map); + +  ... +} +  </pre> + + +  <p>The <code>xml_schema::parser_map</code> interface and the +     <code>xml_schema::parser_map_impl</code> default implementation +     are presented below:</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class parser_map +  { +  public: +    virtual parser_base* +    find (const ro_string* type) const = 0; +  }; + +  class parser_map_impl: public parser_map +  { +  public: +    void +    insert (parser_base&); + +    virtual parser_base* +    find (const ro_string* type) const; + +  private: +    parser_map_impl (const parser_map_impl&); + +    parser_map_impl& +    operator= (const parser_map_impl&); + +    ... +  }; +} +  </pre> + +  <p>The <code>type</code> argument in the <code>find()</code> virtual +     function is the type name and namespace from the xsi:type attribute +     (the namespace prefix is resolved to the actual XML namespace) +     or the type of an element from the substitution group in the form +     <code>"<name> <namespace>"</code> with the space and the +     namespace part absent if the type does not have a namespace. +     You can obtain a parser's dynamic type in the same format +     using the <code>_dynamic_type()</code> function. The static +     type can be obtained by calling the static <code>_static_type()</code> +     function, for example <code>person_pskel::_static_type()</code>. +     Both functions return a C string (<code>const char*</code> or +     <code>const wchar_t*</code>, depending on the character type +     used) which is valid for as long as the application is running. +     The following example shows how we can implement our own parser +     map using <code>std::map</code>:</p> + + +  <pre class="c++"> +#include <map> +#include <string> + +class parser_map: public xml_schema::parser_map +{ +public: + void + insert (xml_schema::parser_base& p) + { +   map_[p._dynamic_type ()] = &p; + } + + virtual xml_schema::parser_base* + find (const xml_schema::ro_string* type) const + { +   map::const_iterator i = map_.find (type); +   return i != map_.end () ? i->second : 0; + } + +private: +  typedef std::map<std::string, xml_schema::parser_base*> map; +  map map_; +}; +  </pre> + +  <p>Most of code presented in this section is taken from the +     <code>polymorphism</code> example which can be found in the +     <code>cxx/parser/</code> directory in the +     <a href="https://cppget.org/xsd-examples">xsd-examples</a> package. +     Handling of <code>xsi:type</code> and substitution groups when used on +     root elements requires a number of special actions as shown in +     the <code>polyroot</code> example.</p> + + +  <!-- Built-in XML Schema Type Parsers --> + + +  <h1><a name="6">6 Built-In XML Schema Type Parsers</a></h1> + +  <p>The XSD runtime provides parser implementations for all built-in +     XML Schema types as summarized in the following table. Declarations +     for these types are automatically included into each generated +     header file. As a result you don't need to include any headers +     to gain access to these parser implementations. Note that some +     parsers return either <code>std::string</code> or +     <code>std::wstring</code> depending on the character type selected.</p> + +  <!-- border="1" is necessary for html2ps --> +  <table id="builtin" border="1"> +    <tr> +      <th>XML Schema type</th> +      <th>Parser implementation in the <code>xml_schema</code> namespace</th> +      <th>Parser return type</th> +    </tr> + +    <tr> +      <th colspan="3">anyType and anySimpleType types</th> +    </tr> +    <tr> +      <td><code>anyType</code></td> +      <td><code>any_type_pimpl</code></td> +      <td><code>void</code></td> +    </tr> +    <tr> +      <td><code>anySimpleType</code></td> +      <td><code>any_simple_type_pimpl</code></td> +      <td><code>void</code></td> +    </tr> + +    <tr> +      <th colspan="3">fixed-length integral types</th> +    </tr> +    <!-- 8-bit --> +    <tr> +      <td><code>byte</code></td> +      <td><code>byte_pimpl</code></td> +      <td><code>signed char</code></td> +    </tr> +    <tr> +      <td><code>unsignedByte</code></td> +      <td><code>unsigned_byte_pimpl</code></td> +      <td><code>unsigned char</code></td> +    </tr> + +    <!-- 16-bit --> +    <tr> +      <td><code>short</code></td> +      <td><code>short_pimpl</code></td> +      <td><code>short</code></td> +    </tr> +    <tr> +      <td><code>unsignedShort</code></td> +      <td><code>unsigned_short_pimpl</code></td> +      <td><code>unsigned short</code></td> +    </tr> + +    <!-- 32-bit --> +    <tr> +      <td><code>int</code></td> +      <td><code>int_pimpl</code></td> +      <td><code>int</code></td> +    </tr> +    <tr> +      <td><code>unsignedInt</code></td> +      <td><code>unsigned_int_pimpl</code></td> +      <td><code>unsigned int</code></td> +    </tr> + +    <!-- 64-bit --> +    <tr> +      <td><code>long</code></td> +      <td><code>long_pimpl</code></td> +      <td><code>long long</code></td> +    </tr> +    <tr> +      <td><code>unsignedLong</code></td> +      <td><code>unsigned_long_pimpl</code></td> +      <td><code>unsigned long long</code></td> +    </tr> + +    <tr> +      <th colspan="3">arbitrary-length integral types</th> +    </tr> +    <tr> +      <td><code>integer</code></td> +      <td><code>integer_pimpl</code></td> +      <td><code>long long</code></td> +    </tr> +    <tr> +      <td><code>nonPositiveInteger</code></td> +      <td><code>non_positive_integer_pimpl</code></td> +      <td><code>long long</code></td> +    </tr> +    <tr> +      <td><code>nonNegativeInteger</code></td> +      <td><code>non_negative_integer_pimpl</code></td> +      <td><code>unsigned long long</code></td> +    </tr> +    <tr> +      <td><code>positiveInteger</code></td> +      <td><code>positive_integer_pimpl</code></td> +      <td><code>unsigned long long</code></td> +    </tr> +    <tr> +      <td><code>negativeInteger</code></td> +      <td><code>negative_integer_pimpl</code></td> +      <td><code>long long</code></td> +    </tr> + +    <tr> +      <th colspan="3">boolean types</th> +    </tr> +    <tr> +      <td><code>boolean</code></td> +      <td><code>boolean_pimpl</code></td> +      <td><code>bool</code></td> +    </tr> + +    <tr> +      <th colspan="3">fixed-precision floating-point types</th> +    </tr> +    <tr> +      <td><code>float</code></td> +      <td><code>float_pimpl</code></td> +      <td><code>float</code></td> +    </tr> +    <tr> +      <td><code>double</code></td> +      <td><code>double_pimpl</code></td> +      <td><code>double</code></td> +    </tr> + +    <tr> +      <th colspan="3">arbitrary-precision floating-point types</th> +    </tr> +    <tr> +      <td><code>decimal</code></td> +      <td><code>decimal_pimpl</code></td> +      <td><code>double</code></td> +    </tr> + +    <tr> +      <th colspan="3">string-based types</th> +    </tr> +    <tr> +      <td><code>string</code></td> +      <td><code>string_pimpl</code></td> +      <td><code>std::string</code> or <code>std::wstring</code></td> +    </tr> +    <tr> +      <td><code>normalizedString</code></td> +      <td><code>normalized_string_pimpl</code></td> +      <td><code>std::string</code> or <code>std::wstring</code></td> +    </tr> +    <tr> +      <td><code>token</code></td> +      <td><code>token_pimpl</code></td> +      <td><code>std::string</code> or <code>std::wstring</code></td> +    </tr> +    <tr> +      <td><code>Name</code></td> +      <td><code>name_pimpl</code></td> +      <td><code>std::string</code> or <code>std::wstring</code></td> +    </tr> +    <tr> +      <td><code>NMTOKEN</code></td> +      <td><code>nmtoken_pimpl</code></td> +      <td><code>std::string</code> or <code>std::wstring</code></td> +    </tr> +    <tr> +      <td><code>NCName</code></td> +      <td><code>ncname_pimpl</code></td> +      <td><code>std::string</code> or <code>std::wstring</code></td> +    </tr> + +    <tr> +      <td><code>language</code></td> +      <td><code>language_pimpl</code></td> +      <td><code>std::string</code> or <code>std::wstring</code></td> +    </tr> + +    <tr> +      <th colspan="3">qualified name</th> +    </tr> +    <tr> +      <td><code>QName</code></td> +      <td><code>qname_pimpl</code></td> +      <td><code>xml_schema::qname</code><br/><a href="#6.1">Section 6.1, +          "<code>QName</code> Parser"</a></td> +    </tr> + +    <tr> +      <th colspan="3">ID/IDREF types</th> +    </tr> +    <tr> +      <td><code>ID</code></td> +      <td><code>id_pimpl</code></td> +      <td><code>std::string</code> or <code>std::wstring</code></td> +    </tr> +    <tr> +      <td><code>IDREF</code></td> +      <td><code>idref_pimpl</code></td> +      <td><code>std::string</code> or <code>std::wstring</code></td> +    </tr> + +    <tr> +      <th colspan="3">list types</th> +    </tr> +    <tr> +      <td><code>NMTOKENS</code></td> +      <td><code>nmtokens_pimpl</code></td> +      <td><code>xml_schema::string_sequence</code><br/><a href="#6.2">Section +          6.2, "<code>NMTOKENS</code> and <code>IDREFS</code> Parsers"</a></td> +    </tr> +    <tr> +      <td><code>IDREFS</code></td> +      <td><code>idrefs_pimpl</code></td> +      <td><code>xml_schema::string_sequence</code><br/><a href="#6.2">Section +          6.2, "<code>NMTOKENS</code> and <code>IDREFS</code> Parsers"</a></td> +    </tr> + +    <tr> +      <th colspan="3">URI types</th> +    </tr> +    <tr> +      <td><code>anyURI</code></td> +      <td><code>uri_pimpl</code></td> +      <td><code>std::string</code> or <code>std::wstring</code></td> +    </tr> + +    <tr> +      <th colspan="3">binary types</th> +    </tr> +    <tr> +      <td><code>base64Binary</code></td> +      <td><code>base64_binary_pimpl</code></td> +      <td><code>std::[unique|auto]_ptr< xml_schema::buffer></code><br/> +          <a href="#6.3">Section 6.3, "<code>base64Binary</code> and +          <code>hexBinary</code> Parsers"</a></td> +    </tr> +    <tr> +      <td><code>hexBinary</code></td> +      <td><code>hex_binary_pimpl</code></td> +      <td><code>std::[unique|auto]_ptr< xml_schema::buffer></code><br/> +          <a href="#6.3">Section 6.3, "<code>base64Binary</code> and +          <code>hexBinary</code> Parsers"</a></td> +    </tr> + +    <tr> +      <th colspan="3">date/time types</th> +    </tr> +    <tr> +      <td><code>date</code></td> +      <td><code>date_pimpl</code></td> +      <td><code>xml_schema::date</code><br/><a href="#6.5">Section 6.5, +          "<code>date</code> Parser"</a></td> +    </tr> +    <tr> +      <td><code>dateTime</code></td> +      <td><code>date_time_pimpl</code></td> +      <td><code>xml_schema::date_time</code><br/><a href="#6.6">Section 6.6, +          "<code>dateTime</code> Parser"</a></td> +    </tr> +    <tr> +      <td><code>duration</code></td> +      <td><code>duration_pimpl</code></td> +      <td><code>xml_schema::duration</code><br/><a href="#6.7">Section 6.7, +          "<code>duration</code> Parser"</a></td> +    </tr> +    <tr> +      <td><code>gDay</code></td> +      <td><code>gday_pimpl</code></td> +      <td><code>xml_schema::gday</code><br/><a href="#6.8">Section 6.8, +          "<code>gDay</code> Parser"</a></td> +    </tr> +    <tr> +      <td><code>gMonth</code></td> +      <td><code>gmonth_pimpl</code></td> +      <td><code>xml_schema::gmonth</code><br/><a href="#6.9">Section 6.9, +          "<code>gMonth</code> Parser"</a></td> +    </tr> +    <tr> +      <td><code>gMonthDay</code></td> +      <td><code>gmonth_day_pimpl</code></td> +      <td><code>xml_schema::gmonth_day</code><br/><a href="#6.10">Section 6.10, +          "<code>gMonthDay</code> Parser"</a></td> +    </tr> +    <tr> +      <td><code>gYear</code></td> +      <td><code>gyear_pimpl</code></td> +      <td><code>xml_schema::gyear</code><br/><a href="#6.11">Section 6.11, +          "<code>gYear</code> Parser"</a></td> +    </tr> +    <tr> +      <td><code>gYearMonth</code></td> +      <td><code>gyear_month_pimpl</code></td> +      <td><code>xml_schema::gyear_month</code><br/><a href="#6.12">Section +          6.12, "<code>gYearMonth</code> Parser"</a></td> +    </tr> +    <tr> +      <td><code>time</code></td> +      <td><code>time_pimpl</code></td> +      <td><code>xml_schema::time</code><br/><a href="#6.13">Section 6.13, +          "<code>time</code> Parser"</a></td> +    </tr> + +  </table> + +  <h2><a name="6.1">6.1 <code>QName</code> Parser</a></h2> + +  <p>The return type of the <code>qname_pimpl</code> parser implementation +     is <code>xml_schema::qname</code> which represents an XML qualified +     name. Its interface is presented below. +     Note that the <code>std::string</code> type in the interface becomes +     <code>std::wstring</code> if the selected character type is +     <code>wchar_t</code>.</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class qname +  { +  public: +    explicit +    qname (const std::string& name); +    qname (const std::string& prefix, const std::string& name); + +    const std::string& +    prefix () const; + +    void +    prefix (const std::string&); + +    const std::string& +    name () const; + +    void +    name (const std::string&); +  }; + +  bool +  operator== (const qname&, const qname&); + +  bool +  operator!= (const qname&, const qname&); +} +  </pre> + + +  <h2><a name="6.2">6.2 <code>NMTOKENS</code> and <code>IDREFS</code> Parsers</a></h2> + +  <p>The return type of the <code>nmtokens_pimpl</code> and +     <code>idrefs_pimpl</code> parser implementations is +     <code>xml_schema::string_sequence</code> which represents a +     sequence of strings. Its interface is presented below. +     Note that the <code>std::string</code> type in the interface becomes +     <code>std::wstring</code> if the selected character type is +     <code>wchar_t</code>.</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class string_sequence: public std::vector<std::string> +  { +  public: +    string_sequence (); + +    explicit +    string_sequence (std::vector<std::string>::size_type n, +                     const std::string& x = std::string ()); + +    template <typename I> +    string_sequence (const I& begin, const I& end); +  }; + +  bool +  operator== (const string_sequence&, const string_sequence&); + +  bool +  operator!= (const string_sequence&, const string_sequence&); +} +  </pre> + + +  <h2><a name="6.3">6.3 <code>base64Binary</code> and <code>hexBinary</code> Parsers</a></h2> + +  <p>The return type of the <code>base64_binary_pimpl</code> and +     <code>hex_binary_pimpl</code> parser implementations is either +     <code>std::unique_ptr<xml_schema::buffer></code> (C++11) or +     <code>std::auto_ptr<xml_schema::buffer></code> (C++98), +     depending on the C++ standard selected (<code>--std</code> XSD +     compiler option). The <code>xml_schema::buffer</code> type +     represents a binary buffer and its interface is presented below.</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class buffer +  { +  public: +    typedef std::size_t size_t; + +    class bounds {}; // Out of bounds exception. + +  public: +    explicit +    buffer (size_t size = 0); +    buffer (size_t size, size_t capacity); +    buffer (const void* data, size_t size); +    buffer (const void* data, size_t size, size_t capacity); +    buffer (void* data, +            size_t size, +            size_t capacity, +            bool assume_ownership); + +  public: +    buffer (const buffer&); + +    buffer& +    operator= (const buffer&); + +    void +    swap (buffer&); + +  public: +    size_t +    capacity () const; + +    bool +    capacity (size_t); + +  public: +    size_t +    size () const; + +    bool +    size (size_t); + +  public: +    const char* +    data () const; + +    char* +    data (); + +    const char* +    begin () const; + +    char* +    begin (); + +    const char* +    end () const; + +    char* +    end (); +  }; + +  bool +  operator== (const buffer&, const buffer&); + +  bool +  operator!= (const buffer&, const buffer&); +} +  </pre> + +  <p>If the <code>assume_ownership</code> argument to the constructor +     is <code>true</code>, the instance assumes the ownership of the +     memory block pointed to by the <code>data</code> argument and will +     eventually release it by calling <code>operator delete()</code>. The +     <code>capacity()</code> and <code>size()</code> modifier functions +     return <code>true</code> if the underlying buffer has moved. +  </p> + +  <p>The <code>bounds</code> exception is thrown if the constructor +     arguments violate the <code>(size <= capacity)</code> +     constraint.</p> + + +  <h2><a name="6.4">6.4 Time Zone Representation</a></h2> + +  <p>The <code>date</code>, <code>dateTime</code>, <code>gDay</code>, +     <code>gMonth</code>, <code>gMonthDay</code>, <code>gYear</code>, +     <code>gYearMonth</code>, and <code>time</code> XML Schema built-in +     types all include an optional time zone component. The following +     <code>xml_schema::time_zone</code> base class is used to represent +     this information:</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class time_zone +  { +  public: +    time_zone (); +    time_zone (short hours, short minutes); + +    bool +    zone_present () const; + +    void +    zone_reset (); + +    short +    zone_hours () const; + +    void +    zone_hours (short); + +    short +    zone_minutes () const; + +    void +    zone_minutes (short); +  }; + +  bool +  operator== (const time_zone&, const time_zone&); + +  bool +  operator!= (const time_zone&, const time_zone&); +} +  </pre> + +  <p>The <code>zone_present()</code> accessor function returns <code>true</code> +     if the time zone is specified. The <code>zone_reset()</code> modifier +     function resets the time zone object to the <em>not specified</em> +     state. If the time zone offset is negative then both hours and +     minutes components are represented as negative integers.</p> + + +  <h2><a name="6.5">6.5 <code>date</code> Parser</a></h2> + + <p>The return type of the <code>date_pimpl</code> parser implementation +     is <code>xml_schema::date</code> which represents a year, a day, and a month +     with an optional time zone. Its interface is presented below. +     For more information on the base <code>xml_schema::time_zone</code> +     class refer to <a href="#6.4">Section 6.4, "Time Zone +     Representation"</a>.</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class date +  { +  public: +    date (int year, unsigned short month, unsigned short day); +    date (int year, unsigned short month, unsigned short day, +          short zone_hours, short zone_minutes); + +    int +    year () const; + +    void +    year (int); + +    unsigned short +    month () const; + +    void +    month (unsigned short); + +    unsigned short +    day () const; + +    void +    day (unsigned short); +  }; + +  bool +  operator== (const date&, const date&); + +  bool +  operator!= (const date&, const date&); +} +  </pre> + +  <h2><a name="6.6">6.6 <code>dateTime</code> Parser</a></h2> + +  <p>The return type of the <code>date_time_pimpl</code> parser implementation +     is <code>xml_schema::date_time</code> which represents a year, a month, a day, +     hours, minutes, and seconds with an optional time zone. Its interface +     is presented below. +     For more information on the base <code>xml_schema::time_zone</code> +     class refer to <a href="#6.4">Section 6.4, "Time Zone +     Representation"</a>.</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class date_time +  { +  public: +    date_time (int year, unsigned short month, unsigned short day, +               unsigned short hours, unsigned short minutes, +               double seconds); + +    date_time (int year, unsigned short month, unsigned short day, +               unsigned short hours, unsigned short minutes, +               double seconds, short zone_hours, short zone_minutes); + +    int +    year () const; + +    void +    year (int); + +    unsigned short +    month () const; + +    void +    month (unsigned short); + +    unsigned short +    day () const; + +    void +    day (unsigned short); + +    unsigned short +    hours () const; + +    void +    hours (unsigned short); + +    unsigned short +    minutes () const; + +    void +    minutes (unsigned short); + +    double +    seconds () const; + +    void +    seconds (double); +  }; + +  bool +  operator== (const date_time&, const date_time&); + +  bool +  operator!= (const date_time&, const date_time&); +} +  </pre> + +  <h2><a name="6.7">6.7 <code>duration</code> Parser</a></h2> + +  <p>The return type of the <code>duration_pimpl</code> parser implementation +     is <code>xml_schema::duration</code> which represents a potentially +     negative duration in the form of years, months, days, hours, minutes, +     and seconds. Its interface is presented below.</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class duration +  { +  public: +    duration (bool negative, +              unsigned int years, unsigned int months, unsigned int days, +              unsigned int hours, unsigned int minutes, double seconds); + +    bool +    negative () const; + +    void +    negative (bool); + +    unsigned int +    years () const; + +    void +    years (unsigned int); + +    unsigned int +    months () const; + +    void +    months (unsigned int); + +    unsigned int +    days () const; + +    void +    days (unsigned int); + +    unsigned int +    hours () const; + +    void +    hours (unsigned int); + +    unsigned int +    minutes () const; + +    void +    minutes (unsigned int); + +    double +    seconds () const; + +    void +    seconds (double); +  }; + +  bool +  operator== (const duration&, const duration&); + +  bool +  operator!= (const duration&, const duration&); +} +  </pre> + + +  <h2><a name="6.8">6.8 <code>gDay</code> Parser</a></h2> + +  <p>The return type of the <code>gday_pimpl</code> parser implementation +     is <code>xml_schema::gday</code> which represents a day of the month with +     an optional time zone. Its interface is presented below. +     For more information on the base <code>xml_schema::time_zone</code> +     class refer to <a href="#6.4">Section 6.4, "Time Zone +     Representation"</a>.</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class gday +  { +  public: +    explicit +    gday (unsigned short day); +    gday (unsigned short day, short zone_hours, short zone_minutes); + +    unsigned short +    day () const; + +    void +    day (unsigned short); +  }; + +  bool +  operator== (const gday&, const gday&); + +  bool +  operator!= (const gday&, const gday&); +} +  </pre> + +  <h2><a name="6.9">6.9 <code>gMonth</code> Parser</a></h2> + +  <p>The return type of the <code>gmonth_pimpl</code> parser implementation +     is <code>xml_schema::gmonth</code> which represents a month of the year +     with an optional time zone. Its interface is presented below. +     For more information on the base <code>xml_schema::time_zone</code> +     class refer to <a href="#6.4">Section 6.4, "Time Zone +     Representation"</a>.</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class gmonth +  { +  public: +    explicit +    gmonth (unsigned short month); +    gmonth (unsigned short month, short zone_hours, short zone_minutes); + +    unsigned short +    month () const; + +    void +    month (unsigned short); +  }; + +  bool +  operator== (const gmonth&, const gmonth&); + +  bool +  operator!= (const gmonth&, const gmonth&); +} +  </pre> + +  <h2><a name="6.10">6.10 <code>gMonthDay</code> Parser</a></h2> + +  <p>The return type of the <code>gmonth_day_pimpl</code> parser implementation +     is <code>xml_schema::gmonth_day</code> which represents a day and a month +     of the year with an optional time zone. Its interface is presented below. +     For more information on the base <code>xml_schema::time_zone</code> +     class refer to <a href="#6.4">Section 6.4, "Time Zone +     Representation"</a>.</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class gmonth_day +  { +  public: +    gmonth_day (unsigned short month, unsigned short day); +    gmonth_day (unsigned short month, unsigned short day, +                short zone_hours, short zone_minutes); + +    unsigned short +    month () const; + +    void +    month (unsigned short); + +    unsigned short +    day () const; + +    void +    day (unsigned short); +  }; + +  bool +  operator== (const gmonth_day&, const gmonth_day&); + +  bool +  operator!= (const gmonth_day&, const gmonth_day&); +} +  </pre> + +  <h2><a name="6.11">6.11 <code>gYear</code> Parser</a></h2> + +  <p>The return type of the <code>gyear_pimpl</code> parser implementation +     is <code>xml_schema::gyear</code> which represents a year with +     an optional time zone. Its interface is presented below. +     For more information on the base <code>xml_schema::time_zone</code> +     class refer to <a href="#6.4">Section 6.4, "Time Zone +     Representation"</a>.</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class gyear +  { +  public: +    explicit +    gyear (int year); +    gyear (int year, short zone_hours, short zone_minutes); + +    int +    year () const; + +    void +    year (int); +  }; + +  bool +  operator== (const gyear&, const gyear&); + +  bool +  operator!= (const gyear&, const gyear&); +} +  </pre> + +  <h2><a name="6.12">6.12 <code>gYearMonth</code> Parser</a></h2> + +  <p>The return type of the <code>gyear_month_pimpl</code> parser implementation +     is <code>xml_schema::gyear_month</code> which represents a year and a month +     with an optional time zone. Its interface is presented below. +     For more information on the base <code>xml_schema::time_zone</code> +     class refer to <a href="#6.4">Section 6.4, "Time Zone +     Representation"</a>.</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class gyear_month +  { +  public: +    gyear_month (int year, unsigned short month); +    gyear_month (int year, unsigned short month, +                 short zone_hours, short zone_minutes); + +    int +    year () const; + +    void +    year (int); + +    unsigned short +    month () const; + +    void +    month (unsigned short); +  }; + +  bool +  operator== (const gyear_month&, const gyear_month&); + +  bool +  operator!= (const gyear_month&, const gyear_month&); +} +  </pre> + + +  <h2><a name="6.13">6.13 <code>time</code> Parser</a></h2> + + <p>The return type of the <code>time_pimpl</code> parser implementation +     is <code>xml_schema::time</code> which represents hours, minutes, +     and seconds with an optional time zone. Its interface is presented below. +     For more information on the base <code>xml_schema::time_zone</code> +     class refer to <a href="#6.4">Section 6.4, "Time Zone +     Representation"</a>.</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class time +  { +  public: +    time (unsigned short hours, unsigned short minutes, double seconds); +    time (unsigned short hours, unsigned short minutes, double seconds, +          short zone_hours, short zone_minutes); + +    unsigned short +    hours () const; + +    void +    hours (unsigned short); + +    unsigned short +    minutes () const; + +    void +    minutes (unsigned short); + +    double +    seconds () const; + +    void +    seconds (double); +  }; + +  bool +  operator== (const time&, const time&); + +  bool +  operator!= (const time&, const time&); +} +  </pre> + + +  <!-- Error Handling --> + + +  <h1><a name="7">7 Document Parser and Error Handling</a></h1> + +  <p>In this chapter we will discuss the <code>xml_schema::document</code> +     type as well as the error handling mechanisms provided by the mapping +     in more detail. As mentioned in <a href="#3.4">Section 3.4, +     "Connecting the Parsers Together"</a>, the interface of +     <code>xml_schema::document</code> depends on the underlying XML +     parser selected (<a href="#5.3">Section 5.3, "Underlying XML +     Parser"</a>). The following sections describe the +     <code>document</code> type interface for Xerces-C++ and +     Expat as underlying parsers.</p> + +  <h2><a name="7.1">7.1 Xerces-C++ Document Parser</a></h2> + +  <p>When Xerces-C++ is used as the underlying XML parser, the +     <code>document</code> type has the following interface. Note that +     if the character type is <code>wchar_t</code>, then the string type +     in the interface becomes <code>std::wstring</code> +     (see <a href="#5.2">Section 5.2, "Character Type and Encoding"</a>).</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class parser_base; +  class error_handler; + +  class flags +  { +  public: +    // Do not validate XML documents with the Xerces-C++ validator. +    // +    static const unsigned long dont_validate; + +    // Do not initialize the Xerces-C++ runtime. +    // +    static const unsigned long dont_initialize; + +    // Disable handling of subsequent imports for the same namespace +    // in Xerces-C++ 3.1.0 and later. +    // +    static const unsigned long no_multiple_imports; +  }; + +  class properties +  { +  public: +    // Add a location for a schema with a target namespace. +    // +    void +    schema_location (const std::string& namespace_, +                     const std::string& location); + +    // Add a location for a schema without a target namespace. +    // +    void +    no_namespace_schema_location (const std::string& location); +  }; + +  class document +  { +  public: +    document (parser_base& root, +              const std::string& root_element_name, +	      bool polymorphic = false); + +    document (parser_base& root, +              const std::string& root_element_namespace, +              const std::string& root_element_name, +	      bool polymorphic = false); + +  public: +    // Parse URI or a local file. +    // +    void +    parse (const std::string& uri, +           flags = 0, +           const properties& = properties ()); + +    // Parse URI or a local file with a user-provided error_handler +    // object. +    // +    void +    parse (const std::string& uri, +           error_handler&, +           flags = 0, +           const properties& = properties ()); + +    // Parse URI or a local file with a user-provided ErrorHandler +    // object. Note that you must initialize the Xerces-C++ runtime +    // before calling this function. +    // +    void +    parse (const std::string& uri, +           xercesc::ErrorHandler&, +           flags = 0, +           const properties& = properties ()); + +    // Parse URI or a local file using a user-provided SAX2XMLReader +    // object. Note that you must initialize the Xerces-C++ runtime +    // before calling this function. +    // +    void +    parse (const std::string& uri, +           xercesc::SAX2XMLReader&, +           flags = 0, +           const properties& = properties ()); + +  public: +    // Parse std::istream. +    // +    void +    parse (std::istream&, +           flags = 0, +           const properties& = properties ()); + +    // Parse std::istream with a user-provided error_handler object. +    // +    void +    parse (std::istream&, +           error_handler&, +           flags = 0, +           const properties& = properties ()); + +    // Parse std::istream with a user-provided ErrorHandler object. +    // Note that you must initialize the Xerces-C++ runtime before +    // calling this function. +    // +    void +    parse (std::istream&, +           xercesc::ErrorHandler&, +           flags = 0, +           const properties& = properties ()); + +    // Parse std::istream using a user-provided SAX2XMLReader object. +    // Note that you must initialize the Xerces-C++ runtime before +    // calling this function. +    // +    void +    parse (std::istream&, +           xercesc::SAX2XMLReader&, +           flags = 0, +           const properties& = properties ()); + +  public: +    // Parse std::istream with a system id. +    // +    void +    parse (std::istream&, +           const std::string& system_id, +           flags = 0, +           const properties& = properties ()); + +    // Parse std::istream with a system id and a user-provided +    // error_handler object. +    // +    void +    parse (std::istream&, +           const std::string& system_id, +           error_handler&, +           flags = 0, +           const properties& = properties ()); + +    // Parse std::istream with a system id and a user-provided +    // ErrorHandler object. Note that you must initialize the +    // Xerces-C++ runtime before calling this function. +    // +    void +    parse (std::istream&, +           const std::string& system_id, +           xercesc::ErrorHandler&, +           flags = 0, +           const properties& = properties ()); + +    // Parse std::istream with a system id using a user-provided +    // SAX2XMLReader object. Note that you must initialize the +    // Xerces-C++ runtime before calling this function. +    // +    void +    parse (std::istream&, +           const std::string& system_id, +           xercesc::SAX2XMLReader&, +           flags = 0, +           const properties& = properties ()); + +  public: +    // Parse std::istream with system and public ids. +    // +    void +    parse (std::istream&, +           const std::string& system_id, +           const std::string& public_id, +           flags = 0, +           const properties& = properties ()); + +    // Parse std::istream with system and public ids and a user-provided +    // error_handler object. +    // +    void +    parse (std::istream&, +           const std::string& system_id, +           const std::string& public_id, +           error_handler&, +           flags = 0, +           const properties& = properties ()); + +    // Parse std::istream with system and public ids and a user-provided +    // ErrorHandler object. Note that you must initialize the Xerces-C++ +    // runtime before calling this function. +    // +    void +    parse (std::istream&, +           const std::string& system_id, +           const std::string& public_id, +           xercesc::ErrorHandler&, +           flags = 0, +           const properties& = properties ()); + +    // Parse std::istream with system and public ids using a user- +    // provided SAX2XMLReader object. Note that you must initialize +    // the Xerces-C++ runtime before calling this function. +    // +    void +    parse (std::istream&, +           const std::string& system_id, +           const std::string& public_id, +           xercesc::SAX2XMLReader&, +           flags = 0, +           const properties& = properties ()); + +  public: +    // Parse InputSource. Note that you must initialize the Xerces-C++ +    // runtime before calling this function. +    // +    void +    parse (const xercesc::InputSource&, +           flags = 0, +           const properties& = properties ()); + +    // Parse InputSource with a user-provided error_handler object. +    // Note that you must initialize the Xerces-C++ runtime before +    // calling this function. +    // +    void +    parse (const xercesc::InputSource&, +           error_handler&, +           flags = 0, +           const properties& = properties ()); + +    // Parse InputSource with a user-provided ErrorHandler object. +    // Note that you must initialize the Xerces-C++ runtime before +    // calling this function. +    // +    void +    parse (const xercesc::InputSource&, +           xercesc::ErrorHandler&, +           flags = 0, +           const properties& = properties ()); + +    // Parse InputSource using a user-provided SAX2XMLReader object. +    // Note that you must initialize the Xerces-C++ runtime before +    // calling this function. +    // +    void +    parse (const xercesc::InputSource&, +           xercesc::SAX2XMLReader&, +           flags = 0, +           const properties& = properties ()); +  }; +} +  </pre> + +  <p>The <code>document</code> class is a root parser for +     the vocabulary. The first argument to its constructors is the +     parser for the type of the root element. The <code>parser_base</code> +     class is the base type for all parser skeletons. The second and +     third arguments to the <code>document</code>'s constructors are +     the root element's name and namespace. The last argument, +     <code>polymorphic</code>, specifies whether the XML documents +     being parsed use polymorphism. For more information on support +     for XML Schema polymorphism in the C++/Parser mapping refer +     to <a href="#5.5">Section 5.5, "Support for Polymorphism"</a>.</p> + +  <p>The rest of the <code>document</code> interface consists of overloaded +     <code>parse()</code> functions. The last two arguments in each of these +     functions are <code>flags</code> and <code>properties</code>. The +     <code>flags</code> argument allows you to modify the default behavior +     of the parsing functions. The <code>properties</code> argument allows +     you to override the schema location attributes specified in XML +     documents. Note that the schema location paths are relative to an +     XML document unless they are complete URIs. For example if you want +     to use a local schema file then you will need to use a URI in the +     form <code>file:///absolute/path/to/your/schema</code>.</p> + +  <p>A number of overloaded <code>parse()</code> functions have the +     <code>system_id</code> and <code>public_id</code> arguments. The +     system id is a <em>system</em> identifier of the resources being +     parsed (for example, URI or a full file path). The public id is a +     <em>public</em> identifier of the resource (for example, an +     application-specific name or a relative file path). The system id +     is used to resolve relative paths (for example, schema paths). In +     diagnostics messages the public id is used if it is available. +     Otherwise the system id is used.</p> + +  <p>The error handling mechanisms employed by the <code>document</code> +     parser are described in <a href="#7.3">Section 7.3, "Error +     Handling"</a>.</p> + +  <h2><a name="7.2">7.2 Expat Document Parser</a></h2> + +  <p>When Expat is used as the underlying XML parser, the +     <code>document</code> type has the following interface. Note that +     if the character type is <code>wchar_t</code>, then the string type +     in the interface becomes <code>std::wstring</code> +     (see <a href="#5.2">Section 5.2, "Character Type and Encoding"</a>).</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class parser_base; +  class error_handler; + +  class document +  { +  public: +    document (parser_base&, +              const std::string& root_element_name, +              bool polymorphic = false); + +    document (parser_base&, +              const std::string& root_element_namespace, +              const std::string& root_element_name, +              bool polymorphic = false); + +  public: +    // Parse a local file. The file is accessed with std::ifstream +    // in binary mode. The std::ios_base::failure exception is used +    // to report io errors (badbit and failbit). +    void +    parse (const std::string& file); + +    // Parse a local file with a user-provided error_handler +    // object. The file is accessed with std::ifstream in binary +    // mode. The std::ios_base::failure exception is used to report +    // io errors (badbit and failbit). +    // +    void +    parse (const std::string& file, error_handler&); + +  public: +    // Parse std::istream. +    // +    void +    parse (std::istream&); + +    // Parse std::istream with a user-provided error_handler object. +    // +    void +    parse (std::istream&, error_handler&); + +    // Parse std::istream with a system id. +    // +    void +    parse (std::istream&, const std::string& system_id); + +    // Parse std::istream with a system id and a user-provided +    // error_handler object. +    // +    void +    parse (std::istream&, +           const std::string& system_id, +           error_handler&); + +    // Parse std::istream with system and public ids. +    // +    void +    parse (std::istream&, +           const std::string& system_id, +           const std::string& public_id); + +    // Parse std::istream with system and public ids and a user-provided +    // error_handler object. +    // +    void +    parse (std::istream&, +           const std::string& system_id, +           const std::string& public_id, +           error_handler&); + +  public: +    // Parse a chunk of input. You can call these functions multiple +    // times with the last call having the last argument true. +    // +    void +    parse (const void* data, std::size_t size, bool last); + +    void +    parse (const void* data, std::size_t size, bool last, +           error_handler&); + +    void +    parse (const void* data, std::size_t size, bool last, +           const std::string& system_id); + +    void +    parse (const void* data, std::size_t size, bool last, +           const std::string& system_id, +           error_handler&); + +    void +    parse (const void* data, std::size_t size, bool last, +           const std::string& system_id, +           const std::string& public_id); + +    void +    parse (const void* data, std::size_t size, bool last, +           const std::string& system_id, +           const std::string& public_id, +           error_handler&); + +  public: +    // Low-level Expat-specific parsing API. +    // +    void +    parse_begin (XML_Parser); + +    void +    parse_begin (XML_Parser, const std::string& public_id); + +    void +    parse_begin (XML_Parser, error_handler&); + +    void +    parse_begin (XML_Parser, +                 const std::string& public_id, +                 error_handler&); +    void +    parse_end (); +  }; +} +  </pre> + +  <p>The <code>document</code> class is a root parser for +     the vocabulary. The first argument to its constructors is the +     parser for the type of the root element. The <code>parser_base</code> +     class is the base type for all parser skeletons. The second and +     third arguments to the <code>document</code>'s constructors are +     the root element's name and namespace. The last argument, +     <code>polymorphic</code>, specifies whether the XML documents +     being parsed use polymorphism. For more information on support +     for XML Schema polymorphism in the C++/Parser mapping refer +     to <a href="#5.5">Section 5.5, "Support for Polymorphism"</a>.</p> + +  <p>A number of overloaded <code>parse()</code> functions have the +     <code>system_id</code> and <code>public_id</code> arguments. The +     system id is a <em>system</em> identifier of the resources being +     parsed (for example, URI or a full file path). The public id is a +     <em>public</em> identifier of the resource (for example, an +     application-specific name or a relative file path). The system id +     is used to resolve relative paths. In diagnostics messages the +     public id is used if it is available. Otherwise the system id +     is used.</p> + +  <p>The <code>parse_begin()</code> and <code>parse_end()</code> functions +     present a low-level, Expat-specific parsing API for maximum control. +     A typical use-case would look like this (pseudo-code):</p> + +  <pre class="c++"> +xxx_pimpl root_p; +document doc_p (root_p, "root"); + +root_p.pre (); +doc_p.parse_begin (xml_parser, "file.xml"); + +while (more_data_to_parse) +{ +  // Call XML_Parse or XML_ParseBuffer. + +  if (status == XML_STATUS_ERROR) +    break; +} + +// Call parse_end even in case of an error to translate +// XML and Schema errors to exceptions or error_handler +// calls. +// +doc.parse_end (); +result_type result (root_p.post_xxx ()); +  </pre> + +  <p>Note that if your vocabulary uses XML namespaces, the +     <code>XML_ParserCreateNS()</code> functions should be used to create +     the XML parser. Space (<code>XML_Char (' ')</code>) should be used +     as a separator (the second argument to <code>XML_ParserCreateNS()</code>). +  </p> + +  <p>The error handling mechanisms employed by the <code>document</code> +     parser are described in <a href="#7.3">Section 7.3, "Error +     Handling"</a>.</p> + + +  <h2><a name="7.3">7.3 Error Handling</a></h2> + +  <p>There are three categories of errors that can result from running +     a parser on an XML document: System, XML, and Application. +     The System category contains memory allocation and file/stream +     operation errors. The XML category covers XML parsing and +     well-formedness checking as well as XML Schema validation errors. +     Finally, the Application category is for application logic errors +     that you may want to propagate from parser implementations to the +     caller of the parser. +  </p> + +  <p>The System errors are mapped to the standard exceptions. The +     out of memory condition is indicated by throwing an instance +     of <code>std::bad_alloc</code>. The stream operation errors +     are reported either by throwing an instance of +     <code>std::ios_base::failure</code> if exceptions are enabled +     or by setting the stream state.</p> + +  <p>Note that if you are parsing <code>std::istream</code> on +     which exceptions are not enabled, then you will need to +     check the stream state before calling the <code>post()</code> +     callback, as shown in the following example:</p> + +  <pre class="c++"> +int +main (int argc, char* argv[]) +{ +  ... + +  std::ifstream ifs (argv[1]); + +  if (ifs.fail ()) +  { +    cerr << argv[1] << ": unable to open" << endl; +    return 1; +  } + +  root_p.pre (); +  doc_p.parse (ifs); + +  if (ifs.fail ()) +  { +    cerr << argv[1] << ": io failure" << endl; +    return 1; +  } + +  result_type result (root_p.post_xxx ()); +} +  </pre> + +  <p>The above example can be rewritten to use exceptions +     as shown below:</p> + +  <pre class="c++"> +int +main (int argc, char* argv[]) +{ +  try +  { +    ... + +    std::ifstream ifs; +    ifs.exceptions (std::ifstream::badbit | std::ifstream::failbit); +    ifs.open (argv[1]); + +    root_p.pre (); +    doc_p.parse (ifs); +    result_type result (root_p.post_xxx ()); +  } +  catch (const std::ifstream::failure&) +  { +    cerr << argv[1] << ": unable to open or io failure" << endl; +    return 1; +  } +} +  </pre> + + +  <p>For reporting application errors from parsing callbacks, you +     can throw any exceptions of your choice. They are propagated to +     the caller of the parser without any alterations.</p> + +  <p>The XML errors can be reported either by throwing the +     <code>xml_schema::parsing</code> exception or by a callback +     to the <code>xml_schema::error_handler</code> object (and +     <code>xercesc::ErrorHandler</code> object in case of Xerces-C++).</p> + +  <p>The <code>xml_schema::parsing</code> exception contains +     a list of warnings and errors that were accumulated during +     parsing. Note that this exception is thrown only if there +     was an error. This makes it impossible to obtain warnings +     from an otherwise successful parsing using this mechanism. +     The following listing shows the definition of +     <code>xml_schema::parsing</code> exception. Note that if the +     character type is <code>wchar_t</code>, then the string type +     and output stream type in the definition become +     <code>std::wstring</code> and <code>std::wostream</code>, +     respectively (see <a href="#5.2">Section 5.2, "Character Type +     and Encoding"</a>).</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class exception: public std::exception +  { +  protected: +    virtual void +    print (std::ostream&) const = 0; +  }; + +  inline std::ostream& +  operator<< (std::ostream& os, const exception& e) +  { +    e.print (os); +    return os; +  } + + +  class severity +  { +  public: +    enum value +    { +      warning, +      error +    }; +  }; + + +  class error +  { +  public: +    error (xml_schema::severity, +           const std::string& id, +           unsigned long line, +           unsigned long column, +           const std::string& message); + +    xml_schema::severity +    severity () const; + +    const std::string& +    id () const; + +    unsigned long +    line () const; + +    unsigned long +    column () const; + +    const std::string& +    message () const; +  }; + +  std::ostream& +  operator<< (std::ostream&, const error&); + + +  class diagnostics: public std::vector<error> +  { +  }; + +  std::ostream& +  operator<< (std::ostream&, const diagnostics&); + + +  class parsing: public exception +  { +  public: +    parsing (); +    parsing (const xml_schema::diagnostics&); + +    const xml_schema::diagnostics& +    diagnostics () const; + +    virtual const char* +    what () const throw (); + +  protected: +    virtual void +    print (std::ostream&) const; +  }; +} +  </pre> + +  <p>The following example shows how we can catch and print this +     exception. The code will print diagnostics messages one per line +     in case of an error.</p> + +  <pre class="c++"> +int +main (int argc, char* argv[]) +{ +  try +  { +    // Parse. +  } +  catch (const xml_schema::parsing& e) +  { +    cerr << e << endl; +    return 1; +  } +} +  </pre> + +  <p>With the <code>error_handler</code> approach the diagnostics +     messages are delivered as parsing progresses. The following +     listing presents the definition of the <code>error_handler</code> +     interface. Note that if the character type is <code>wchar_t</code>, +     then the string type in the interface becomes <code>std::wstring</code> +     (see <a href="#5.2">Section 5.2, "Character Type and Encoding"</a>).</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class error_handler +  { +  public: +    class severity +    { +    public: +      enum value +      { +        warning, +        error, +        fatal +      }; +    }; + +    virtual bool +    handle (const std::string& id, +            unsigned long line, +            unsigned long column, +            severity, +            const std::string& message) = 0; +  }; +} +  </pre> + +  <p>The return value of the <code>handle()</code> function indicates whether +     parsing should continue if possible. The error with the fatal severity +     level terminates the parsing process regardless of the returned value. +     At the end of the parsing process with an error that was reported via +     the  <code>error_handler</code> object, an empty +     <code>xml_schema::parsing</code> exception is thrown to indicate +     the failure to the caller. You can alter this behavior by throwing +     your own exception from the <code>handle()</code> function.</p> + + +  <!-- Appendix A --> + + +  <h1><a name="A">Appendix A — Supported XML Schema Constructs</a></h1> + +  <p>The C++/Parser mapping supports validation of the following W3C XML +     Schema constructs in the generated code.</p> + +  <!-- border="1" is necessary for html2ps --> +  <table id="features" border="1"> +    <tr><th>Construct</th><th>Notes</th></tr> +    <tr><th colspan="2">Structure</th></tr> + +    <tr><td>element</td><td></td></tr> +    <tr><td>attribute</td><td></td></tr> + +    <tr><td>any</td><td></td></tr> +    <tr><td>anyAttribute</td><td></td></tr> + +    <tr><td>all</td><td></td></tr> +    <tr><td>sequence</td><td></td></tr> +    <tr><td>choice</td><td></td></tr> + +    <tr><td>complex type, empty content</td><td></td></tr> +    <tr><td>complex type, mixed content</td><td></td></tr> +    <tr><td>complex type, simple content extension</td><td></td></tr> +    <tr><td>complex type, simple content restriction</td> +        <td>Simple type facets are not validated.</td></tr> +    <tr><td>complex type, complex content extension</td><td></td></tr> +    <tr><td>complex type, complex content restriction</td><td></td></tr> + +    <tr><td>list</td><td></td></tr> + +    <tr><th colspan="2">Datatypes</th></tr> + +    <tr><td>byte</td><td></td></tr> +    <tr><td>unsignedByte</td><td></td></tr> +    <tr><td>short</td><td></td></tr> +    <tr><td>unsignedShort</td><td></td></tr> +    <tr><td>int</td><td></td></tr> +    <tr><td>unsignedInt</td><td></td></tr> +    <tr><td>long</td><td></td></tr> +    <tr><td>unsignedLong</td><td></td></tr> +    <tr><td>integer</td><td></td></tr> +    <tr><td>nonPositiveInteger</td><td></td></tr> +    <tr><td>nonNegativeInteger</td><td></td></tr> +    <tr><td>positiveInteger</td><td></td></tr> +    <tr><td>negativeInteger</td><td></td></tr> + +    <tr><td>boolean</td><td></td></tr> + +    <tr><td>float</td><td></td></tr> +    <tr><td>double</td><td></td></tr> +    <tr><td>decimal</td><td></td></tr> + +    <tr><td>string</td><td></td></tr> +    <tr><td>normalizedString</td><td></td></tr> +    <tr><td>token</td><td></td></tr> +    <tr><td>Name</td><td></td></tr> +    <tr><td>NMTOKEN</td><td></td></tr> +    <tr><td>NCName</td><td></td></tr> +    <tr><td>language</td><td></td></tr> +    <tr><td>anyURI</td><td></td></tr> + +    <tr><td>ID</td><td>Identity constraint is not enforced.</td></tr> +    <tr><td>IDREF</td><td>Identity constraint is not enforced.</td></tr> + +    <tr><td>NMTOKENS</td><td></td></tr> +    <tr><td>IDREFS</td><td>Identity constraint is not enforced.</td></tr> + +    <tr><td>QName</td><td></td></tr> + +    <tr><td>base64Binary</td><td></td></tr> +    <tr><td>hexBinary</td><td></td></tr> + +    <tr><td>date</td><td></td></tr> +    <tr><td>dateTime</td><td></td></tr> +    <tr><td>duration</td><td></td></tr> +    <tr><td>gDay</td><td></td></tr> +    <tr><td>gMonth</td><td></td></tr> +    <tr><td>gMonthDay</td><td></td></tr> +    <tr><td>gYear</td><td></td></tr> +    <tr><td>gYearMonth</td><td></td></tr> +    <tr><td>time</td><td></td></tr> +  </table> + + +  </div> +</div> + +</body> +</html> diff --git a/doc/cxx/tree/guide/guide.html2ps.in b/doc/cxx/tree/guide/guide.html2ps.in new file mode 100644 index 0000000..461ffde --- /dev/null +++ b/doc/cxx/tree/guide/guide.html2ps.in @@ -0,0 +1,65 @@ +@@html2ps { +  option { +    toc: hb; +    colour: 1; +    hyphenate: 1; +    titlepage: 1; +  } + +  datefmt: "%B %Y"; + +  titlepage { +    content: " +<div align=center> +  <h1><big>C++/Tree Mapping</big></h1> +  <h1><big>Getting Started Guide</big></h1> +  <h1> </h1> +  <h1> </h1> +  <h1> </h1> +  <h1> </h1> +  <h1> </h1> +  <h1> </h1> +</div> +  <p>Copyright © @copyright@.</p> + +  <p>Permission is granted to copy, distribute and/or modify this +     document under the terms of the +     <a href='https://www.codesynthesis.com/licenses/fdl-1.2.txt'>GNU Free +     Documentation License, version 1.2</a>; with no Invariant Sections, +     no Front-Cover Texts and no Back-Cover Texts. +  </p> + +  <p>This document is available in the following formats: +     <a href='https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/guide/index.xhtml'>XHTML</a>, +     <a href='https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/guide/cxx-parser-guide.pdf'>PDF</a>, and +     <a href='https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/guide/cxx-parser-guide.ps'>PostScript</a>.</p>"; +  } + +  toc { +    indent: 2em; +  } + +  header { +    odd-right: $H; +    even-left: $H; +  } + +  footer { +    odd-left: $D; +    odd-center: $T; +    odd-right: $N; + +    even-left: $N; +    even-center: $T; +    even-right: $D; +  } +} + +body { +  font-size: 12pt; +  text-align: justify; +} + +pre { +  font-size: 10pt; +} diff --git a/doc/cxx/tree/guide/index.xhtml b/doc/cxx/tree/guide/index.xhtml new file mode 100644 index 0000000..fdaaa45 --- /dev/null +++ b/doc/cxx/tree/guide/index.xhtml @@ -0,0 +1,2736 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> + +<head> +  <title>C++/Tree Mapping Getting Started Guide</title> + +  <meta name="copyright" content="© 2005-2023 Code Synthesis"/> +  <meta name="keywords" content="xsd,xml,schema,c++,mapping,data,binding,parsing,serialization,validation"/> +  <meta name="description" content="C++/Tree Mapping Getting Started Guide"/> + +  <link rel="stylesheet" type="text/css" href="../../../default.css" /> + +<style type="text/css"> +  pre { +    padding    : 0 0 0 0em; +    margin     : 0em 0em 0em 0; + +    font-size  : 102% +  } + +  body { +    min-width: 48em; +  } + +  h1 { +    font-weight: bold; +    font-size: 200%; +    line-height: 1.2em; +  } + +  h2 { +    font-weight : bold; +    font-size   : 150%; + +    padding-top : 0.8em; +  } + +  h3 { +    font-size   : 140%; +    padding-top : 0.8em; +  } + +  /* Adjust indentation for three levels. */ +  #container { +    max-width: 48em; +  } + +  #content { +    padding: 0 0.1em 0 4em; +    /*background-color: red;*/ +  } + +  #content h1 { +    margin-left: -2.06em; +  } + +  #content h2 { +    margin-left: -1.33em; +  } + +  /* Title page */ + +  #titlepage { +    padding: 2em 0 1em 0; +    border-bottom: 1px solid black; +  } + +  #titlepage .title { +    font-weight: bold; +    font-size: 200%; +    text-align: center; +  } + +  #titlepage #first-title { +    padding: 1em 0 0.4em 0; +  } + +  #titlepage #second-title { +    padding: 0.4em 0 2em 0; +  } + +  /* Lists */ +  ul.list li { +    padding-top      : 0.3em; +    padding-bottom   : 0.3em; +  } + +  div.img { +    text-align: center; +    padding: 2em 0 2em 0; +  } + +  /*  */ +  dl dt { +    padding   : 0.8em 0 0 0; +  } + +  /* Built-in table */ +  #builtin { +    margin: 2em 0 2em 0; + +    border-collapse   : collapse; +    border            : 1px solid; +    border-color      : #000000; + +    font-size        : 11px; +    line-height      : 14px; +  } + +  #builtin th, #builtin td { +    border: 1px solid; +    padding           : 0.9em 0.9em 0.7em 0.9em; +  } + +  #builtin th { +    background : #cde8f6; +  } + +  #builtin td { +    text-align: left; +  } + +  /* TOC */ +  table.toc { +    border-style      : none; +    border-collapse   : separate; +    border-spacing    : 0; + +    margin            : 0.2em 0 0.2em 0; +    padding           : 0 0 0 0; +  } + +  table.toc tr { +    padding           : 0 0 0 0; +    margin            : 0 0 0 0; +  } + +  table.toc * td, table.toc * th { +    border-style      : none; +    margin            : 0 0 0 0; +    vertical-align    : top; +  } + +  table.toc * th { +    font-weight       : normal; +    padding           : 0em 0.1em 0em 0; +    text-align        : left; +    white-space       : nowrap; +  } + +  table.toc * table.toc th { +    padding-left      : 1em; +  } + +  table.toc * td { +    padding           : 0em 0 0em 0.7em; +    text-align        : left; +  } +</style> + + +</head> + +<body> +<div id="container"> +  <div id="content"> + +  <div class="noprint"> + +  <div id="titlepage"> +    <div class="title" id="first-title">C++/Tree Mapping</div> +    <div class="title" id="second-title">Getting Started Guide</div> + +  <p>Copyright © 2005-2023 Code Synthesis.</p> + +  <p>Permission is granted to copy, distribute and/or modify this +     document under the terms of the +     <a href="https://www.codesynthesis.com/licenses/fdl-1.2.txt">GNU Free +     Documentation License, version 1.2</a>; with no Invariant Sections, +     no Front-Cover Texts and no Back-Cover Texts. +  </p> + +  <p>This document is available in the following formats: +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/guide/index.xhtml">XHTML</a>, +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/guide/cxx-tree-guide.pdf">PDF</a>, and +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/guide/cxx-tree-guide.ps">PostScript</a>.</p> + +  </div> + +  <h1>Table of Contents</h1> + +  <table class="toc"> +    <tr> +      <th></th><td><a href="#0">Preface</a> +        <table class="toc"> +          <tr><th></th><td><a href="#0.1">About This Document</a></td></tr> +          <tr><th></th><td><a href="#0.2">More Information</a></td></tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>1</th><td><a href="#1">Introduction</a> +        <table class="toc"> +          <tr><th>1.1</th><td><a href="#1.1">Mapping Overview</a></td></tr> +          <tr><th>1.2</th><td><a href="#1.2">Benefits</a></td></tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>2</th><td><a href="#2">Hello World Example</a> +        <table class="toc"> +          <tr><th>2.1</th><td><a href="#2.1">Writing XML Document and Schema</a></td></tr> +          <tr><th>2.2</th><td><a href="#2.2">Translating Schema to C++</a></td></tr> +          <tr><th>2.3</th><td><a href="#2.3">Implementing Application Logic</a></td></tr> +          <tr><th>2.4</th><td><a href="#2.4">Compiling and Running</a></td></tr> +	  <tr><th>2.5</th><td><a href="#2.5">Adding Serialization</a></td></tr> +	  <tr><th>2.6</th><td><a href="#2.6">Selecting Naming Convention</a></td></tr> +	  <tr><th>2.7</th><td><a href="#2.7">Generating Documentation</a></td></tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>3</th><td><a href="#3">Overall Mapping Configuration</a> +        <table class="toc"> +	  <tr><th>3.1</th><td><a href="#3.1">C++ Standard</a></td></tr> +          <tr><th>3.2</th><td><a href="#3.2">Character Type and Encoding</a></td></tr> +          <tr><th>3.3</th><td><a href="#3.3">Support for Polymorphism </a></td></tr> +          <tr><th>3.4</th><td><a href="#3.4">Namespace Mapping</a></td></tr> +          <tr><th>3.5</th><td><a href="#3.5">Thread Safety</a></td></tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>4</th><td><a href="#4">Working with Object Models</a> +        <table class="toc"> +          <tr><th>4.1</th><td><a href="#4.1">Attribute and Element Cardinalities</a></td></tr> +          <tr><th>4.2</th><td><a href="#4.2">Accessing the Object Model</a></td></tr> +          <tr><th>4.3</th><td><a href="#4.3">Modifying the Object Model</a></td></tr> +          <tr><th>4.4</th><td><a href="#4.4">Creating the Object Model from Scratch</a></td></tr> +	  <tr><th>4.5</th><td><a href="#4.5">Mapping for the Built-in XML Schema Types</a></td></tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>5</th><td><a href="#5">Parsing</a> +        <table class="toc"> +          <tr><th>5.1</th><td><a href="#5.1">XML Schema Validation and Searching</a></td></tr> +          <tr><th>5.2</th><td><a href="#5.2">Error Handling</a></td></tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>6</th><td><a href="#6">Serialization</a> +        <table class="toc"> +          <tr><th>6.1</th><td><a href="#6.1">Namespace and Schema Information</a></td></tr> +          <tr><th>6.2</th><td><a href="#6.2">Error Handling</a></td></tr> +        </table> +      </td> +    </tr> + +  </table> +  </div> + +  <h1><a name="0">Preface</a></h1> + +  <h2><a name="0.1">About This Document</a></h2> + +  <p>The goal of this document is to provide you with an understanding of +     the C++/Tree programming model and allow you to efficiently evaluate +     XSD against your project's technical requirements. As such, this +     document is intended for C++ developers and software architects +     who are looking for an XML processing solution. For a more in-depth +     description of the C++/Tree mapping refer to the +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/">C++/Tree +     Mapping User Manual</a>.</p> + +  <p>Prior experience with XML and C++ is required to understand this +     document. Basic understanding of XML Schema is advantageous but +     not expected or required. +  </p> + + +  <h2><a name="0.2">More Information</a></h2> + +  <p>Beyond this guide, you may also find the following sources of +     information useful:</p> + +  <ul class="list"> +    <li><a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/">C++/Tree +        Mapping User Manual</a></li> + +    <li><a href="http://wiki.codesynthesis.com/Tree/Customization_guide">C++/Tree +        Mapping Customization Guide</a></li> + +    <li><a href="http://wiki.codesynthesis.com/Tree/FAQ">C++/Tree +        Mapping Frequently Asked Questions (FAQ)</a></li> + +    <li><a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD +        Compiler Command Line Manual</a></li> + +    <li>The <code>cxx/tree/</code> directory in the +        <a href="https://cppget.org/xsd-examples">xsd-examples</a> package +        contains a collection of examples and a README file with an overview +        of each example.</li> + +    <li>The <code>README</code> file in the +        <a href="https://cppget.org/xsd-examples">xsd-examples</a> package +        explains how to build the examples.</li> + +    <li>The <a href="https://www.codesynthesis.com/mailman/listinfo/xsd-users">xsd-users</a> +        mailing list is the place to ask technical questions about XSD and the C++/Parser mapping. +        Furthermore, the <a href="https://www.codesynthesis.com/pipermail/xsd-users/">archives</a> +        may already have answers to some of your questions.</li> +  </ul> + +  <!-- Introduction --> + +  <h1><a name="1">1 Introduction</a></h1> + +  <p>Welcome to CodeSynthesis XSD and the C++/Tree mapping. XSD is a +     cross-platform W3C XML Schema to C++ data binding compiler. C++/Tree +     is a W3C XML Schema to C++ mapping that represents the data stored +     in XML as a statically-typed, vocabulary-specific object model. +  </p> + +  <h2><a name="1.1">1.1 Mapping Overview</a></h2> + +  <p>Based on a formal description of an XML vocabulary (schema), the +     C++/Tree mapping produces a tree-like data structure suitable for +     in-memory processing. The core of the mapping consists of C++ +     classes that constitute the object model and are derived from +     types defined in XML Schema as well as XML parsing and +     serialization code.</p> + +  <p>Besides the core features, C++/Tree provide a number of additional +     mapping elements that can be useful in some applications. These +     include serialization and extraction to/from formats others than +     XML, such as unstructured text (useful for debugging) and binary +     representations such as XDR and CDR for high-speed data processing +     as well as automatic documentation generation. The C++/Tree mapping +     also provides a wide range of mechanisms for controlling and +     customizing the generated code.</p> + +  <p>A typical application that uses C++/Tree for XML processing usually +     performs the following three steps: it first reads (parses) an XML +     document to an in-memory object model, it then performs some useful +     computations on that object model which may involve modification +     of the model, and finally it may write (serialize) the modified +     object model back to XML.</p> + +  <p>The next chapter presents a simple application that performs these +     three steps. The following chapters show how to use the C++/Tree +     mapping in more detail.</p> + +  <h2><a name="1.2">1.2 Benefits</a></h2> + +  <p>Traditional XML access APIs such as Document Object Model (DOM) +     or Simple API for XML (SAX) have a number of drawbacks that +     make them less suitable for creating robust and maintainable +     XML processing applications. These drawbacks include: +  </p> + +  <ul class="list"> +    <li>Generic representation of XML in terms of elements, attributes, +        and text forces an application developer to write a substantial +        amount of bridging code that identifies and transforms pieces +        of information encoded in XML to a representation more suitable +        for consumption by the application logic.</li> + +    <li>String-based flow control defers error detection to runtime. +        It also reduces code readability and maintainability.</li> + +    <li>Lack of type safety because the data is represented as text.</li> + +    <li>Resulting applications are hard to debug, change, and +        maintain.</li> +  </ul> + +  <p>In contrast, statically-typed, vocabulary-specific object model +     produced by the C++/Tree mapping allows you to operate in your +     domain terms instead of the generic elements, attributes, and +     text. Static typing helps catch errors at compile-time rather +     than at run-time. Automatic code generation frees you for more +     interesting tasks (such as doing something useful with the +     information stored in the XML documents) and minimizes the +     effort needed to adapt your applications to changes in the +     document structure. To summarize, the C++/Tree object model has +     the following key advantages over generic XML access APIs:</p> + +  <ul class="list"> +    <li><b>Ease of use.</b> The generated code hides all the complexity +        associated with parsing and serializing XML. This includes navigating +        the structure and converting between the text representation and +        data types suitable for manipulation by the application +        logic.</li> + +    <li><b>Natural representation.</b> The object representation allows +         you to access the XML data using your domain vocabulary instead +         of generic elements, attributes, and text.</li> + +    <li><b>Concise code.</b> With the object representation the +        application implementation is simpler and thus easier +        to read and understand.</li> + +    <li><b>Safety.</b> The generated object model is statically +        typed and uses functions instead of strings to access the +        information. This helps catch programming errors at compile-time +        rather than at runtime.</li> + +    <li><b>Maintainability.</b> Automatic code generation minimizes the +        effort needed to adapt the application to changes in the +        document structure. With static typing, the C++ compiler +        can pin-point the places in the client code that need to be +        changed.</li> + +    <li><b>Compatibility.</b> Sequences of elements are represented in +        the object model as containers conforming to the standard C++ +        sequence requirements. This makes it possible to use standard +        C++ algorithms on the object representation and frees you from +        learning yet another container interface, as is the case with +        DOM.</li> + +    <li><b>Efficiency.</b> If the application makes repetitive use +        of the data extracted from XML, then the C++/Tree object model +        is more efficient because the navigation is performed using +        function calls rather than string comparisons and the XML +        data is extracted only once. Furthermore, the runtime memory +        usage is reduced due to more efficient data storage +        (for instance, storing numeric data as integers instead of +        strings) as well as the static knowledge of cardinality +        constraints.</li> +  </ul> + + +  <!-- Hello World Parser --> + + +  <h1><a name="2">2 Hello World Example</a></h1> + +  <p>In this chapter we will examine how to parse, access, modify, and +     serialize a very simple XML document using the XSD-generated +     C++/Tree object model. The code presented in this chapter is +     based on the <code>hello</code> example which can be found in +     the <code>cxx/tree/</code> directory in the +     <a href="https://cppget.org/xsd-examples">xsd-examples</a> package.</p> + +  <h2><a name="2.1">2.1 Writing XML Document and Schema</a></h2> + +  <p>First, we need to get an idea about the structure +     of the XML documents we are going to process. Our +     <code>hello.xml</code>, for example, could look like this:</p> + +  <pre class="xml"> +<?xml version="1.0"?> +<hello> + +  <greeting>Hello</greeting> + +  <name>sun</name> +  <name>moon</name> +  <name>world</name> + +</hello> +  </pre> + +  <p>Then we can write a description of the above XML in the +     XML Schema language and save it into <code>hello.xsd</code>:</p> + +  <pre class="xml"> +<?xml version="1.0"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + +  <xs:complexType name="hello_t"> +    <xs:sequence> +      <xs:element name="greeting" type="xs:string"/> +      <xs:element name="name" type="xs:string" maxOccurs="unbounded"/> +    </xs:sequence> +  </xs:complexType> + +  <xs:element name="hello" type="hello_t"/> + +</xs:schema> +  </pre> + +  <p>Even if you are not familiar with XML Schema, it +     should be easy to connect declarations in <code>hello.xsd</code> +     to elements in <code>hello.xml</code>. The <code>hello_t</code> type +     is defined as a sequence of the nested <code>greeting</code> and +     <code>name</code> elements. Note that the term sequence in XML +     Schema means that elements should appear in a particular order +     as opposed to appearing multiple times. The <code>name</code> +     element has its <code>maxOccurs</code> property set to +     <code>unbounded</code> which means it can appear multiple times +     in an XML document. Finally, the globally-defined <code>hello</code> +     element prescribes the root element for our vocabulary. For an +     easily-approachable introduction to XML Schema refer to +     <a href="http://www.w3.org/TR/xmlschema-0/">XML Schema Part 0: +     Primer</a>.</p> + +  <p>The above schema is a specification of our XML vocabulary; it tells +     everybody what valid documents of our XML-based language should look +     like. We can also update our <code>hello.xml</code> to include the +     information about the schema so that XML parsers can validate +     our document:</p> + +      <pre class="xml"> +<?xml version="1.0"?> +<hello xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +       xsi:noNamespaceSchemaLocation="hello.xsd"> + +  <greeting>Hello</greeting> + +  <name>sun</name> +  <name>moon</name> +  <name>world</name> + +</hello> +      </pre> + + +  <p>The next step is to compile the schema to generate the object +     model and parsing functions.</p> + +  <h2><a name="2.2">2.2 Translating Schema to C++</a></h2> + +  <p>Now we are ready to translate our <code>hello.xsd</code> to C++. +     To do this we invoke the XSD compiler from a terminal (UNIX) or +     a command prompt (Windows): +  </p> + +  <pre class="terminal"> +$ xsd cxx-tree hello.xsd +  </pre> + +  <p>The XSD compiler produces two C++ files: <code>hello.hxx</code> and +     <code>hello.cxx</code>. The following code fragment is taken from +     <code>hello.hxx</code>; it should give you an idea about what gets +     generated: +  </p> + +  <pre class="c++"> +class hello_t +{ +public: +  // greeting +  // +  typedef xml_schema::string greeting_type; + +  const greeting_type& +  greeting () const; + +  greeting_type& +  greeting (); + +  void +  greeting (const greeting_type& x); + +  // name +  // +  typedef xml_schema::string name_type; +  typedef xsd::sequence<name_type> name_sequence; +  typedef name_sequence::iterator name_iterator; +  typedef name_sequence::const_iterator name_const_iterator; + +  const name_sequence& +  name () const; + +  name_sequence& +  name (); + +  void +  name (const name_sequence& s); + +  // Constructor. +  // +  hello_t (const greeting_type&); + +  ... + +}; + +std::unique_ptr<hello_t> +hello (const std::string& uri); + +std::unique_ptr<hello_t> +hello (std::istream&); +  </pre> + +  <p>The <code>hello_t</code> C++ class corresponds to the +     <code>hello_t</code> XML Schema type. For each element +     in this type a set of C++ type definitions as well as +     accessor and modifier functions are generated inside the +     <code>hello_t</code> class. Note that the type definitions +     and member functions for the <code>greeting</code> and +     <code>name</code> elements are different because of the +     cardinality differences between these two elements +     (<code>greeting</code> is a required single element and +     <code>name</code> is a sequence of elements).</p> + +  <p>The <code>xml_schema::string</code> type used in the type +     definitions is a C++ class provided by the XSD runtime +     that corresponds to built-in XML Schema type +     <code>string</code>. The <code>xml_schema::string</code> +     is based on <code>std::string</code> and can be used as +     such. Similarly, the <code>sequence</code> class template +     that is used in the <code>name_sequence</code> type +     definition is based on and has the same interface as +     <code>std::vector</code>. The mapping between the built-in +     XML Schema types and C++ types is described in more detail in +     <a href="#4.5">Section 4.5, "Mapping for the Built-in XML Schema +     Types"</a>. The <code>hello_t</code> class also includes a +     constructor with an initializer for the required +     <code>greeting</code> element as its argument.</p> + +  <p>The <code>hello</code> overloaded global functions correspond +     to the <code>hello</code> global element in XML Schema. A +     global element in XML Schema is a valid document root. +     By default XSD generated a set of parsing functions for each +     global element defined in XML Schema (this can be overridden +     with the <code>--root-element-*</code> options). Parsing +     functions return a dynamically allocated object model as an +     automatic pointer. The actual pointer used depends on the +     C++ standard selected. For C++11 it is <code>std::unique_ptr</code> +     as shown above. For C++98 it is <code>std::auto_ptr</code>. +     For example, if we modify our XSD compiler invocation to +     select C++98:</p> + +  <pre class="terminal"> +$ xsd cxx-tree --std c++98 hello.xsd +  </pre> + +  <p>Then the parsing function signatures will become:</p> + +  <pre class="c++"> +std::auto_ptr<hello_t> +hello (const std::string& uri); + +std::auto_ptr<hello_t> +hello (std::istream&); +  </pre> + +  <p>For more information on parsing functions see <a href="#5">Chapter 5, +     "Parsing"</a>.</p> + +  <h2><a name="2.3">2.3 Implementing Application Logic</a></h2> + +  <p>At this point we have all the parts we need to do something useful +     with the information stored in our XML document: +  </p> + +  <pre class="c++"> +#include <iostream> +#include "hello.hxx" + +using namespace std; + +int +main (int argc, char* argv[]) +{ +  try +  { +    unique_ptr<hello_t> h (hello (argv[1])); + +    for (hello_t::name_const_iterator i (h->name ().begin ()); +         i != h->name ().end (); +         ++i) +    { +      cerr << h->greeting () << ", " << *i << "!" << endl; +    } +  } +  catch (const xml_schema::exception& e) +  { +    cerr << e << endl; +    return 1; +  } +} +  </pre> + +  <p>The first part of our application calls one of the parsing +     functions to parser an XML file specified in the command line. +     We then use the returned object model to iterate over names +     and print a greeting line for each of them. Finally, we +     catch and print the <code>xml_schema::exception</code> +     exception in case something goes wrong. This exception +     is the root of the exception hierarchy used by the +     XSD-generated code. +  </p> + + +  <h2><a name="2.4">2.4 Compiling and Running</a></h2> + +  <p>After saving our application from the previous section in +     <code>driver.cxx</code>, we are ready to compile our first +     program and run it on the test XML document. On a UNIX +     system this can be done with the following commands: +  </p> + +  <pre class="terminal"> +$ c++ -std=c++11 -I.../libxsd -c driver.cxx hello.cxx +$ c++ -std=c++11 -o driver driver.o hello.o -lxerces-c +$ ./driver hello.xml +Hello, sun! +Hello, moon! +Hello, world! +  </pre> + +  <p>Here <code>.../libxsd</code> represents the path to the +     <a href="https://cppget.org/libxsd">libxsd</a> package root +     directory. Note also that we are required to link our +     application with the Xerces-C++ library because the generated +     code uses it as the underlying XML parser.</p> + +  <h2><a name="2.5">2.5 Adding Serialization</a></h2> + +  <p>While parsing and accessing the XML data may be everything +     you need, there are applications that require creating new +     or modifying existing XML documents. By default XSD does +     not produce serialization code. We will need to request +     it with the <code>--generate-serialization</code> options:</p> + +  <pre class="terminal"> +$ xsd cxx-tree --generate-serialization hello.xsd +  </pre> + +  <p>If we now examine the generated <code>hello.hxx</code> file, +     we will find a set of overloaded serialization functions, +     including the following version:</p> + +  <pre class="c++"> +void +hello (std::ostream&, +       const hello_t&, +       const xml_schema::namespace_infomap& = +         xml_schema::namespace_infomap ()); + +  </pre> + +  <p>Just like with parsing functions, XSD generates serialization +     functions for each global element unless instructed otherwise +     with one of the <code>--root-element-*</code> options. For more +     information on serialization functions see <a href="#6">Chapter 6, +     "Serialization"</a>.</p> + +  <p>We first examine an application that modifies an existing +     object model and serializes it back to XML:</p> + +  <pre class="c++"> +#include <iostream> +#include "hello.hxx" + +using namespace std; + +int +main (int argc, char* argv[]) +{ +  try +  { +    unique_ptr<hello_t> h (hello (argv[1])); + +    // Change the greeting phrase. +    // +    h->greeting ("Hi"); + +    // Add another entry to the name sequence. +    // +    h->name ().push_back ("mars"); + +    // Serialize the modified object model to XML. +    // +    xml_schema::namespace_infomap map; +    map[""].name = ""; +    map[""].schema = "hello.xsd"; + +    hello (cout, *h, map); +  } +  catch (const xml_schema::exception& e) +  { +    cerr << e << endl; +    return 1; +  } +} +  </pre> + +  <p>First, our application parses an XML document and obtains its +     object model as in the previous example. Then it changes the +     greeting string and adds another entry to the list of names. +     Finally, it serializes the object model back to XML by calling +     the serialization function.</p> + +  <p>The first argument we pass to the serialization function is +     <code>cout</code> which results in the XML being written to +     the standard output for us to inspect. We could have also +     written the result to a file or memory buffer by creating an +     instance of <code>std::ofstream</code> or <code>std::ostringstream</code> +     and passing it instead of <code>cout</code>. The second argument is the +     object model we want to serialize. The final argument is an optional +     namespace information map for our vocabulary. It captures information +     such as namespaces, namespace prefixes to which they should be mapped, +     and schemas associated with these namespaces. If we don't provide +     this argument then generic namespace prefixes (<code>p1</code>, +     <code>p2</code>, etc.) will be automatically assigned to XML namespaces +     and no schema information will be added to the resulting document +     (see <a href="#6">Chapter 6, "Serialization"</a> for details). +     In our case, the prefix (map key) and namespace name are empty +     because our vocabulary does not use XML namespaces.</p> + +  <p>If we now compile and run this application we will see the +     output as shown in the following listing:</p> + +  <pre class="xml"> +<?xml version="1.0"?> +<hello xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +       xsi:noNamespaceSchemaLocation="hello.xsd"> + +  <greeting>Hi</greeting> + +  <name>sun</name> +  <name>moon</name> +  <name>world</name> +  <name>mars</name> + +</hello> +  </pre> + +  <p>We can also create and serialize an object model from scratch +     as shown in the following example:</p> + +  <pre class="c++"> +#include <iostream> +#include <fstream> +#include "hello.hxx" + +using namespace std; + +int +main (int argc, char* argv[]) +{ +  try +  { +    hello_t h ("Hi"); + +    hello_t::name_sequence& ns (h.name ()); + +    ns.push_back ("Jane"); +    ns.push_back ("John"); + +    // Serialize the object model to XML. +    // +    xml_schema::namespace_infomap map; +    map[""].name = ""; +    map[""].schema = "hello.xsd"; + +    std::ofstream ofs (argv[1]); +    hello (ofs, h, map); +  } +  catch (const xml_schema::exception& e) +  { +    cerr << e << endl; +    return 1; +  } +} +  </pre> + +  <p>In this example we used the generated constructor to create +     an instance of type <code>hello_t</code>. To reduce typing, +     we obtained a reference to the name sequence which we then +     used to add a few names. The serialization part is identical +     to the previous example except this time we are writing to +     a file. If we compile and run this program, it produces the +     following XML file:</p> + +  <pre class="xml"> +<?xml version="1.0"?> +<hello xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +       xsi:noNamespaceSchemaLocation="hello.xsd"> + +  <greeting>Hi</greeting> + +  <name>Jane</name> +  <name>John</name> + +</hello> +  </pre> + +  <h2><a name="2.6">2.6 Selecting Naming Convention</a></h2> + +  <p>By default XSD uses the so-called K&R (Kernighan and Ritchie) +     identifier naming convention in the generated code. In this +     convention both type and function names are in lower case and +     words are separated by underscores. If your application code or +     schemas use a different notation, you may want to change the +     naming convention used in the generated code for consistency. +     XSD supports a set of widely-used naming conventions +     that you can select with the <code>--type-naming</code> and +     <code>--function-naming</code> options. You can also further +     refine one of the predefined conventions or create a completely +     custom naming scheme by using the  <code>--*-regex</code> options.</p> + +  <p>As an example, let's assume that our "Hello World" application +     uses the so-called upper-camel-case naming convention for types +     (that is, each word in a type name is capitalized) and the K&R +     convention for function names. Since K&R is the default +     convention for both type and function names, we only need to +     change the type naming scheme:</p> + +  <pre class="terminal"> +$ xsd cxx-tree --type-naming ucc hello.xsd +  </pre> + +  <p>The <code>ucc</code> argument to the <code>--type-naming</code> +     options stands for upper-camel-case. If we now examine the +     generated <code>hello.hxx</code>, we will see the following +     changes compared to the declarations shown in the previous +     sections:</p> + +  <pre class="c++"> +class Hello_t +{ +public: +  // greeting +  // +  typedef xml_schema::String GreetingType; + +  const GreetingType& +  greeting () const; + +  GreetingType& +  greeting (); + +  void +  greeting (const GreetingType& x); + +  // name +  // +  typedef xml_schema::String NameType; +  typedef xsd::sequence<NameType> NameSequence; +  typedef NameSequence::iterator NameIterator; +  typedef NameSequence::const_iterator NameConstIterator; + +  const NameSequence& +  name () const; + +  NameSequence& +  name (); + +  void +  name (const NameSequence& s); + +  // Constructor. +  // +  Hello_t (const GreetingType&); + +  ... + +}; + +std::unique_ptr<Hello_t> +hello (const std::string& uri); + +std::unique_ptr<Hello_t> +hello (std::istream&); +  </pre> + +  <p>Notice that the type names in the <code>xml_schema</code> namespace, +     for example <code>xml_schema::String</code>, now also use the +     upper-camel-case naming convention. The only thing that we may +     be unhappy about in the above code is the <code>_t</code> +     suffix in <code>Hello_t</code>. If we are not in a position +     to change the schema, we can <em>touch-up</em> the <code>ucc</code> +     convention with a custom translation rule using the +     <code>--type-regex</code> option:</p> + +  <pre class="terminal"> +$ xsd cxx-tree --type-naming ucc --type-regex '/ (.+)_t/\u$1/' hello.xsd +  </pre> + +  <p>This results in the following changes to the generated code:</p> + +  <pre class="c++"> +class Hello +{ +public: +  // greeting +  // +  typedef xml_schema::String GreetingType; + +  const GreetingType& +  greeting () const; + +  GreetingType& +  greeting (); + +  void +  greeting (const GreetingType& x); + +  // name +  // +  typedef xml_schema::String NameType; +  typedef xsd::sequence<NameType> NameSequence; +  typedef NameSequence::iterator NameIterator; +  typedef NameSequence::const_iterator NameConstIterator; + +  const NameSequence& +  name () const; + +  NameSequence& +  name (); + +  void +  name (const NameSequence& s); + +  // Constructor. +  // +  Hello (const GreetingType&); + +  ... + +}; + +std::unique_ptr<Hello> +hello (const std::string& uri); + +std::unique_ptr<Hello> +hello (std::istream&); +  </pre> + +  <p>For more detailed information on the <code>--type-naming</code>, +     <code>--function-naming</code>, <code>--type-regex</code>, and +     other <code>--*-regex</code> options refer to the NAMING +     CONVENTION section in the <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD +     Compiler Command Line Manual</a>.</p> + +  <h2><a name="2.7">2.7 Generating Documentation</a></h2> + +  <p>While our object model is quite simple, real-world vocabularies +     can be quite complex with hundreds of types, elements, and +     attributes. For such vocabularies figuring out which types +     provide which member functions by studying the generated +     source code or schemas can be a daunting task. To provide +     application developers with a more accessible way of +     understanding the generated object models, the XSD compiler +     can be instructed to produce source code with documentation +     comments in the Doxygen format. Then the source code can be +     processed with the <a href="http://www.doxygen.org">Doxygen</a> +     documentation system to extract this information and produce +     documentation in various formats. +  </p> + +  <p>In this section we will see how to generate documentation +     for our "Hello World" vocabulary. To showcase the full power +     of the XSD documentation facilities, we will first document +     our schema. The XSD compiler will then transfer +     this information from the schema to the generated code and +     then to the object model documentation. Note that the +     documentation in the schema is not required for XSD to +     generate useful documentation. Below you will find +     our <code>hello.xsd</code> with added documentation:</p> + +  <pre class="xml"> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + +  <xs:complexType name="hello_t"> + +    <xs:annotation> +      <xs:documentation> +        The hello_t type consists of a greeting phrase and a +        collection of names to which this greeting applies. +      </xs:documentation> +    </xs:annotation> + +    <xs:sequence> + +      <xs:element name="greeting" type="xs:string"> +        <xs:annotation> +          <xs:documentation> +            The greeting element contains the greeting phrase +            for this hello object. +          </xs:documentation> +        </xs:annotation> +      </xs:element> + +      <xs:element name="name" type="xs:string" maxOccurs="unbounded"> +        <xs:annotation> +          <xs:documentation> +            The name elements contains names to be greeted. +          </xs:documentation> +        </xs:annotation> +      </xs:element> + +    </xs:sequence> +  </xs:complexType> + +  <xs:element name="hello" type="hello_t"> +    <xs:annotation> +      <xs:documentation> +        The hello element is a root of the Hello XML vocabulary. +        Every conforming document should start with this element. +      </xs:documentation> +    </xs:annotation> +  </xs:element> + +</xs:schema> +  </pre> + +  <p>The first step in obtaining the documentation is to recompile +     our schema with the <code>--generate-doxygen</code> option:</p> + +  <pre class="terminal"> +$ xsd cxx-tree --generate-serialization --generate-doxygen hello.xsd +  </pre> + +  <p>Now the generated <code>hello.hxx</code> file contains comments +     in the Doxygen format. The next step is to process this file +     with the Doxygen documentation system. If your project does +     not use Doxygen then you first need to create a configuration +     file for your project:</p> + +  <pre class="terminal"> +$ doxygen -g hello.doxygen +  </pre> + +  <p>You only need to perform this step once. Now we can generate +     the documentation by executing the following command in the +     directory with the generated source code:</p> + +  <pre class="terminal"> +$ doxygen hello.doxygen +  </pre> + +  <p>While the generated documentation can be useful as is, we can +     go one step further and link (using the Doxygen tags mechanism) +     the documentation for our object model with the documentation +     for the XSD runtime library which defines C++ classes for the +     built-in XML Schema types. This way we can seamlessly browse +     between documentation for the <code>hello_t</code> class which +     is generated by the XSD compiler and the <code>xml_schema::string</code> +     class which is defined in the XSD runtime library. The Doxygen +     configuration file for the XSD runtime is provided with the XSD +     distribution.</p> + +  <p>You can view the result of the steps described in this section +     on the <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/hello/html/annotated.html">Hello +     Example Documentation</a> page.</p> + +  <!-- Chapater 3 --> + + +  <h1><a name="3">3 Overall Mapping Configuration</a></h1> + +  <p>The C++/Tree mapping has a number of configuration parameters that +     determine the overall properties and behavior of the generated code. +     Configuration parameters are specified with the XSD command line +     options. This chapter describes configuration aspects that are most +     commonly encountered by application developers. These include: the +     C++ standard, the character type that is used by the generated code, +     handling of vocabularies that use XML Schema polymorphism, XML Schema +     to C++ namespace mapping, and thread safety. For more ways to configure +     the generated code refer to the +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD +     Compiler Command Line Manual</a>. +  </p> + +  <h2><a name="3.1">3.1 C++ Standard</a></h2> + +  <p>The C++/Tree mapping provides support for ISO/IEC C++ 2011 (C++11) +     and ISO/IEC C++ 1998/2003 (C++98). To select the C++ standard for the +     generated code we use the <code>--std</code> XSD compiler command +     line option. While the majority of the examples in this guide use +     C++11, the document explains the C++11/98 usage difference and so +     they can easily be converted to C++98.</p> + +  <h2><a name="3.2">3.2 Character Type and Encoding</a></h2> + +  <p>The C++/Tree mapping has built-in support for two character types: +    <code>char</code> and <code>wchar_t</code>. You can select the +    character type with the <code>--char-type</code> command line +    option. The default character type is <code>char</code>. The +    character type affects all string and string-based types that +    are used in the mapping. These include the string-based built-in +    XML Schema types, exception types, stream types, etc.</p> + +  <p>Another aspect of the mapping that depends on the character type +     is character encoding. For the <code>char</code> character type +     the default encoding is UTF-8. Other supported encodings are +     ISO-8859-1, Xerces-C++ Local Code Page (LPC), as well as +     custom encodings. You can select which encoding should be used +     in the object model with the <code>--char-encoding</code> command +     line option.</p> + +  <p>For the <code>wchar_t</code> character type the encoding is +     automatically selected between UTF-16 and UTF-32/UCS-4 depending +     on the size of the <code>wchar_t</code> type. On some platforms +     (for example, Windows with Visual C++ and AIX with IBM XL C++) +     <code>wchar_t</code> is 2 bytes long. For these platforms the +     encoding is UTF-16. On other platforms <code>wchar_t</code> is 4 bytes +     long and UTF-32/UCS-4 is used.</p> + +  <p>Note also that the character encoding that is used in the object model +     is independent of the encodings used in input and output XML. In fact, +     all three (object mode, input XML, and output XML) can have different +     encodings.</p> + +  <h2><a name="3.3">3.3 Support for Polymorphism</a></h2> + +  <p>By default XSD generates non-polymorphic code. If your vocabulary +     uses XML Schema polymorphism in the form of <code>xsi:type</code> +     and/or substitution groups, then you will need to compile +     your schemas with the <code>--generate-polymorphic</code> option +     to produce polymorphism-aware code. For more information on +     working with polymorphic object models, refer to +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#2.11">Section 2.11, +     "Mapping for <code>xsi:type</code> and Substitution Groups"</a> in +     the C++/Tree Mapping User Manual.</p> + +  <h2><a name="3.4">3.4 Namespace Mapping</a></h2> + +  <p>XSD maps XML namespaces specified in the <code>targetNamespace</code> +     attribute in XML Schema to one or more nested C++ namespaces. By +     default, a namespace URI is mapped to a sequence of C++ namespace +     names by removing the protocol and host parts and splitting the +     rest into a sequence of names with <code>'/'</code> as the name +     separator.</p> + +  <p>The default mapping of namespace URIs to C++ namespaces +     can be altered using the <code>--namespace-map</code> and +     <code>--namespace-regex</code> compiler options. For example, +     to map namespace URI <code>https://www.codesynthesis.com/my</code> to +     C++ namespace <code>cs::my</code>, we can use the following option:</p> + +  <pre class="terminal"> +--namespace-map https://www.codesynthesis.com/my=cs::my +  </pre> + +  <p>A vocabulary without a namespace is mapped to the global scope. This +     also can be altered with the above options by using an empty name +     for the XML namespace:</p> + +  <pre class="terminal"> +--namespace-map =cs +  </pre> + +  <h2><a name="3.5">3.5 Thread Safety</a></h2> + +  <p>XSD-generated code is thread-safe in the sense that you can +     use different instantiations of the object model in several +     threads concurrently. This is possible due to the generated +     code not relying on any writable global variables. If you need +     to share the same object between several threads then you will +     need to provide some form of synchronization. One approach would +     be to use the generated code customization mechanisms to embed +     synchronization primitives into the generated C++ classes. For more +     information on generated code customization refer to the +     <a href="http://wiki.codesynthesis.com/Tree/Customization_guide">C++/Tree +     Mapping Customization Guide</a>.</p> + +  <p>If you also would like to call parsing and/or serialization +     functions from several threads potentially concurrently, then +     you will need to make sure the Xerces-C++ runtime is initialized +     and terminated only once. The easiest way to do this is to +     initialize/terminate Xerces-C++ from <code>main()</code> when +     there are no threads yet/anymore:</p> + +  <pre class="c++"> +#include <xercesc/util/PlatformUtils.hpp> + +int +main () +{ +  xercesc::XMLPlatformUtils::Initialize (); + +  { +    // Start/terminate threads and parse/serialize here. +  } + +  xercesc::XMLPlatformUtils::Terminate (); +} +  </pre> + +  <p>Because you initialize the Xerces-C++ runtime yourself you should +     also pass the <code>xml_schema::flags::dont_initialize</code> flag +     to parsing and serialization functions. See <a href="#5">Chapter 5, +     "Parsing"</a> and <a href="#6">Chapter 6, "Serialization"</a> for +     more information.</p> + + +  <!-- Chapater 4 --> + + +  <h1><a name="4">4 Working with Object Models</a></h1> + +  <p>As we have seen in the previous chapters, the XSD compiler generates +     a C++ class for each type defined in XML Schema. Together these classes +     constitute an object model for an XML vocabulary. In this chapter we +     will take a closer look at different elements that comprise an +     object model class as well as how to create, access, and modify +     object models.</p> + +  <p>In this and subsequent chapters we will use the following schema +     that describes a collection of person records. We save it in +     <code>people.xsd</code>:</p> + +  <pre class="xml"> +<?xml version="1.0"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + +  <xs:simpleType name="gender_t"> +    <xs:restriction base="xs:string"> +      <xs:enumeration value="male"/> +      <xs:enumeration value="female"/> +    </xs:restriction> +  </xs:simpleType> + +  <xs:complexType name="person_t"> +    <xs:sequence> +      <xs:element name="first-name" type="xs:string"/> +      <xs:element name="middle-name" type="xs:string" minOccurs="0"/> +      <xs:element name="last-name" type="xs:string"/> +      <xs:element name="gender" type="gender_t"/> +      <xs:element name="age" type="xs:short"/> +    </xs:sequence> +    <xs:attribute name="id" type="xs:unsignedInt" use="required"/> +  </xs:complexType> + +  <xs:complexType name="people_t"> +    <xs:sequence> +      <xs:element name="person" type="person_t" maxOccurs="unbounded"/> +    </xs:sequence> +  </xs:complexType> + +  <xs:element name="people" type="people_t"/> + +</xs:schema> +  </pre> + +  <p>A sample XML instance to go along with this schema is saved +     in <code>people.xml</code>:</p> + +  <pre class="xml"> +<?xml version="1.0"?> +<people xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +        xsi:noNamespaceSchemaLocation="people.xsd"> + +  <person id="1"> +    <first-name>John</first-name> +    <last-name>Doe</last-name> +    <gender>male</gender> +    <age>32</age> +  </person> + +  <person id="2"> +    <first-name>Jane</first-name> +    <middle-name>Mary</middle-name> +    <last-name>Doe</last-name> +    <gender>female</gender> +    <age>28</age> +  </person> + +</people> +  </pre> + +  <p>Compiling <code>people.xsd</code> with the XSD compiler results +     in three generated C++ classes: <code>gender_t</code>, +     <code>person_t</code>, and <code>people_t</code>. +     The <code>gender_t</code> class is modelled after the C++ +     <code>enum</code> type. Its definition is presented below:</p> + +  <pre class="c++"> +class gender_t: public xml_schema::string +{ +public: +  enum value +  { +    male, +    female +  }; + +  gender_t (value); +  gender_t (const xml_schema::string&); + +  gender_t& +  operator= (value); + +  operator value () const; +}; +  </pre> + +  <p>The following listing shows how we can use this type:</p> + +  <pre class="c++"> +gender_t m (gender_t::male); +gender_t f ("female"); + +if (m == "female" || f == gender_t::male) +{ +  ... +} + +switch (m) +{ +case gender_t::male: +  { +    ... +  } +case gender_t::female: +  { +    ... +  } +} +  </pre> + +  <p>The other two classes will be examined in detail in the subsequent +     sections.</p> + +  <h2><a name="4.1">4.1 Attribute and Element Cardinalities</a></h2> + +  <p>As we have seen in the previous chapters, XSD generates a different +     set of type definitions and member functions for elements with +     different cardinalities. The C++/Tree mapping divides all the possible +     element and attribute cardinalities into three cardinality classes: +     <em>one</em>, <em>optional</em>, and <em>sequence</em>.</p> + +  <p>The <em>one</em> cardinality class covers all elements that should +     occur exactly once as well as required attributes. In our +     example, the <code>first-name</code>, <code>last-name</code>, +     <code>gender</code>, and <code>age</code> elements as well as +     the <code>id</code> attribute belong to this cardinality class. +     The following code fragment shows type definitions as well as the +     accessor and modifier functions that are generated for the +     <code>gender</code> element in the <code>person_t</code> class:</p> + +  <pre class="c++"> +class person_t +{ +  // gender +  // +  typedef gender_t gender_type; + +  const gender_type& +  gender () const; + +  gender_type& +  gender (); + +  void +  gender (const gender_type&); +}; +  </pre> + +  <p>The <code>gender_type</code> type is an alias for the element's type. +     The first two accessor functions return read-only (constant) and +     read-write references to the element's value, respectively. The +     modifier function sets the new value for the element.</p> + +  <p>The <em>optional</em> cardinality class covers all elements that +     can occur zero or one time as well as optional attributes. In our +     example, the <code>middle-name</code> element belongs to this +     cardinality class. The following code fragment shows the type +     definitions as well as the accessor and modifier functions that +     are generated for this element in the <code>person_t</code> class:</p> + +  <pre class="c++"> +class person_t +{ +  // middle-name +  // +  typedef xml_schema::string middle_name_type; +  typedef xsd::optional<middle_name_type> middle_name_optional; + +  const middle_name_optional& +  middle_name () const; + +  middle_name_optional& +  middle_name (); + +  void +  middle_name (const middle_name_type&); + +  void +  middle_name (const middle_name_optional&); +}; +  </pre> + +  <p>As with the <code>gender</code> element, <code>middle_name_type</code> +     is an alias for the element's type. The <code>middle_name_optional</code> +     type is a container for the element's optional value. It can be queried +     for the presence of the value using the <code>present()</code> function. +     The value itself can be retrieved using the <code>get()</code> +     accessor and set using the <code>set()</code> modifier. The container +     can be reverted to the value not present state with the call to the +     <code>reset()</code> function. The following example shows how we +     can use this container:</p> + +  <pre class="c++"> +person_t::middle_name_optional n ("John"); + +if (n.present ()) +{ +  cout << n.get () << endl; +} + +n.set ("Jane"); +n.reset (); +  </pre> + + +  <p>Unlike the <em>one</em> cardinality class, the accessor functions +     for the <em>optional</em> class return read-only (constant) and +     read-write references to the container instead of the element's +     value directly. The modifier functions set the new value for the +     element.</p> + +  <p>Finally, the <em>sequence</em> cardinality class covers all elements +     that can occur more than once. In our example, the +     <code>person</code> element in the <code>people_t</code> type +     belongs to this cardinality class. The following code fragment shows +     the type definitions as well as the accessor and modifier functions +     that are generated for this element in the <code>people_t</code> +     class:</p> + +  <pre class="c++"> +class people_t +{ +  // person +  // +  typedef person_t person_type; +  typedef xsd::sequence<person_type> person_sequence; +  typedef person_sequence::iterator person_iterator; +  typedef person_sequence::const_iterator person_const_iterator; + +  const person_sequence& +  person () const; + +  person_sequence& +  person (); + +  void +  person (const person_sequence&); +}; +  </pre> + +  <p>Identical to the other cardinality classes, <code>person_type</code> +     is an alias for the element's type. The <code>person_sequence</code> +     type is a sequence container for the element's values. It is based +     on and has the same interface as <code>std::vector</code> and +     therefore can be used in similar ways. The <code>person_iterator</code> +     and <code>person_const_iterator</code> types are read-only +     (constant) and read-write iterators for the <code>person_sequence</code> +     container.</p> + +  <p>Similar to the <em>optional</em> cardinality class, the +     accessor functions for the <em>sequence</em> class return +     read-only (constant) and read-write references to the sequence +     container. The modifier functions copies the entries from +     the passed sequence.</p> + +  <p>C++/Tree is a "flattening" mapping in a sense that many levels of +     nested compositors (<code>choice</code> and <code>sequence</code>), +     all potentially with their own cardinalities, are in the end mapped +     to a flat set of elements with one of the three cardinality classes +     discussed above. While this results in a simple and easy to use API +     for most types, in certain cases, the order of elements in the actual +     XML documents is not preserved once parsed into the object model. To +     overcome this limitation we can mark certain schema types, for which +     content order is not sufficiently preserved, as ordered. For more +     information on this functionality refer to +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#2.8.4">Section +     2.8.4, "Element Order"</a> in the C++/Tree Mapping User Manual.</p> + +  <p>For complex schemas with many levels of nested compositors +     (<code>choice</code> and <code>sequence</code>) it can also +     be hard to deduce the cardinality class of a particular element. +     The generated Doxygen documentation can greatly help with +     this task. For each element and attribute the documentation +     clearly identifies its cardinality class. Alternatively, you +     can study the generated header files to find out the cardinality +     class of a particular attribute or element.</p> + +  <p>In the next sections we will examine how to access and modify +     information stored in an object model using accessor and modifier +     functions described in this section.</p> + +  <h2><a name="4.2">4.2 Accessing the Object Model</a></h2> + +  <p>In this section we will learn how to get to the information +     stored in the object model for our person records vocabulary. +     The following application accesses and prints the contents +     of the <code>people.xml</code> file:</p> + +  <pre class="c++"> +#include <iostream> +#include "people.hxx" + +using namespace std; + +int +main () +{ +  unique_ptr<people_t> ppl (people ("people.xml")); + +  // Iterate over individual person records. +  // +  people_t::person_sequence& ps (ppl->person ()); + +  for (people_t::person_iterator i (ps.begin ()); i != ps.end (); ++i) +  { +    person_t& p (*i); + +    // Print names: first-name and last-name are required elements, +    // middle-name is optional. +    // +    cout << "name:   " << p.first_name () << " "; + +    if (p.middle_name ().present ()) +      cout << p.middle_name ().get () << " "; + +    cout << p.last_name () << endl; + +    // Print gender, age, and id which are all required. +    // +    cout << "gender: " << p.gender () << endl +         << "age:    " << p.age () << endl +         << "id:     " << p.id () << endl +         << endl; +  } +} +  </pre> + +  <p>This code shows common patterns of accessing elements and attributes +     with different cardinality classes. For the sequence element +     (<code>person</code> in <code>people_t</code>) we first obtain a +     reference to the container and then iterate over individual +     records. The values of elements and attributes with the +     <em>one</em> cardinality class (<code>first-name</code>, +     <code>last-name</code>, <code>gender</code>, <code>age</code>, +     and <code>id</code>) can be obtained directly by calling the +     corresponding accessor functions. For the optional element +     <code>middle-name</code> we first check if the value is present +     and only then call <code>get()</code> to retrieve it.</p> + +  <p>Note that when we want to reduce typing by creating a variable +     representing a fragment of the object model that we are currently +     working with (<code>ps</code> and <code>p</code> above), we obtain +     a reference to that fragment instead of making a potentially +     expensive copy. This is generally a good rule to follow when +     creating high-performance applications.</p> + +  <p>If we run the above application on our sample +     <code>people.xml</code>, the output looks as follows:</p> + +  <pre class="terminal"> +name:   John Doe +gender: male +age:    32 +id:     1 + +name:   Jane Mary Doe +gender: female +age:    28 +id:     2 +  </pre> + + +  <h2><a name="4.3">4.3 Modifying the Object Model</a></h2> + +  <p>In this section we will learn how to modify the information +     stored in the object model for our person records vocabulary. +     The following application changes the contents of the +     <code>people.xml</code> file:</p> + +  <pre class="c++"> +#include <iostream> +#include "people.hxx" + +using namespace std; + +int +main () +{ +  unique_ptr<people_t> ppl (people ("people.xml")); + +  // Iterate over individual person records and increment +  // the age. +  // +  people_t::person_sequence& ps (ppl->person ()); + +  for (people_t::person_iterator i (ps.begin ()); i != ps.end (); ++i) +  { +    // Alternative way: i->age ()++; +    // +    i->age (i->age () + 1); +  } + +  // Add middle-name to the first record and remove it from +  // the second. +  // +  person_t& john (ps[0]); +  person_t& jane (ps[1]); + +  john.middle_name ("Mary"); +  jane.middle_name ().reset (); + +  // Add another John record. +  // +  ps.push_back (john); + +  // Serialize the modified object model to XML. +  // +  xml_schema::namespace_infomap map; +  map[""].name = ""; +  map[""].schema = "people.xsd"; + +  people (cout, *ppl, map); +} +  </pre> + +  <p>The first modification the above application performs is iterating +     over person records and incrementing the age value. This code +     fragment shows how to modify the value of a required attribute +     or element. The next modification shows how to set a new value +     for the optional <code>middle-name</code> element as well +     as clear its value. Finally the example adds a copy of the +     John Doe record to the <code>person</code> element sequence.</p> + +  <p>Note that in this case using references for the <code>ps</code>, +     <code>john</code>, and <code>jane</code> variables is no longer +     a performance improvement but a requirement for the application +     to function correctly. If we hadn't used references, all our changes +     would have been made on copies without affecting the object model.</p> + +  <p>If we run the above application on our sample <code>people.xml</code>, +     the output looks as follows:</p> + +  <pre class="xml"> +<?xml version="1.0"?> +<people xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +        xsi:noNamespaceSchemaLocation="people.xsd"> + +  <person id="1"> +    <first-name>John</first-name> +    <middle-name>Mary</middle-name> +    <last-name>Doe</last-name> +    <gender>male</gender> +    <age>33</age> +  </person> + +  <person id="2"> +    <first-name>Jane</first-name> +    <last-name>Doe</last-name> +    <gender>female</gender> +    <age>29</age> +  </person> + +  <person id="1"> +    <first-name>John</first-name> +    <middle-name>Mary</middle-name> +    <last-name>Doe</last-name> +    <gender>male</gender> +    <age>33</age> +  </person> + +</people> +  </pre> + + +  <h2><a name="4.4">4.4 Creating the Object Model from Scratch</a></h2> + +  <p>In this section we will learn how to create a new object model +     for our person records vocabulary. The following application +     recreates the content of the original <code>people.xml</code> +     file:</p> + +  <pre class="c++"> +#include <iostream> +#include "people.hxx" + +using namespace std; + +int +main () +{ +  people_t ppl; +  people_t::person_sequence& ps (ppl.person ()); + +  // Add the John Doe record. +  // +  ps.push_back ( +    person_t ("John",         // first-name +              "Doe",          // last-name +              gender_t::male, // gender +              32,             // age +              1)); + +  // Add the Jane Doe record. +  // +  ps.push_back ( +    person_t ("Jane",           // first-name +              "Doe",            // last-name +              gender_t::female, // gender +              28,               // age +              2));              // id + +  // Add middle name to the Jane Doe record. +  // +  person_t& jane (ps.back ()); +  jane.middle_name ("Mary"); + +  // Serialize the object model to XML. +  // +  xml_schema::namespace_infomap map; +  map[""].name = ""; +  map[""].schema = "people.xsd"; + +  people (cout, ppl, map); +} +  </pre> + +  <p>The only new part in the above application is the calls +     to the <code>people_t</code> and <code>person_t</code> +     constructors. As a general rule, for each C++ class +     XSD generates a constructor with initializers +     for each element and attribute belonging to the <em>one</em> +     cardinality class. For our vocabulary, the following +     constructors are generated:</p> + +  <pre class="c++"> +class person_t +{ +  person_t (const first_name_type&, +            const last_name_type&, +            const gender_type&, +            const age_type&, +            const id_type&); +}; + +class people_t +{ +  people_t (); +}; +  </pre> + +  <p>Note also that we set the <code>middle-name</code> element +     on the Jane Doe record by obtaining a reference to that record +     in the object model and setting the <code>middle-name</code> +     value on it. This is a general rule that should be followed +     in order to obtain the best performance: if possible, +     direct modifications to the object model should be preferred +     to modifications on temporaries with subsequent copying. The +     following code fragment shows a semantically equivalent but +     slightly slower version:</p> + +  <pre class="c++"> +// Add the Jane Doe record. +// +person_t jane ("Jane",           // first-name +               "Doe",            // last-name +               gender_t::female, // gender +               28,               // age +               2);               // id + +jane.middle_name ("Mary"); + +ps.push_back (jane); +  </pre> + +  <p>We can also go one step further to reduce copying and improve +     the performance of our application by using the non-copying +    <code>push_back()</code> function which assumes ownership +     of the passed objects:</p> + +  <pre class="c++"> +// Add the Jane Doe record. C++11 version +// +unique_ptr<person_t> jane_p ( +  new person_t ("Jane",           // first-name +                "Doe",            // last-name +                gender_t::female, // gender +                28,               // age +                2));              // id +ps.push_back (std::move (jane_p)); // assumes ownership + +// Add the John Doe record. C++98 version. +// +auto_ptr<person_t> john_p ( +  new person_t ("John",           // first-name +                "Doe",            // last-name +                gender_t::male,   // gender +                32,               // age +                1)); +ps.push_back (john_p); // assumes ownership +  </pre> + +  <p>For more information on the non-copying modifier functions refer to +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#2.8">Section +     2.8, "Mapping for Local Elements and Attributes"</a> in the C++/Tree Mapping +     User Manual. The above application produces the following output:</p> + +  <pre class="xml"> +<?xml version="1.0" ?> +<people xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +        xsi:noNamespaceSchemaLocation="people.xsd"> + +  <person id="1"> +    <first-name>John</first-name> +    <last-name>Doe</last-name> +    <gender>male</gender> +    <age>32</age> +  </person> + +  <person id="2"> +    <first-name>Jane</first-name> +    <middle-name>Mary</middle-name> +    <last-name>Doe</last-name> +    <gender>female</gender> +    <age>28</age> +  </person> + +</people> +  </pre> + +  <h2><a name="4.5">4.5 Mapping for the Built-in XML Schema Types</a></h2> + +  <p>Our person record vocabulary uses several built-in XML Schema +     types: <code>string</code>, <code>short</code>, and +     <code>unsignedInt</code>. Until now we haven't talked about +     the mapping of built-in XML Schema types to C++ types and how +     to work with them. This section provides an overview +     of the built-in types. For more detailed information refer +     to <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#2.5">Section +     2.5, "Mapping for Built-in Data Types"</a> in the C++/Tree Mapping +     User Manual.</p> + +  <p>In XML Schema, built-in types are defined in the XML Schema namespace. +     By default, the C++/Tree mapping maps this namespace to C++ +     namespace <code>xml_schema</code> (this mapping can be altered +     with the <code>--namespace-map</code> option). The following table +     summarizes the mapping of XML Schema built-in types to C++ types:</p> + +  <!-- border="1" is necessary for html2ps --> +  <table id="builtin" border="1"> +    <tr> +      <th>XML Schema type</th> +      <th>Alias in the <code>xml_schema</code> namespace</th> +      <th>C++ type</th> +    </tr> + +    <tr> +      <th colspan="3">fixed-length integral types</th> +    </tr> +    <!-- 8-bit --> +    <tr> +      <td><code>byte</code></td> +      <td><code>byte</code></td> +      <td><code>signed char</code></td> +    </tr> +    <tr> +      <td><code>unsignedByte</code></td> +      <td><code>unsigned_byte</code></td> +      <td><code>unsigned char</code></td> +    </tr> + +    <!-- 16-bit --> +    <tr> +      <td><code>short</code></td> +      <td><code>short_</code></td> +      <td><code>short</code></td> +    </tr> +    <tr> +      <td><code>unsignedShort</code></td> +      <td><code>unsigned_short</code></td> +      <td><code>unsigned short</code></td> +    </tr> + +    <!-- 32-bit --> +    <tr> +      <td><code>int</code></td> +      <td><code>int_</code></td> +      <td><code>int</code></td> +    </tr> +    <tr> +      <td><code>unsignedInt</code></td> +      <td><code>unsigned_int</code></td> +      <td><code>unsigned int</code></td> +    </tr> + +    <!-- 64-bit --> +    <tr> +      <td><code>long</code></td> +      <td><code>long_</code></td> +      <td><code>long long</code></td> +    </tr> +    <tr> +      <td><code>unsignedLong</code></td> +      <td><code>unsigned_long</code></td> +      <td><code>unsigned long long</code></td> +    </tr> + +    <tr> +      <th colspan="3">arbitrary-length integral types</th> +    </tr> +    <tr> +      <td><code>integer</code></td> +      <td><code>integer</code></td> +      <td><code>long long</code></td> +    </tr> +    <tr> +      <td><code>nonPositiveInteger</code></td> +      <td><code>non_positive_integer</code></td> +      <td><code>long long</code></td> +    </tr> +    <tr> +      <td><code>nonNegativeInteger</code></td> +      <td><code>non_negative_integer</code></td> +      <td><code>unsigned long long</code></td> +    </tr> +    <tr> +      <td><code>positiveInteger</code></td> +      <td><code>positive_integer</code></td> +      <td><code>unsigned long long</code></td> +    </tr> +    <tr> +      <td><code>negativeInteger</code></td> +      <td><code>negative_integer</code></td> +      <td><code>long long</code></td> +    </tr> + +    <tr> +      <th colspan="3">boolean types</th> +    </tr> +    <tr> +      <td><code>boolean</code></td> +      <td><code>boolean</code></td> +      <td><code>bool</code></td> +    </tr> + +    <tr> +      <th colspan="3">fixed-precision floating-point types</th> +    </tr> +    <tr> +      <td><code>float</code></td> +      <td><code>float_</code></td> +      <td><code>float</code></td> +    </tr> +    <tr> +      <td><code>double</code></td> +      <td><code>double_</code></td> +      <td><code>double</code></td> +    </tr> + +    <tr> +      <th colspan="3">arbitrary-precision floating-point types</th> +    </tr> +    <tr> +      <td><code>decimal</code></td> +      <td><code>decimal</code></td> +      <td><code>double</code></td> +    </tr> + +    <tr> +      <th colspan="3">string types</th> +    </tr> +    <tr> +      <td><code>string</code></td> +      <td><code>string</code></td> +      <td>type derived from <code>std::basic_string</code></td> +    </tr> +    <tr> +      <td><code>normalizedString</code></td> +      <td><code>normalized_string</code></td> +      <td>type derived from <code>string</code></td> +    </tr> +    <tr> +      <td><code>token</code></td> +      <td><code>token</code></td> +      <td>type derived from <code>normalized_string</code></td> +    </tr> +    <tr> +      <td><code>Name</code></td> +      <td><code>name</code></td> +      <td>type derived from <code>token</code></td> +    </tr> +    <tr> +      <td><code>NMTOKEN</code></td> +      <td><code>nmtoken</code></td> +      <td>type derived from <code>token</code></td> +    </tr> +    <tr> +      <td><code>NMTOKENS</code></td> +      <td><code>nmtokens</code></td> +      <td>type derived from <code>sequence<nmtoken></code></td> +    </tr> +    <tr> +      <td><code>NCName</code></td> +      <td><code>ncname</code></td> +      <td>type derived from <code>name</code></td> +    </tr> +    <tr> +      <td><code>language</code></td> +      <td><code>language</code></td> +      <td>type derived from <code>token</code></td> +    </tr> + +    <tr> +      <th colspan="3">qualified name</th> +    </tr> +    <tr> +      <td><code>QName</code></td> +      <td><code>qname</code></td> +      <td><code>xml_schema::qname</code></td> +    </tr> + +    <tr> +      <th colspan="3">ID/IDREF types</th> +    </tr> +    <tr> +      <td><code>ID</code></td> +      <td><code>id</code></td> +      <td>type derived from <code>ncname</code></td> +    </tr> +    <tr> +      <td><code>IDREF</code></td> +      <td><code>idref</code></td> +      <td>type derived from <code>ncname</code></td> +    </tr> +    <tr> +      <td><code>IDREFS</code></td> +      <td><code>idrefs</code></td> +      <td>type derived from <code>sequence<idref></code></td> +    </tr> + +    <tr> +      <th colspan="3">URI types</th> +    </tr> +    <tr> +      <td><code>anyURI</code></td> +      <td><code>uri</code></td> +      <td>type derived from <code>std::basic_string</code></td> +    </tr> + +    <tr> +      <th colspan="3">binary types</th> +    </tr> +    <tr> +      <td><code>base64Binary</code></td> +      <td><code>base64_binary</code></td> +      <td><code>xml_schema::base64_binary</code></td> +    </tr> +    <tr> +      <td><code>hexBinary</code></td> +      <td><code>hex_binary</code></td> +      <td><code>xml_schema::hex_binary</code></td> +    </tr> + +    <tr> +      <th colspan="3">date/time types</th> +    </tr> +    <tr> +      <td><code>date</code></td> +      <td><code>date</code></td> +      <td><code>xml_schema::date</code></td> +    </tr> +    <tr> +      <td><code>dateTime</code></td> +      <td><code>date_time</code></td> +      <td><code>xml_schema::date_time</code></td> +    </tr> +    <tr> +      <td><code>duration</code></td> +      <td><code>duration</code></td> +      <td><code>xml_schema::duration</code></td> +    </tr> +    <tr> +      <td><code>gDay</code></td> +      <td><code>gday</code></td> +      <td><code>xml_schema::gday</code></td> +    </tr> +    <tr> +      <td><code>gMonth</code></td> +      <td><code>gmonth</code></td> +      <td><code>xml_schema::gmonth</code></td> +    </tr> +    <tr> +      <td><code>gMonthDay</code></td> +      <td><code>gmonth_day</code></td> +      <td><code>xml_schema::gmonth_day</code></td> +    </tr> +    <tr> +      <td><code>gYear</code></td> +      <td><code>gyear</code></td> +      <td><code>xml_schema::gyear</code></td> +    </tr> +    <tr> +      <td><code>gYearMonth</code></td> +      <td><code>gyear_month</code></td> +      <td><code>xml_schema::gyear_month</code></td> +    </tr> +    <tr> +      <td><code>time</code></td> +      <td><code>time</code></td> +      <td><code>xml_schema::time</code></td> +    </tr> + +    <tr> +      <th colspan="3">entity types</th> +    </tr> +    <tr> +      <td><code>ENTITY</code></td> +      <td><code>entity</code></td> +      <td>type derived from <code>name</code></td> +    </tr> +    <tr> +      <td><code>ENTITIES</code></td> +      <td><code>entities</code></td> +      <td>type derived from <code>sequence<entity></code></td> +    </tr> +  </table> + +  <p>As you can see from the table above a number of built-in +     XML Schema types are mapped to fundamental C++ types such +     as <code>int</code> or <code>bool</code>. All string-based +     XML Schema types are mapped to C++ types that are derived +     from either <code>std::string</code> or +     <code>std::wstring</code>, depending on the character +     type selected. For access and modification purposes these +     types can be treated as <code>std::string</code>. A number +     of built-in types, such as <code>qname</code>, the binary +     types, and the date/time types do not have suitable +     fundamental or standard C++ types to map to. As a result, +     these types are implemented from scratch in the XSD runtime. +     For more information on their interfaces refer to +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#2.5">Section +     2.5, "Mapping for Built-in Data Types"</a> in the C++/Tree Mapping +     User Manual.</p> + + +  <!-- Chapater 5 --> + + +  <h1><a name="5">5 Parsing</a></h1> + +  <p>We have already seen how to parse XML to an object model in this guide +     before. In this chapter we will discuss the parsing topic in more +     detail.</p> + +  <p>By default, the C++/Tree mapping provides a total of 14 overloaded +     parsing functions. They differ in the input methods used to +     read XML as well as the error reporting mechanisms. It is also possible +     to generate types for root elements instead of parsing and serialization +     functions. This may be useful if your XML vocabulary has multiple +     root elements. For more information on element types refer to +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#2.9">Section +     2.9, "Mapping for Global Elements"</a> in the C++/Tree Mapping User +     Manual.</p> + + +  <p>In this section we will discuss the most commonly used versions of +     the parsing functions. For a comprehensive description of parsing +     refer to <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#3">Chapter +     3, "Parsing"</a> in the C++/Tree Mapping User Manual. For the <code>people</code> +     global element from our person record vocabulary, we will concentrate +     on the following three parsing functions:</p> + +  <pre class="c++"> +std::[unique|auto]_ptr<people_t> +people (const std::string& uri, +	xml_schema::flags f = 0, +	const xml_schema::properties& p = xml_schema::properties ()); + +std::[unique|auto]_ptr<people_t> +people (std::istream& is, +        xml_schema::flags f = 0, +        const xml_schema::properties& p = xml_schema::properties ()); + +std::[unique|auto]_ptr<people_t> +people (std::istream& is, +        const std::string& resource_id, +        xml_schema::flags f = 0, +        const xml_schema::properties& p = ::xml_schema::properties ()); +  </pre> + +  <p>The first function parses a local file or a URI. We have already +     used this parsing function in the previous chapters. The second +     and third functions read XML from a standard input stream. The +     last function also requires a resource id. This id is used to +     identify the XML document being parser in diagnostics  messages +     as well as to resolve relative paths to other documents (for example, +     schemas) that might be referenced from the XML document.</p> + +  <p>The last two arguments to all three parsing functions are parsing +     flags and properties. The flags argument provides a number of ways +     to fine-tune the parsing process. The properties argument allows +     to pass additional information to the parsing functions. We will +     use these two arguments in <a href="#5.1">Section 5.1, "XML Schema +     Validation and Searching"</a> below. All three functions return +     the object model as either <code>std::unique_ptr</code> (C++11) or +     <code>std::auto_ptr</code> (C++98), depending on the C++ standard +     selected (<code>--std</code> XSD compiler option). The following +     example shows how we can use the above parsing functions:</p> + +  <pre class="c++"> +using std::unique_ptr; + +// Parse a local file or URI. +// +unique_ptr<people_t> p1 (people ("people.xml")); +unique_ptr<people_t> p2 (people ("http://example.com/people.xml")); + +// Parse a local file via ifstream. +// +std::ifstream ifs ("people.xml"); +unique_ptr<people_t> p3 (people (ifs, "people.xml")); + +// Parse an XML string. +// +std::string str ("..."); // XML in a string. +std::istringstream iss (str); +unique_ptr<people_t> p4 (people (iss)); +  </pre> + + +  <h2><a name="5.1">5.1 XML Schema Validation and Searching</a></h2> + +  <p>The C++/Tree mapping relies on the underlying Xerces-C++ XML +     parser for full XML document validation. The XML Schema +     validation is enabled by default and can be disabled by +     passing the <code>xml_schema::flags::dont_validate</code> +     flag to the parsing functions, for example:</p> + +  <pre class="c++"> +unique_ptr<people_t> p ( +  people ("people.xml", xml_schema::flags::dont_validate)); +  </pre> + +  <p>Even when XML Schema validation is disabled, the generated +     code still performs a number of checks to prevent +     construction of an inconsistent object model (for example, an +     object model with missing required attributes or elements).</p> + +  <p>When XML Schema validation is enabled, the XML parser needs +     to locate a schema to validate against. There are several +     methods to provide the schema location information to the +     parser. The easiest and most commonly used method is to +     specify schema locations in the XML document itself +     with the <code>schemaLocation</code> or +     <code>noNamespaceSchemaLocation</code> attributes, for example:</p> + +  <pre class="xml"> +<?xml version="1.0" ?> +<people xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +        xsi:noNamespaceSchemaLocation="people.xsd" +        xsi:schemaLocation="http://www.w3.org/XML/1998/namespace xml.xsd"> +  </pre> + +  <p>As you might have noticed, we used this method in all the sample XML +     documents presented in this guide up until now. Note that the +     schema locations specified with these two attributes are relative +     to the document's path unless they are absolute URIs (that is +     start with <code>http://</code>, <code>file://</code>, etc.). +     In particular, if you specify just file names as your schema +     locations, as we did above, then the schemas should reside in +     the same directory as the XML document itself.</p> + +  <p>Another method of providing the schema location information +     is via the <code>xml_schema::properties</code> argument, as +     shown in the following example:</p> + +  <pre class="c++"> +xml_schema::properties props; +props.no_namespace_schema_location ("people.xsd"); +props.schema_location ("http://www.w3.org/XML/1998/namespace", "xml.xsd"); + +unique_ptr<people_t> p (people ("people.xml", 0, props)); +  </pre> + +  <p>The schema locations provided with this method overrides +     those specified in the XML document. As with the previous +     method, the schema locations specified this way are +     relative to the document's path unless they are absolute URIs. +     In particular, if you want to use local schemas that are +     not related to the document being parsed, then you will +     need to use the <code>file://</code> URI. The following +     example shows how to use schemas that reside in the current +     working directory:</p> + +  <pre class="c++"> +#include <unistd.h> // getcwd +#include <limits.h> // PATH_MAX + +char cwd[PATH_MAX]; +if (getcwd (cwd, PATH_MAX) == 0) +{ +  // Buffer too small? +} + +xml_schema::properties props; + +props.no_namespace_schema_location ( +  "file:///" + std::string (cwd) + "/people.xsd"); + +props.schema_location ( +  "http://www.w3.org/XML/1998/namespace", +  "file:///" + std::string (cwd) + "/xml.xsd"); + +unique_ptr<people_t> p (people ("people.xml", 0, props)); +  </pre> + +  <p>A third method is the most useful if you are planning to parse +     several XML documents of the same vocabulary. In that case +     it may be beneficial to pre-parse and cache the schemas in +     the XML parser which can then be used to parse all documents +     without re-parsing the schemas. For more information on +     this method refer to the <code>caching</code> example in the +     <code>cxx/tree/</code> directory in the +     <a href="https://cppget.org/xsd-examples">xsd-examples</a> package. +     It is also possible to convert the schemas into a pre-compiled +     binary representation and embed this  representation directly into +     the application executable. With this approach your application can +     perform XML Schema validation without depending on any external +     schema files. For more information on how to achieve this refer to +     the <code>embedded</code> example in the <code>cxx/tree/</code> +     directory in the <a href="https://cppget.org/xsd-examples">xsd-examples</a> +     package.</p> + +  <p>When the XML parser cannot locate a schema for the +     XML document, the validation fails and XML document +     elements and attributes for which schema definitions could +     not be located are reported in the diagnostics. For +     example, if we remove the <code>noNamespaceSchemaLocation</code> +     attribute in <code>people.xml</code> from the previous chapter, +     then we will get the following diagnostics if we try to parse +     this file with validation enabled:</p> + +  <pre class="terminal"> +people.xml:2:63 error: no declaration found for element 'people' +people.xml:4:18 error: no declaration found for element 'person' +people.xml:4:18 error: attribute 'id' is not declared for element 'person' +people.xml:5:17 error: no declaration found for element 'first-name' +people.xml:6:18 error: no declaration found for element 'middle-name' +people.xml:7:16 error: no declaration found for element 'last-name' +people.xml:8:13 error: no declaration found for element 'gender' +people.xml:9:10 error: no declaration found for element 'age' +  </pre> + +  <h2><a name="5.2">5.2 Error Handling</a></h2> + +  <p>The parsing functions offer a number of ways to handle error conditions +     with the C++ exceptions being the most commonly used mechanism. All +     C++/Tree exceptions derive from common base <code>xml_schema::exception</code> +     which in turn derives from <code>std::exception</code>. The easiest +     way to uniformly handle all possible C++/Tree exceptions and print +     detailed information about the error is to catch and print +     <code>xml_schema::exception</code>, as shown in the following +     example:</p> + +  <pre class="c++"> +try +{ +  unique_ptr<people_t> p (people ("people.xml")); +} +catch (const xml_schema::exception& e) +{ +  cerr << e << endl; +} +  </pre> + +  <p>Each individual C++/Tree exception also allows you to obtain +     error details programmatically. For example, the +     <code>xml_schema::parsing</code> exception is thrown when +     the XML parsing and validation in the underlying XML parser +     fails. It encapsulates various diagnostics information +     such as the file name, line and column numbers, as well as the +     error or warning message for each entry. For more information +     about this and other exceptions that can be thrown during +     parsing, refer to +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#3.3">Section +     3.3, "Error Handling"</a> in the C++/Tree Mapping +     User Manual.</p> + +  <p>Note that if you are parsing <code>std::istream</code> on which +     exceptions are not enabled, then you will need to check the +     stream state after the call to the parsing function in order +     to detect any possible stream failures, for example:</p> + +  <pre class="c++"> +std::ifstream ifs ("people.xml"); + +if (ifs.fail ()) +{ +  cerr << "people.xml: unable to open" << endl; +  return 1; +} + +unique_ptr<people_t> p (people (ifs, "people.xml")); + +if (ifs.fail ()) +{ +  cerr << "people.xml: read error" << endl; +  return 1; +} +  </pre> + +  <p>The above example can be rewritten to use exceptions as +     shown below:</p> + +  <pre class="c++"> +try +{ +  std::ifstream ifs; +  ifs.exceptions (std::ifstream::badbit | std::ifstream::failbit); +  ifs.open ("people.xml"); + +  unique_ptr<people_t> p (people (ifs, "people.xml")); +} +catch (const std::ifstream::failure&) +{ +  cerr << "people.xml: unable to open or read error" << endl; +  return 1; +} +  </pre> + + +  <!-- Chapater 6 --> + + +  <h1><a name="6">6 Serialization</a></h1> + +  <p>We have already seen how to serialize an object model back to XML +     in this guide before. In this chapter we will discuss the +     serialization topic in more detail.</p> + +  <p>By default, the C++/Tree mapping provides a total of 8 overloaded +     serialization functions. They differ in the output methods used to write +     XML as well as the error reporting mechanisms. It is also possible to +     generate types for root elements instead of parsing and serialization +     functions. This may be useful if your XML vocabulary has multiple +     root elements. For more information on element types refer to +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#2.9">Section +     2.9, "Mapping for Global Elements"</a> in the C++/Tree Mapping User +     Manual.</p> + + +  <p>In this section we will discuss the most commonly +     used version of serialization functions. For a comprehensive description +     of serialization refer to +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#4">Chapter +     4, "Serialization"</a> in the C++/Tree Mapping User Manual. For the +     <code>people</code> global element from our person record vocabulary, +     we will concentrate on the following serialization function:</p> + +  <pre class="c++"> +void +people (std::ostream& os, +        const people_t& x, +        const xml_schema::namespace_infomap& map = +          xml_schema::namespace_infomap (), +        const std::string& encoding = "UTF-8", +        xml_schema::flags f = 0); +  </pre> + +  <p>This function serializes the object model passed as the second +     argument to the standard output stream passed as the first +     argument. The third argument is a namespace information map +     which we will discuss in more detail in the next section. +     The fourth argument is a character encoding that the resulting +     XML document should be in. Possible valid values for this +     argument are "US-ASCII", "ISO8859-1", "UTF-8", "UTF-16BE", +     "UTF-16LE", "UCS-4BE", and "UCS-4LE". Finally, the flags +     argument allows fine-tuning of the serialization process. +     The following example shows how we can use the above serialization +     function:</p> + +  <pre class="c++"> +people_t& p = ... + +xml_schema::namespace_infomap map; +map[""].schema = "people.xsd"; + +// Serialize to stdout. +// +people (std::cout, p, map); + +// Serialize to a file. +// +std::ofstream ofs ("people.xml"); +people (ofs, p, map); + +// Serialize to a string. +// +std::ostringstream oss; +people (oss, p, map); +std::string xml (oss.str ()); +  </pre> + + +  <h2><a name="6.1">6.1 Namespace and Schema Information</a></h2> + +  <p>While XML serialization can be done just from the object +     model alone, it is often desirable to assign meaningful +     prefixes to XML namespaces used in the vocabulary as +     well as to provide the schema location information. +     This is accomplished by passing the namespace information +     map to the serialization function. The key in this map is +     a namespace prefix that should be assigned to an XML namespace +     specified in the <code>name</code> variable of the +     map value. You can also assign an optional schema location for +     this namespace in the <code>schema</code> variable. Based +     on each key-value entry in this map, the serialization +     function adds two attributes to the resulting XML document: +     the namespace-prefix mapping attribute and schema location +     attribute. The empty prefix indicates that the namespace +     should be mapped without a prefix. For example, the following +     map:</p> + +  <pre class="c++"> +xml_schema::namespace_infomap map; + +map[""].name = "http://www.example.com/example"; +map[""].schema = "example.xsd"; + +map["x"].name = "http://www.w3.org/XML/1998/namespace"; +map["x"].schema = "xml.xsd"; +  </pre> + +  <p>Results in the following XML document:</p> + +  <pre class="xml"> +<?xml version="1.0" ?> +<example +  xmlns="http://www.example.com/example" +  xmlns:x="http://www.w3.org/XML/1998/namespace" +  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +  xsi:schemaLocation="http://www.example.com/example example.xsd +                      http://www.w3.org/XML/1998/namespace xml.xsd"> +  </pre> + +  <p>The empty namespace indicates that the vocabulary has no target +     namespace. For example, the following map results in only the +     <code>noNamespaceSchemaLocation</code> attribute being added:</p> + +  <pre class="c++"> +xml_schema::namespace_infomap map; + +map[""].name = ""; +map[""].schema = "example.xsd"; +  </pre> + +  <h2><a name="6.2">6.2 Error Handling</a></h2> + +  <p>Similar to the parsing functions, the serialization functions offer a +     number of ways to handle error conditions with the C++ exceptions being +     the most commonly used mechanisms. As with parsing, the easiest way to +     uniformly handle all possible serialization exceptions and print +     detailed information about the error is to catch and print +     <code>xml_schema::exception</code>:</p> + + <pre class="c++"> +try +{ +  people_t& p = ... + +  xml_schema::namespace_infomap map; +  map[""].schema = "people.xsd"; + +  people (std::cout, p, map)); +} +catch (const xml_schema::exception& e) +{ +  cerr << e << endl; +} +  </pre> + +  <p>The most commonly encountered serialization exception is +     <code>xml_schema::serialization</code>. It is thrown +     when the XML serialization in the underlying XML writer +     fails. It encapsulates various diagnostics information +     such as the file name, line and column numbers, as well as the +     error or warning message for each entry. For more information +     about this and other exceptions that can be thrown during +     serialization, refer to +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#4.4">Section +     4.4, "Error Handling"</a> in the C++/Tree Mapping +     User Manual.</p> + +  <p>Note that if you are serializing to <code>std::ostream</code> on +     which exceptions are not enabled, then you will need to check the +     stream state after the call to the serialization function in order +     to detect any possible stream failures, for example:</p> + +  <pre class="c++"> +std::ofstream ofs ("people.xml"); + +if (ofs.fail ()) +{ +  cerr << "people.xml: unable to open" << endl; +  return 1; +} + +people (ofs, p, map)); + +if (ofs.fail ()) +{ +  cerr << "people.xml: write error" << endl; +  return 1; +} +  </pre> + +  <p>The above example can be rewritten to use exceptions as +     shown below:</p> + +  <pre class="c++"> +try +{ +  std::ofstream ofs; +  ofs.exceptions (std::ofstream::badbit | std::ofstream::failbit); +  ofs.open ("people.xml"); + +  people (ofs, p, map)); +} +catch (const std::ofstream::failure&) +{ +  cerr << "people.xml: unable to open or write error" << endl; +  return 1; +} +  </pre> + +  </div> +</div> + +</body> +</html> diff --git a/doc/cxx/tree/guide/index.xhtml.in b/doc/cxx/tree/guide/index.xhtml.in new file mode 100644 index 0000000..2f7f1e2 --- /dev/null +++ b/doc/cxx/tree/guide/index.xhtml.in @@ -0,0 +1,2736 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> + +<head> +  <title>C++/Tree Mapping Getting Started Guide</title> + +  <meta name="copyright" content="© @copyright@"/> +  <meta name="keywords" content="xsd,xml,schema,c++,mapping,data,binding,parsing,serialization,validation"/> +  <meta name="description" content="C++/Tree Mapping Getting Started Guide"/> + +  <link rel="stylesheet" type="text/css" href="../../../default.css" /> + +<style type="text/css"> +  pre { +    padding    : 0 0 0 0em; +    margin     : 0em 0em 0em 0; + +    font-size  : 102% +  } + +  body { +    min-width: 48em; +  } + +  h1 { +    font-weight: bold; +    font-size: 200%; +    line-height: 1.2em; +  } + +  h2 { +    font-weight : bold; +    font-size   : 150%; + +    padding-top : 0.8em; +  } + +  h3 { +    font-size   : 140%; +    padding-top : 0.8em; +  } + +  /* Adjust indentation for three levels. */ +  #container { +    max-width: 48em; +  } + +  #content { +    padding: 0 0.1em 0 4em; +    /*background-color: red;*/ +  } + +  #content h1 { +    margin-left: -2.06em; +  } + +  #content h2 { +    margin-left: -1.33em; +  } + +  /* Title page */ + +  #titlepage { +    padding: 2em 0 1em 0; +    border-bottom: 1px solid black; +  } + +  #titlepage .title { +    font-weight: bold; +    font-size: 200%; +    text-align: center; +  } + +  #titlepage #first-title { +    padding: 1em 0 0.4em 0; +  } + +  #titlepage #second-title { +    padding: 0.4em 0 2em 0; +  } + +  /* Lists */ +  ul.list li { +    padding-top      : 0.3em; +    padding-bottom   : 0.3em; +  } + +  div.img { +    text-align: center; +    padding: 2em 0 2em 0; +  } + +  /*  */ +  dl dt { +    padding   : 0.8em 0 0 0; +  } + +  /* Built-in table */ +  #builtin { +    margin: 2em 0 2em 0; + +    border-collapse   : collapse; +    border            : 1px solid; +    border-color      : #000000; + +    font-size        : 11px; +    line-height      : 14px; +  } + +  #builtin th, #builtin td { +    border: 1px solid; +    padding           : 0.9em 0.9em 0.7em 0.9em; +  } + +  #builtin th { +    background : #cde8f6; +  } + +  #builtin td { +    text-align: left; +  } + +  /* TOC */ +  table.toc { +    border-style      : none; +    border-collapse   : separate; +    border-spacing    : 0; + +    margin            : 0.2em 0 0.2em 0; +    padding           : 0 0 0 0; +  } + +  table.toc tr { +    padding           : 0 0 0 0; +    margin            : 0 0 0 0; +  } + +  table.toc * td, table.toc * th { +    border-style      : none; +    margin            : 0 0 0 0; +    vertical-align    : top; +  } + +  table.toc * th { +    font-weight       : normal; +    padding           : 0em 0.1em 0em 0; +    text-align        : left; +    white-space       : nowrap; +  } + +  table.toc * table.toc th { +    padding-left      : 1em; +  } + +  table.toc * td { +    padding           : 0em 0 0em 0.7em; +    text-align        : left; +  } +</style> + + +</head> + +<body> +<div id="container"> +  <div id="content"> + +  <div class="noprint"> + +  <div id="titlepage"> +    <div class="title" id="first-title">C++/Tree Mapping</div> +    <div class="title" id="second-title">Getting Started Guide</div> + +  <p>Copyright © @copyright@.</p> + +  <p>Permission is granted to copy, distribute and/or modify this +     document under the terms of the +     <a href="https://www.codesynthesis.com/licenses/fdl-1.2.txt">GNU Free +     Documentation License, version 1.2</a>; with no Invariant Sections, +     no Front-Cover Texts and no Back-Cover Texts. +  </p> + +  <p>This document is available in the following formats: +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/guide/index.xhtml">XHTML</a>, +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/guide/cxx-tree-guide.pdf">PDF</a>, and +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/guide/cxx-tree-guide.ps">PostScript</a>.</p> + +  </div> + +  <h1>Table of Contents</h1> + +  <table class="toc"> +    <tr> +      <th></th><td><a href="#0">Preface</a> +        <table class="toc"> +          <tr><th></th><td><a href="#0.1">About This Document</a></td></tr> +          <tr><th></th><td><a href="#0.2">More Information</a></td></tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>1</th><td><a href="#1">Introduction</a> +        <table class="toc"> +          <tr><th>1.1</th><td><a href="#1.1">Mapping Overview</a></td></tr> +          <tr><th>1.2</th><td><a href="#1.2">Benefits</a></td></tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>2</th><td><a href="#2">Hello World Example</a> +        <table class="toc"> +          <tr><th>2.1</th><td><a href="#2.1">Writing XML Document and Schema</a></td></tr> +          <tr><th>2.2</th><td><a href="#2.2">Translating Schema to C++</a></td></tr> +          <tr><th>2.3</th><td><a href="#2.3">Implementing Application Logic</a></td></tr> +          <tr><th>2.4</th><td><a href="#2.4">Compiling and Running</a></td></tr> +	  <tr><th>2.5</th><td><a href="#2.5">Adding Serialization</a></td></tr> +	  <tr><th>2.6</th><td><a href="#2.6">Selecting Naming Convention</a></td></tr> +	  <tr><th>2.7</th><td><a href="#2.7">Generating Documentation</a></td></tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>3</th><td><a href="#3">Overall Mapping Configuration</a> +        <table class="toc"> +	  <tr><th>3.1</th><td><a href="#3.1">C++ Standard</a></td></tr> +          <tr><th>3.2</th><td><a href="#3.2">Character Type and Encoding</a></td></tr> +          <tr><th>3.3</th><td><a href="#3.3">Support for Polymorphism </a></td></tr> +          <tr><th>3.4</th><td><a href="#3.4">Namespace Mapping</a></td></tr> +          <tr><th>3.5</th><td><a href="#3.5">Thread Safety</a></td></tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>4</th><td><a href="#4">Working with Object Models</a> +        <table class="toc"> +          <tr><th>4.1</th><td><a href="#4.1">Attribute and Element Cardinalities</a></td></tr> +          <tr><th>4.2</th><td><a href="#4.2">Accessing the Object Model</a></td></tr> +          <tr><th>4.3</th><td><a href="#4.3">Modifying the Object Model</a></td></tr> +          <tr><th>4.4</th><td><a href="#4.4">Creating the Object Model from Scratch</a></td></tr> +	  <tr><th>4.5</th><td><a href="#4.5">Mapping for the Built-in XML Schema Types</a></td></tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>5</th><td><a href="#5">Parsing</a> +        <table class="toc"> +          <tr><th>5.1</th><td><a href="#5.1">XML Schema Validation and Searching</a></td></tr> +          <tr><th>5.2</th><td><a href="#5.2">Error Handling</a></td></tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>6</th><td><a href="#6">Serialization</a> +        <table class="toc"> +          <tr><th>6.1</th><td><a href="#6.1">Namespace and Schema Information</a></td></tr> +          <tr><th>6.2</th><td><a href="#6.2">Error Handling</a></td></tr> +        </table> +      </td> +    </tr> + +  </table> +  </div> + +  <h1><a name="0">Preface</a></h1> + +  <h2><a name="0.1">About This Document</a></h2> + +  <p>The goal of this document is to provide you with an understanding of +     the C++/Tree programming model and allow you to efficiently evaluate +     XSD against your project's technical requirements. As such, this +     document is intended for C++ developers and software architects +     who are looking for an XML processing solution. For a more in-depth +     description of the C++/Tree mapping refer to the +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/">C++/Tree +     Mapping User Manual</a>.</p> + +  <p>Prior experience with XML and C++ is required to understand this +     document. Basic understanding of XML Schema is advantageous but +     not expected or required. +  </p> + + +  <h2><a name="0.2">More Information</a></h2> + +  <p>Beyond this guide, you may also find the following sources of +     information useful:</p> + +  <ul class="list"> +    <li><a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/">C++/Tree +        Mapping User Manual</a></li> + +    <li><a href="http://wiki.codesynthesis.com/Tree/Customization_guide">C++/Tree +        Mapping Customization Guide</a></li> + +    <li><a href="http://wiki.codesynthesis.com/Tree/FAQ">C++/Tree +        Mapping Frequently Asked Questions (FAQ)</a></li> + +    <li><a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD +        Compiler Command Line Manual</a></li> + +    <li>The <code>cxx/tree/</code> directory in the +        <a href="https://cppget.org/xsd-examples">xsd-examples</a> package +        contains a collection of examples and a README file with an overview +        of each example.</li> + +    <li>The <code>README</code> file in the +        <a href="https://cppget.org/xsd-examples">xsd-examples</a> package +        explains how to build the examples.</li> + +    <li>The <a href="https://www.codesynthesis.com/mailman/listinfo/xsd-users">xsd-users</a> +        mailing list is the place to ask technical questions about XSD and the C++/Parser mapping. +        Furthermore, the <a href="https://www.codesynthesis.com/pipermail/xsd-users/">archives</a> +        may already have answers to some of your questions.</li> +  </ul> + +  <!-- Introduction --> + +  <h1><a name="1">1 Introduction</a></h1> + +  <p>Welcome to CodeSynthesis XSD and the C++/Tree mapping. XSD is a +     cross-platform W3C XML Schema to C++ data binding compiler. C++/Tree +     is a W3C XML Schema to C++ mapping that represents the data stored +     in XML as a statically-typed, vocabulary-specific object model. +  </p> + +  <h2><a name="1.1">1.1 Mapping Overview</a></h2> + +  <p>Based on a formal description of an XML vocabulary (schema), the +     C++/Tree mapping produces a tree-like data structure suitable for +     in-memory processing. The core of the mapping consists of C++ +     classes that constitute the object model and are derived from +     types defined in XML Schema as well as XML parsing and +     serialization code.</p> + +  <p>Besides the core features, C++/Tree provide a number of additional +     mapping elements that can be useful in some applications. These +     include serialization and extraction to/from formats others than +     XML, such as unstructured text (useful for debugging) and binary +     representations such as XDR and CDR for high-speed data processing +     as well as automatic documentation generation. The C++/Tree mapping +     also provides a wide range of mechanisms for controlling and +     customizing the generated code.</p> + +  <p>A typical application that uses C++/Tree for XML processing usually +     performs the following three steps: it first reads (parses) an XML +     document to an in-memory object model, it then performs some useful +     computations on that object model which may involve modification +     of the model, and finally it may write (serialize) the modified +     object model back to XML.</p> + +  <p>The next chapter presents a simple application that performs these +     three steps. The following chapters show how to use the C++/Tree +     mapping in more detail.</p> + +  <h2><a name="1.2">1.2 Benefits</a></h2> + +  <p>Traditional XML access APIs such as Document Object Model (DOM) +     or Simple API for XML (SAX) have a number of drawbacks that +     make them less suitable for creating robust and maintainable +     XML processing applications. These drawbacks include: +  </p> + +  <ul class="list"> +    <li>Generic representation of XML in terms of elements, attributes, +        and text forces an application developer to write a substantial +        amount of bridging code that identifies and transforms pieces +        of information encoded in XML to a representation more suitable +        for consumption by the application logic.</li> + +    <li>String-based flow control defers error detection to runtime. +        It also reduces code readability and maintainability.</li> + +    <li>Lack of type safety because the data is represented as text.</li> + +    <li>Resulting applications are hard to debug, change, and +        maintain.</li> +  </ul> + +  <p>In contrast, statically-typed, vocabulary-specific object model +     produced by the C++/Tree mapping allows you to operate in your +     domain terms instead of the generic elements, attributes, and +     text. Static typing helps catch errors at compile-time rather +     than at run-time. Automatic code generation frees you for more +     interesting tasks (such as doing something useful with the +     information stored in the XML documents) and minimizes the +     effort needed to adapt your applications to changes in the +     document structure. To summarize, the C++/Tree object model has +     the following key advantages over generic XML access APIs:</p> + +  <ul class="list"> +    <li><b>Ease of use.</b> The generated code hides all the complexity +        associated with parsing and serializing XML. This includes navigating +        the structure and converting between the text representation and +        data types suitable for manipulation by the application +        logic.</li> + +    <li><b>Natural representation.</b> The object representation allows +         you to access the XML data using your domain vocabulary instead +         of generic elements, attributes, and text.</li> + +    <li><b>Concise code.</b> With the object representation the +        application implementation is simpler and thus easier +        to read and understand.</li> + +    <li><b>Safety.</b> The generated object model is statically +        typed and uses functions instead of strings to access the +        information. This helps catch programming errors at compile-time +        rather than at runtime.</li> + +    <li><b>Maintainability.</b> Automatic code generation minimizes the +        effort needed to adapt the application to changes in the +        document structure. With static typing, the C++ compiler +        can pin-point the places in the client code that need to be +        changed.</li> + +    <li><b>Compatibility.</b> Sequences of elements are represented in +        the object model as containers conforming to the standard C++ +        sequence requirements. This makes it possible to use standard +        C++ algorithms on the object representation and frees you from +        learning yet another container interface, as is the case with +        DOM.</li> + +    <li><b>Efficiency.</b> If the application makes repetitive use +        of the data extracted from XML, then the C++/Tree object model +        is more efficient because the navigation is performed using +        function calls rather than string comparisons and the XML +        data is extracted only once. Furthermore, the runtime memory +        usage is reduced due to more efficient data storage +        (for instance, storing numeric data as integers instead of +        strings) as well as the static knowledge of cardinality +        constraints.</li> +  </ul> + + +  <!-- Hello World Parser --> + + +  <h1><a name="2">2 Hello World Example</a></h1> + +  <p>In this chapter we will examine how to parse, access, modify, and +     serialize a very simple XML document using the XSD-generated +     C++/Tree object model. The code presented in this chapter is +     based on the <code>hello</code> example which can be found in +     the <code>cxx/tree/</code> directory in the +     <a href="https://cppget.org/xsd-examples">xsd-examples</a> package.</p> + +  <h2><a name="2.1">2.1 Writing XML Document and Schema</a></h2> + +  <p>First, we need to get an idea about the structure +     of the XML documents we are going to process. Our +     <code>hello.xml</code>, for example, could look like this:</p> + +  <pre class="xml"> +<?xml version="1.0"?> +<hello> + +  <greeting>Hello</greeting> + +  <name>sun</name> +  <name>moon</name> +  <name>world</name> + +</hello> +  </pre> + +  <p>Then we can write a description of the above XML in the +     XML Schema language and save it into <code>hello.xsd</code>:</p> + +  <pre class="xml"> +<?xml version="1.0"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + +  <xs:complexType name="hello_t"> +    <xs:sequence> +      <xs:element name="greeting" type="xs:string"/> +      <xs:element name="name" type="xs:string" maxOccurs="unbounded"/> +    </xs:sequence> +  </xs:complexType> + +  <xs:element name="hello" type="hello_t"/> + +</xs:schema> +  </pre> + +  <p>Even if you are not familiar with XML Schema, it +     should be easy to connect declarations in <code>hello.xsd</code> +     to elements in <code>hello.xml</code>. The <code>hello_t</code> type +     is defined as a sequence of the nested <code>greeting</code> and +     <code>name</code> elements. Note that the term sequence in XML +     Schema means that elements should appear in a particular order +     as opposed to appearing multiple times. The <code>name</code> +     element has its <code>maxOccurs</code> property set to +     <code>unbounded</code> which means it can appear multiple times +     in an XML document. Finally, the globally-defined <code>hello</code> +     element prescribes the root element for our vocabulary. For an +     easily-approachable introduction to XML Schema refer to +     <a href="http://www.w3.org/TR/xmlschema-0/">XML Schema Part 0: +     Primer</a>.</p> + +  <p>The above schema is a specification of our XML vocabulary; it tells +     everybody what valid documents of our XML-based language should look +     like. We can also update our <code>hello.xml</code> to include the +     information about the schema so that XML parsers can validate +     our document:</p> + +      <pre class="xml"> +<?xml version="1.0"?> +<hello xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +       xsi:noNamespaceSchemaLocation="hello.xsd"> + +  <greeting>Hello</greeting> + +  <name>sun</name> +  <name>moon</name> +  <name>world</name> + +</hello> +      </pre> + + +  <p>The next step is to compile the schema to generate the object +     model and parsing functions.</p> + +  <h2><a name="2.2">2.2 Translating Schema to C++</a></h2> + +  <p>Now we are ready to translate our <code>hello.xsd</code> to C++. +     To do this we invoke the XSD compiler from a terminal (UNIX) or +     a command prompt (Windows): +  </p> + +  <pre class="terminal"> +$ xsd cxx-tree hello.xsd +  </pre> + +  <p>The XSD compiler produces two C++ files: <code>hello.hxx</code> and +     <code>hello.cxx</code>. The following code fragment is taken from +     <code>hello.hxx</code>; it should give you an idea about what gets +     generated: +  </p> + +  <pre class="c++"> +class hello_t +{ +public: +  // greeting +  // +  typedef xml_schema::string greeting_type; + +  const greeting_type& +  greeting () const; + +  greeting_type& +  greeting (); + +  void +  greeting (const greeting_type& x); + +  // name +  // +  typedef xml_schema::string name_type; +  typedef xsd::sequence<name_type> name_sequence; +  typedef name_sequence::iterator name_iterator; +  typedef name_sequence::const_iterator name_const_iterator; + +  const name_sequence& +  name () const; + +  name_sequence& +  name (); + +  void +  name (const name_sequence& s); + +  // Constructor. +  // +  hello_t (const greeting_type&); + +  ... + +}; + +std::unique_ptr<hello_t> +hello (const std::string& uri); + +std::unique_ptr<hello_t> +hello (std::istream&); +  </pre> + +  <p>The <code>hello_t</code> C++ class corresponds to the +     <code>hello_t</code> XML Schema type. For each element +     in this type a set of C++ type definitions as well as +     accessor and modifier functions are generated inside the +     <code>hello_t</code> class. Note that the type definitions +     and member functions for the <code>greeting</code> and +     <code>name</code> elements are different because of the +     cardinality differences between these two elements +     (<code>greeting</code> is a required single element and +     <code>name</code> is a sequence of elements).</p> + +  <p>The <code>xml_schema::string</code> type used in the type +     definitions is a C++ class provided by the XSD runtime +     that corresponds to built-in XML Schema type +     <code>string</code>. The <code>xml_schema::string</code> +     is based on <code>std::string</code> and can be used as +     such. Similarly, the <code>sequence</code> class template +     that is used in the <code>name_sequence</code> type +     definition is based on and has the same interface as +     <code>std::vector</code>. The mapping between the built-in +     XML Schema types and C++ types is described in more detail in +     <a href="#4.5">Section 4.5, "Mapping for the Built-in XML Schema +     Types"</a>. The <code>hello_t</code> class also includes a +     constructor with an initializer for the required +     <code>greeting</code> element as its argument.</p> + +  <p>The <code>hello</code> overloaded global functions correspond +     to the <code>hello</code> global element in XML Schema. A +     global element in XML Schema is a valid document root. +     By default XSD generated a set of parsing functions for each +     global element defined in XML Schema (this can be overridden +     with the <code>--root-element-*</code> options). Parsing +     functions return a dynamically allocated object model as an +     automatic pointer. The actual pointer used depends on the +     C++ standard selected. For C++11 it is <code>std::unique_ptr</code> +     as shown above. For C++98 it is <code>std::auto_ptr</code>. +     For example, if we modify our XSD compiler invocation to +     select C++98:</p> + +  <pre class="terminal"> +$ xsd cxx-tree --std c++98 hello.xsd +  </pre> + +  <p>Then the parsing function signatures will become:</p> + +  <pre class="c++"> +std::auto_ptr<hello_t> +hello (const std::string& uri); + +std::auto_ptr<hello_t> +hello (std::istream&); +  </pre> + +  <p>For more information on parsing functions see <a href="#5">Chapter 5, +     "Parsing"</a>.</p> + +  <h2><a name="2.3">2.3 Implementing Application Logic</a></h2> + +  <p>At this point we have all the parts we need to do something useful +     with the information stored in our XML document: +  </p> + +  <pre class="c++"> +#include <iostream> +#include "hello.hxx" + +using namespace std; + +int +main (int argc, char* argv[]) +{ +  try +  { +    unique_ptr<hello_t> h (hello (argv[1])); + +    for (hello_t::name_const_iterator i (h->name ().begin ()); +         i != h->name ().end (); +         ++i) +    { +      cerr << h->greeting () << ", " << *i << "!" << endl; +    } +  } +  catch (const xml_schema::exception& e) +  { +    cerr << e << endl; +    return 1; +  } +} +  </pre> + +  <p>The first part of our application calls one of the parsing +     functions to parser an XML file specified in the command line. +     We then use the returned object model to iterate over names +     and print a greeting line for each of them. Finally, we +     catch and print the <code>xml_schema::exception</code> +     exception in case something goes wrong. This exception +     is the root of the exception hierarchy used by the +     XSD-generated code. +  </p> + + +  <h2><a name="2.4">2.4 Compiling and Running</a></h2> + +  <p>After saving our application from the previous section in +     <code>driver.cxx</code>, we are ready to compile our first +     program and run it on the test XML document. On a UNIX +     system this can be done with the following commands: +  </p> + +  <pre class="terminal"> +$ c++ -std=c++11 -I.../libxsd -c driver.cxx hello.cxx +$ c++ -std=c++11 -o driver driver.o hello.o -lxerces-c +$ ./driver hello.xml +Hello, sun! +Hello, moon! +Hello, world! +  </pre> + +  <p>Here <code>.../libxsd</code> represents the path to the +     <a href="https://cppget.org/libxsd">libxsd</a> package root +     directory. Note also that we are required to link our +     application with the Xerces-C++ library because the generated +     code uses it as the underlying XML parser.</p> + +  <h2><a name="2.5">2.5 Adding Serialization</a></h2> + +  <p>While parsing and accessing the XML data may be everything +     you need, there are applications that require creating new +     or modifying existing XML documents. By default XSD does +     not produce serialization code. We will need to request +     it with the <code>--generate-serialization</code> options:</p> + +  <pre class="terminal"> +$ xsd cxx-tree --generate-serialization hello.xsd +  </pre> + +  <p>If we now examine the generated <code>hello.hxx</code> file, +     we will find a set of overloaded serialization functions, +     including the following version:</p> + +  <pre class="c++"> +void +hello (std::ostream&, +       const hello_t&, +       const xml_schema::namespace_infomap& = +         xml_schema::namespace_infomap ()); + +  </pre> + +  <p>Just like with parsing functions, XSD generates serialization +     functions for each global element unless instructed otherwise +     with one of the <code>--root-element-*</code> options. For more +     information on serialization functions see <a href="#6">Chapter 6, +     "Serialization"</a>.</p> + +  <p>We first examine an application that modifies an existing +     object model and serializes it back to XML:</p> + +  <pre class="c++"> +#include <iostream> +#include "hello.hxx" + +using namespace std; + +int +main (int argc, char* argv[]) +{ +  try +  { +    unique_ptr<hello_t> h (hello (argv[1])); + +    // Change the greeting phrase. +    // +    h->greeting ("Hi"); + +    // Add another entry to the name sequence. +    // +    h->name ().push_back ("mars"); + +    // Serialize the modified object model to XML. +    // +    xml_schema::namespace_infomap map; +    map[""].name = ""; +    map[""].schema = "hello.xsd"; + +    hello (cout, *h, map); +  } +  catch (const xml_schema::exception& e) +  { +    cerr << e << endl; +    return 1; +  } +} +  </pre> + +  <p>First, our application parses an XML document and obtains its +     object model as in the previous example. Then it changes the +     greeting string and adds another entry to the list of names. +     Finally, it serializes the object model back to XML by calling +     the serialization function.</p> + +  <p>The first argument we pass to the serialization function is +     <code>cout</code> which results in the XML being written to +     the standard output for us to inspect. We could have also +     written the result to a file or memory buffer by creating an +     instance of <code>std::ofstream</code> or <code>std::ostringstream</code> +     and passing it instead of <code>cout</code>. The second argument is the +     object model we want to serialize. The final argument is an optional +     namespace information map for our vocabulary. It captures information +     such as namespaces, namespace prefixes to which they should be mapped, +     and schemas associated with these namespaces. If we don't provide +     this argument then generic namespace prefixes (<code>p1</code>, +     <code>p2</code>, etc.) will be automatically assigned to XML namespaces +     and no schema information will be added to the resulting document +     (see <a href="#6">Chapter 6, "Serialization"</a> for details). +     In our case, the prefix (map key) and namespace name are empty +     because our vocabulary does not use XML namespaces.</p> + +  <p>If we now compile and run this application we will see the +     output as shown in the following listing:</p> + +  <pre class="xml"> +<?xml version="1.0"?> +<hello xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +       xsi:noNamespaceSchemaLocation="hello.xsd"> + +  <greeting>Hi</greeting> + +  <name>sun</name> +  <name>moon</name> +  <name>world</name> +  <name>mars</name> + +</hello> +  </pre> + +  <p>We can also create and serialize an object model from scratch +     as shown in the following example:</p> + +  <pre class="c++"> +#include <iostream> +#include <fstream> +#include "hello.hxx" + +using namespace std; + +int +main (int argc, char* argv[]) +{ +  try +  { +    hello_t h ("Hi"); + +    hello_t::name_sequence& ns (h.name ()); + +    ns.push_back ("Jane"); +    ns.push_back ("John"); + +    // Serialize the object model to XML. +    // +    xml_schema::namespace_infomap map; +    map[""].name = ""; +    map[""].schema = "hello.xsd"; + +    std::ofstream ofs (argv[1]); +    hello (ofs, h, map); +  } +  catch (const xml_schema::exception& e) +  { +    cerr << e << endl; +    return 1; +  } +} +  </pre> + +  <p>In this example we used the generated constructor to create +     an instance of type <code>hello_t</code>. To reduce typing, +     we obtained a reference to the name sequence which we then +     used to add a few names. The serialization part is identical +     to the previous example except this time we are writing to +     a file. If we compile and run this program, it produces the +     following XML file:</p> + +  <pre class="xml"> +<?xml version="1.0"?> +<hello xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +       xsi:noNamespaceSchemaLocation="hello.xsd"> + +  <greeting>Hi</greeting> + +  <name>Jane</name> +  <name>John</name> + +</hello> +  </pre> + +  <h2><a name="2.6">2.6 Selecting Naming Convention</a></h2> + +  <p>By default XSD uses the so-called K&R (Kernighan and Ritchie) +     identifier naming convention in the generated code. In this +     convention both type and function names are in lower case and +     words are separated by underscores. If your application code or +     schemas use a different notation, you may want to change the +     naming convention used in the generated code for consistency. +     XSD supports a set of widely-used naming conventions +     that you can select with the <code>--type-naming</code> and +     <code>--function-naming</code> options. You can also further +     refine one of the predefined conventions or create a completely +     custom naming scheme by using the  <code>--*-regex</code> options.</p> + +  <p>As an example, let's assume that our "Hello World" application +     uses the so-called upper-camel-case naming convention for types +     (that is, each word in a type name is capitalized) and the K&R +     convention for function names. Since K&R is the default +     convention for both type and function names, we only need to +     change the type naming scheme:</p> + +  <pre class="terminal"> +$ xsd cxx-tree --type-naming ucc hello.xsd +  </pre> + +  <p>The <code>ucc</code> argument to the <code>--type-naming</code> +     options stands for upper-camel-case. If we now examine the +     generated <code>hello.hxx</code>, we will see the following +     changes compared to the declarations shown in the previous +     sections:</p> + +  <pre class="c++"> +class Hello_t +{ +public: +  // greeting +  // +  typedef xml_schema::String GreetingType; + +  const GreetingType& +  greeting () const; + +  GreetingType& +  greeting (); + +  void +  greeting (const GreetingType& x); + +  // name +  // +  typedef xml_schema::String NameType; +  typedef xsd::sequence<NameType> NameSequence; +  typedef NameSequence::iterator NameIterator; +  typedef NameSequence::const_iterator NameConstIterator; + +  const NameSequence& +  name () const; + +  NameSequence& +  name (); + +  void +  name (const NameSequence& s); + +  // Constructor. +  // +  Hello_t (const GreetingType&); + +  ... + +}; + +std::unique_ptr<Hello_t> +hello (const std::string& uri); + +std::unique_ptr<Hello_t> +hello (std::istream&); +  </pre> + +  <p>Notice that the type names in the <code>xml_schema</code> namespace, +     for example <code>xml_schema::String</code>, now also use the +     upper-camel-case naming convention. The only thing that we may +     be unhappy about in the above code is the <code>_t</code> +     suffix in <code>Hello_t</code>. If we are not in a position +     to change the schema, we can <em>touch-up</em> the <code>ucc</code> +     convention with a custom translation rule using the +     <code>--type-regex</code> option:</p> + +  <pre class="terminal"> +$ xsd cxx-tree --type-naming ucc --type-regex '/ (.+)_t/\u$1/' hello.xsd +  </pre> + +  <p>This results in the following changes to the generated code:</p> + +  <pre class="c++"> +class Hello +{ +public: +  // greeting +  // +  typedef xml_schema::String GreetingType; + +  const GreetingType& +  greeting () const; + +  GreetingType& +  greeting (); + +  void +  greeting (const GreetingType& x); + +  // name +  // +  typedef xml_schema::String NameType; +  typedef xsd::sequence<NameType> NameSequence; +  typedef NameSequence::iterator NameIterator; +  typedef NameSequence::const_iterator NameConstIterator; + +  const NameSequence& +  name () const; + +  NameSequence& +  name (); + +  void +  name (const NameSequence& s); + +  // Constructor. +  // +  Hello (const GreetingType&); + +  ... + +}; + +std::unique_ptr<Hello> +hello (const std::string& uri); + +std::unique_ptr<Hello> +hello (std::istream&); +  </pre> + +  <p>For more detailed information on the <code>--type-naming</code>, +     <code>--function-naming</code>, <code>--type-regex</code>, and +     other <code>--*-regex</code> options refer to the NAMING +     CONVENTION section in the <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD +     Compiler Command Line Manual</a>.</p> + +  <h2><a name="2.7">2.7 Generating Documentation</a></h2> + +  <p>While our object model is quite simple, real-world vocabularies +     can be quite complex with hundreds of types, elements, and +     attributes. For such vocabularies figuring out which types +     provide which member functions by studying the generated +     source code or schemas can be a daunting task. To provide +     application developers with a more accessible way of +     understanding the generated object models, the XSD compiler +     can be instructed to produce source code with documentation +     comments in the Doxygen format. Then the source code can be +     processed with the <a href="http://www.doxygen.org">Doxygen</a> +     documentation system to extract this information and produce +     documentation in various formats. +  </p> + +  <p>In this section we will see how to generate documentation +     for our "Hello World" vocabulary. To showcase the full power +     of the XSD documentation facilities, we will first document +     our schema. The XSD compiler will then transfer +     this information from the schema to the generated code and +     then to the object model documentation. Note that the +     documentation in the schema is not required for XSD to +     generate useful documentation. Below you will find +     our <code>hello.xsd</code> with added documentation:</p> + +  <pre class="xml"> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + +  <xs:complexType name="hello_t"> + +    <xs:annotation> +      <xs:documentation> +        The hello_t type consists of a greeting phrase and a +        collection of names to which this greeting applies. +      </xs:documentation> +    </xs:annotation> + +    <xs:sequence> + +      <xs:element name="greeting" type="xs:string"> +        <xs:annotation> +          <xs:documentation> +            The greeting element contains the greeting phrase +            for this hello object. +          </xs:documentation> +        </xs:annotation> +      </xs:element> + +      <xs:element name="name" type="xs:string" maxOccurs="unbounded"> +        <xs:annotation> +          <xs:documentation> +            The name elements contains names to be greeted. +          </xs:documentation> +        </xs:annotation> +      </xs:element> + +    </xs:sequence> +  </xs:complexType> + +  <xs:element name="hello" type="hello_t"> +    <xs:annotation> +      <xs:documentation> +        The hello element is a root of the Hello XML vocabulary. +        Every conforming document should start with this element. +      </xs:documentation> +    </xs:annotation> +  </xs:element> + +</xs:schema> +  </pre> + +  <p>The first step in obtaining the documentation is to recompile +     our schema with the <code>--generate-doxygen</code> option:</p> + +  <pre class="terminal"> +$ xsd cxx-tree --generate-serialization --generate-doxygen hello.xsd +  </pre> + +  <p>Now the generated <code>hello.hxx</code> file contains comments +     in the Doxygen format. The next step is to process this file +     with the Doxygen documentation system. If your project does +     not use Doxygen then you first need to create a configuration +     file for your project:</p> + +  <pre class="terminal"> +$ doxygen -g hello.doxygen +  </pre> + +  <p>You only need to perform this step once. Now we can generate +     the documentation by executing the following command in the +     directory with the generated source code:</p> + +  <pre class="terminal"> +$ doxygen hello.doxygen +  </pre> + +  <p>While the generated documentation can be useful as is, we can +     go one step further and link (using the Doxygen tags mechanism) +     the documentation for our object model with the documentation +     for the XSD runtime library which defines C++ classes for the +     built-in XML Schema types. This way we can seamlessly browse +     between documentation for the <code>hello_t</code> class which +     is generated by the XSD compiler and the <code>xml_schema::string</code> +     class which is defined in the XSD runtime library. The Doxygen +     configuration file for the XSD runtime is provided with the XSD +     distribution.</p> + +  <p>You can view the result of the steps described in this section +     on the <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/hello/html/annotated.html">Hello +     Example Documentation</a> page.</p> + +  <!-- Chapater 3 --> + + +  <h1><a name="3">3 Overall Mapping Configuration</a></h1> + +  <p>The C++/Tree mapping has a number of configuration parameters that +     determine the overall properties and behavior of the generated code. +     Configuration parameters are specified with the XSD command line +     options. This chapter describes configuration aspects that are most +     commonly encountered by application developers. These include: the +     C++ standard, the character type that is used by the generated code, +     handling of vocabularies that use XML Schema polymorphism, XML Schema +     to C++ namespace mapping, and thread safety. For more ways to configure +     the generated code refer to the +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD +     Compiler Command Line Manual</a>. +  </p> + +  <h2><a name="3.1">3.1 C++ Standard</a></h2> + +  <p>The C++/Tree mapping provides support for ISO/IEC C++ 2011 (C++11) +     and ISO/IEC C++ 1998/2003 (C++98). To select the C++ standard for the +     generated code we use the <code>--std</code> XSD compiler command +     line option. While the majority of the examples in this guide use +     C++11, the document explains the C++11/98 usage difference and so +     they can easily be converted to C++98.</p> + +  <h2><a name="3.2">3.2 Character Type and Encoding</a></h2> + +  <p>The C++/Tree mapping has built-in support for two character types: +    <code>char</code> and <code>wchar_t</code>. You can select the +    character type with the <code>--char-type</code> command line +    option. The default character type is <code>char</code>. The +    character type affects all string and string-based types that +    are used in the mapping. These include the string-based built-in +    XML Schema types, exception types, stream types, etc.</p> + +  <p>Another aspect of the mapping that depends on the character type +     is character encoding. For the <code>char</code> character type +     the default encoding is UTF-8. Other supported encodings are +     ISO-8859-1, Xerces-C++ Local Code Page (LPC), as well as +     custom encodings. You can select which encoding should be used +     in the object model with the <code>--char-encoding</code> command +     line option.</p> + +  <p>For the <code>wchar_t</code> character type the encoding is +     automatically selected between UTF-16 and UTF-32/UCS-4 depending +     on the size of the <code>wchar_t</code> type. On some platforms +     (for example, Windows with Visual C++ and AIX with IBM XL C++) +     <code>wchar_t</code> is 2 bytes long. For these platforms the +     encoding is UTF-16. On other platforms <code>wchar_t</code> is 4 bytes +     long and UTF-32/UCS-4 is used.</p> + +  <p>Note also that the character encoding that is used in the object model +     is independent of the encodings used in input and output XML. In fact, +     all three (object mode, input XML, and output XML) can have different +     encodings.</p> + +  <h2><a name="3.3">3.3 Support for Polymorphism</a></h2> + +  <p>By default XSD generates non-polymorphic code. If your vocabulary +     uses XML Schema polymorphism in the form of <code>xsi:type</code> +     and/or substitution groups, then you will need to compile +     your schemas with the <code>--generate-polymorphic</code> option +     to produce polymorphism-aware code. For more information on +     working with polymorphic object models, refer to +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#2.11">Section 2.11, +     "Mapping for <code>xsi:type</code> and Substitution Groups"</a> in +     the C++/Tree Mapping User Manual.</p> + +  <h2><a name="3.4">3.4 Namespace Mapping</a></h2> + +  <p>XSD maps XML namespaces specified in the <code>targetNamespace</code> +     attribute in XML Schema to one or more nested C++ namespaces. By +     default, a namespace URI is mapped to a sequence of C++ namespace +     names by removing the protocol and host parts and splitting the +     rest into a sequence of names with <code>'/'</code> as the name +     separator.</p> + +  <p>The default mapping of namespace URIs to C++ namespaces +     can be altered using the <code>--namespace-map</code> and +     <code>--namespace-regex</code> compiler options. For example, +     to map namespace URI <code>https://www.codesynthesis.com/my</code> to +     C++ namespace <code>cs::my</code>, we can use the following option:</p> + +  <pre class="terminal"> +--namespace-map https://www.codesynthesis.com/my=cs::my +  </pre> + +  <p>A vocabulary without a namespace is mapped to the global scope. This +     also can be altered with the above options by using an empty name +     for the XML namespace:</p> + +  <pre class="terminal"> +--namespace-map =cs +  </pre> + +  <h2><a name="3.5">3.5 Thread Safety</a></h2> + +  <p>XSD-generated code is thread-safe in the sense that you can +     use different instantiations of the object model in several +     threads concurrently. This is possible due to the generated +     code not relying on any writable global variables. If you need +     to share the same object between several threads then you will +     need to provide some form of synchronization. One approach would +     be to use the generated code customization mechanisms to embed +     synchronization primitives into the generated C++ classes. For more +     information on generated code customization refer to the +     <a href="http://wiki.codesynthesis.com/Tree/Customization_guide">C++/Tree +     Mapping Customization Guide</a>.</p> + +  <p>If you also would like to call parsing and/or serialization +     functions from several threads potentially concurrently, then +     you will need to make sure the Xerces-C++ runtime is initialized +     and terminated only once. The easiest way to do this is to +     initialize/terminate Xerces-C++ from <code>main()</code> when +     there are no threads yet/anymore:</p> + +  <pre class="c++"> +#include <xercesc/util/PlatformUtils.hpp> + +int +main () +{ +  xercesc::XMLPlatformUtils::Initialize (); + +  { +    // Start/terminate threads and parse/serialize here. +  } + +  xercesc::XMLPlatformUtils::Terminate (); +} +  </pre> + +  <p>Because you initialize the Xerces-C++ runtime yourself you should +     also pass the <code>xml_schema::flags::dont_initialize</code> flag +     to parsing and serialization functions. See <a href="#5">Chapter 5, +     "Parsing"</a> and <a href="#6">Chapter 6, "Serialization"</a> for +     more information.</p> + + +  <!-- Chapater 4 --> + + +  <h1><a name="4">4 Working with Object Models</a></h1> + +  <p>As we have seen in the previous chapters, the XSD compiler generates +     a C++ class for each type defined in XML Schema. Together these classes +     constitute an object model for an XML vocabulary. In this chapter we +     will take a closer look at different elements that comprise an +     object model class as well as how to create, access, and modify +     object models.</p> + +  <p>In this and subsequent chapters we will use the following schema +     that describes a collection of person records. We save it in +     <code>people.xsd</code>:</p> + +  <pre class="xml"> +<?xml version="1.0"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + +  <xs:simpleType name="gender_t"> +    <xs:restriction base="xs:string"> +      <xs:enumeration value="male"/> +      <xs:enumeration value="female"/> +    </xs:restriction> +  </xs:simpleType> + +  <xs:complexType name="person_t"> +    <xs:sequence> +      <xs:element name="first-name" type="xs:string"/> +      <xs:element name="middle-name" type="xs:string" minOccurs="0"/> +      <xs:element name="last-name" type="xs:string"/> +      <xs:element name="gender" type="gender_t"/> +      <xs:element name="age" type="xs:short"/> +    </xs:sequence> +    <xs:attribute name="id" type="xs:unsignedInt" use="required"/> +  </xs:complexType> + +  <xs:complexType name="people_t"> +    <xs:sequence> +      <xs:element name="person" type="person_t" maxOccurs="unbounded"/> +    </xs:sequence> +  </xs:complexType> + +  <xs:element name="people" type="people_t"/> + +</xs:schema> +  </pre> + +  <p>A sample XML instance to go along with this schema is saved +     in <code>people.xml</code>:</p> + +  <pre class="xml"> +<?xml version="1.0"?> +<people xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +        xsi:noNamespaceSchemaLocation="people.xsd"> + +  <person id="1"> +    <first-name>John</first-name> +    <last-name>Doe</last-name> +    <gender>male</gender> +    <age>32</age> +  </person> + +  <person id="2"> +    <first-name>Jane</first-name> +    <middle-name>Mary</middle-name> +    <last-name>Doe</last-name> +    <gender>female</gender> +    <age>28</age> +  </person> + +</people> +  </pre> + +  <p>Compiling <code>people.xsd</code> with the XSD compiler results +     in three generated C++ classes: <code>gender_t</code>, +     <code>person_t</code>, and <code>people_t</code>. +     The <code>gender_t</code> class is modelled after the C++ +     <code>enum</code> type. Its definition is presented below:</p> + +  <pre class="c++"> +class gender_t: public xml_schema::string +{ +public: +  enum value +  { +    male, +    female +  }; + +  gender_t (value); +  gender_t (const xml_schema::string&); + +  gender_t& +  operator= (value); + +  operator value () const; +}; +  </pre> + +  <p>The following listing shows how we can use this type:</p> + +  <pre class="c++"> +gender_t m (gender_t::male); +gender_t f ("female"); + +if (m == "female" || f == gender_t::male) +{ +  ... +} + +switch (m) +{ +case gender_t::male: +  { +    ... +  } +case gender_t::female: +  { +    ... +  } +} +  </pre> + +  <p>The other two classes will be examined in detail in the subsequent +     sections.</p> + +  <h2><a name="4.1">4.1 Attribute and Element Cardinalities</a></h2> + +  <p>As we have seen in the previous chapters, XSD generates a different +     set of type definitions and member functions for elements with +     different cardinalities. The C++/Tree mapping divides all the possible +     element and attribute cardinalities into three cardinality classes: +     <em>one</em>, <em>optional</em>, and <em>sequence</em>.</p> + +  <p>The <em>one</em> cardinality class covers all elements that should +     occur exactly once as well as required attributes. In our +     example, the <code>first-name</code>, <code>last-name</code>, +     <code>gender</code>, and <code>age</code> elements as well as +     the <code>id</code> attribute belong to this cardinality class. +     The following code fragment shows type definitions as well as the +     accessor and modifier functions that are generated for the +     <code>gender</code> element in the <code>person_t</code> class:</p> + +  <pre class="c++"> +class person_t +{ +  // gender +  // +  typedef gender_t gender_type; + +  const gender_type& +  gender () const; + +  gender_type& +  gender (); + +  void +  gender (const gender_type&); +}; +  </pre> + +  <p>The <code>gender_type</code> type is an alias for the element's type. +     The first two accessor functions return read-only (constant) and +     read-write references to the element's value, respectively. The +     modifier function sets the new value for the element.</p> + +  <p>The <em>optional</em> cardinality class covers all elements that +     can occur zero or one time as well as optional attributes. In our +     example, the <code>middle-name</code> element belongs to this +     cardinality class. The following code fragment shows the type +     definitions as well as the accessor and modifier functions that +     are generated for this element in the <code>person_t</code> class:</p> + +  <pre class="c++"> +class person_t +{ +  // middle-name +  // +  typedef xml_schema::string middle_name_type; +  typedef xsd::optional<middle_name_type> middle_name_optional; + +  const middle_name_optional& +  middle_name () const; + +  middle_name_optional& +  middle_name (); + +  void +  middle_name (const middle_name_type&); + +  void +  middle_name (const middle_name_optional&); +}; +  </pre> + +  <p>As with the <code>gender</code> element, <code>middle_name_type</code> +     is an alias for the element's type. The <code>middle_name_optional</code> +     type is a container for the element's optional value. It can be queried +     for the presence of the value using the <code>present()</code> function. +     The value itself can be retrieved using the <code>get()</code> +     accessor and set using the <code>set()</code> modifier. The container +     can be reverted to the value not present state with the call to the +     <code>reset()</code> function. The following example shows how we +     can use this container:</p> + +  <pre class="c++"> +person_t::middle_name_optional n ("John"); + +if (n.present ()) +{ +  cout << n.get () << endl; +} + +n.set ("Jane"); +n.reset (); +  </pre> + + +  <p>Unlike the <em>one</em> cardinality class, the accessor functions +     for the <em>optional</em> class return read-only (constant) and +     read-write references to the container instead of the element's +     value directly. The modifier functions set the new value for the +     element.</p> + +  <p>Finally, the <em>sequence</em> cardinality class covers all elements +     that can occur more than once. In our example, the +     <code>person</code> element in the <code>people_t</code> type +     belongs to this cardinality class. The following code fragment shows +     the type definitions as well as the accessor and modifier functions +     that are generated for this element in the <code>people_t</code> +     class:</p> + +  <pre class="c++"> +class people_t +{ +  // person +  // +  typedef person_t person_type; +  typedef xsd::sequence<person_type> person_sequence; +  typedef person_sequence::iterator person_iterator; +  typedef person_sequence::const_iterator person_const_iterator; + +  const person_sequence& +  person () const; + +  person_sequence& +  person (); + +  void +  person (const person_sequence&); +}; +  </pre> + +  <p>Identical to the other cardinality classes, <code>person_type</code> +     is an alias for the element's type. The <code>person_sequence</code> +     type is a sequence container for the element's values. It is based +     on and has the same interface as <code>std::vector</code> and +     therefore can be used in similar ways. The <code>person_iterator</code> +     and <code>person_const_iterator</code> types are read-only +     (constant) and read-write iterators for the <code>person_sequence</code> +     container.</p> + +  <p>Similar to the <em>optional</em> cardinality class, the +     accessor functions for the <em>sequence</em> class return +     read-only (constant) and read-write references to the sequence +     container. The modifier functions copies the entries from +     the passed sequence.</p> + +  <p>C++/Tree is a "flattening" mapping in a sense that many levels of +     nested compositors (<code>choice</code> and <code>sequence</code>), +     all potentially with their own cardinalities, are in the end mapped +     to a flat set of elements with one of the three cardinality classes +     discussed above. While this results in a simple and easy to use API +     for most types, in certain cases, the order of elements in the actual +     XML documents is not preserved once parsed into the object model. To +     overcome this limitation we can mark certain schema types, for which +     content order is not sufficiently preserved, as ordered. For more +     information on this functionality refer to +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#2.8.4">Section +     2.8.4, "Element Order"</a> in the C++/Tree Mapping User Manual.</p> + +  <p>For complex schemas with many levels of nested compositors +     (<code>choice</code> and <code>sequence</code>) it can also +     be hard to deduce the cardinality class of a particular element. +     The generated Doxygen documentation can greatly help with +     this task. For each element and attribute the documentation +     clearly identifies its cardinality class. Alternatively, you +     can study the generated header files to find out the cardinality +     class of a particular attribute or element.</p> + +  <p>In the next sections we will examine how to access and modify +     information stored in an object model using accessor and modifier +     functions described in this section.</p> + +  <h2><a name="4.2">4.2 Accessing the Object Model</a></h2> + +  <p>In this section we will learn how to get to the information +     stored in the object model for our person records vocabulary. +     The following application accesses and prints the contents +     of the <code>people.xml</code> file:</p> + +  <pre class="c++"> +#include <iostream> +#include "people.hxx" + +using namespace std; + +int +main () +{ +  unique_ptr<people_t> ppl (people ("people.xml")); + +  // Iterate over individual person records. +  // +  people_t::person_sequence& ps (ppl->person ()); + +  for (people_t::person_iterator i (ps.begin ()); i != ps.end (); ++i) +  { +    person_t& p (*i); + +    // Print names: first-name and last-name are required elements, +    // middle-name is optional. +    // +    cout << "name:   " << p.first_name () << " "; + +    if (p.middle_name ().present ()) +      cout << p.middle_name ().get () << " "; + +    cout << p.last_name () << endl; + +    // Print gender, age, and id which are all required. +    // +    cout << "gender: " << p.gender () << endl +         << "age:    " << p.age () << endl +         << "id:     " << p.id () << endl +         << endl; +  } +} +  </pre> + +  <p>This code shows common patterns of accessing elements and attributes +     with different cardinality classes. For the sequence element +     (<code>person</code> in <code>people_t</code>) we first obtain a +     reference to the container and then iterate over individual +     records. The values of elements and attributes with the +     <em>one</em> cardinality class (<code>first-name</code>, +     <code>last-name</code>, <code>gender</code>, <code>age</code>, +     and <code>id</code>) can be obtained directly by calling the +     corresponding accessor functions. For the optional element +     <code>middle-name</code> we first check if the value is present +     and only then call <code>get()</code> to retrieve it.</p> + +  <p>Note that when we want to reduce typing by creating a variable +     representing a fragment of the object model that we are currently +     working with (<code>ps</code> and <code>p</code> above), we obtain +     a reference to that fragment instead of making a potentially +     expensive copy. This is generally a good rule to follow when +     creating high-performance applications.</p> + +  <p>If we run the above application on our sample +     <code>people.xml</code>, the output looks as follows:</p> + +  <pre class="terminal"> +name:   John Doe +gender: male +age:    32 +id:     1 + +name:   Jane Mary Doe +gender: female +age:    28 +id:     2 +  </pre> + + +  <h2><a name="4.3">4.3 Modifying the Object Model</a></h2> + +  <p>In this section we will learn how to modify the information +     stored in the object model for our person records vocabulary. +     The following application changes the contents of the +     <code>people.xml</code> file:</p> + +  <pre class="c++"> +#include <iostream> +#include "people.hxx" + +using namespace std; + +int +main () +{ +  unique_ptr<people_t> ppl (people ("people.xml")); + +  // Iterate over individual person records and increment +  // the age. +  // +  people_t::person_sequence& ps (ppl->person ()); + +  for (people_t::person_iterator i (ps.begin ()); i != ps.end (); ++i) +  { +    // Alternative way: i->age ()++; +    // +    i->age (i->age () + 1); +  } + +  // Add middle-name to the first record and remove it from +  // the second. +  // +  person_t& john (ps[0]); +  person_t& jane (ps[1]); + +  john.middle_name ("Mary"); +  jane.middle_name ().reset (); + +  // Add another John record. +  // +  ps.push_back (john); + +  // Serialize the modified object model to XML. +  // +  xml_schema::namespace_infomap map; +  map[""].name = ""; +  map[""].schema = "people.xsd"; + +  people (cout, *ppl, map); +} +  </pre> + +  <p>The first modification the above application performs is iterating +     over person records and incrementing the age value. This code +     fragment shows how to modify the value of a required attribute +     or element. The next modification shows how to set a new value +     for the optional <code>middle-name</code> element as well +     as clear its value. Finally the example adds a copy of the +     John Doe record to the <code>person</code> element sequence.</p> + +  <p>Note that in this case using references for the <code>ps</code>, +     <code>john</code>, and <code>jane</code> variables is no longer +     a performance improvement but a requirement for the application +     to function correctly. If we hadn't used references, all our changes +     would have been made on copies without affecting the object model.</p> + +  <p>If we run the above application on our sample <code>people.xml</code>, +     the output looks as follows:</p> + +  <pre class="xml"> +<?xml version="1.0"?> +<people xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +        xsi:noNamespaceSchemaLocation="people.xsd"> + +  <person id="1"> +    <first-name>John</first-name> +    <middle-name>Mary</middle-name> +    <last-name>Doe</last-name> +    <gender>male</gender> +    <age>33</age> +  </person> + +  <person id="2"> +    <first-name>Jane</first-name> +    <last-name>Doe</last-name> +    <gender>female</gender> +    <age>29</age> +  </person> + +  <person id="1"> +    <first-name>John</first-name> +    <middle-name>Mary</middle-name> +    <last-name>Doe</last-name> +    <gender>male</gender> +    <age>33</age> +  </person> + +</people> +  </pre> + + +  <h2><a name="4.4">4.4 Creating the Object Model from Scratch</a></h2> + +  <p>In this section we will learn how to create a new object model +     for our person records vocabulary. The following application +     recreates the content of the original <code>people.xml</code> +     file:</p> + +  <pre class="c++"> +#include <iostream> +#include "people.hxx" + +using namespace std; + +int +main () +{ +  people_t ppl; +  people_t::person_sequence& ps (ppl.person ()); + +  // Add the John Doe record. +  // +  ps.push_back ( +    person_t ("John",         // first-name +              "Doe",          // last-name +              gender_t::male, // gender +              32,             // age +              1)); + +  // Add the Jane Doe record. +  // +  ps.push_back ( +    person_t ("Jane",           // first-name +              "Doe",            // last-name +              gender_t::female, // gender +              28,               // age +              2));              // id + +  // Add middle name to the Jane Doe record. +  // +  person_t& jane (ps.back ()); +  jane.middle_name ("Mary"); + +  // Serialize the object model to XML. +  // +  xml_schema::namespace_infomap map; +  map[""].name = ""; +  map[""].schema = "people.xsd"; + +  people (cout, ppl, map); +} +  </pre> + +  <p>The only new part in the above application is the calls +     to the <code>people_t</code> and <code>person_t</code> +     constructors. As a general rule, for each C++ class +     XSD generates a constructor with initializers +     for each element and attribute belonging to the <em>one</em> +     cardinality class. For our vocabulary, the following +     constructors are generated:</p> + +  <pre class="c++"> +class person_t +{ +  person_t (const first_name_type&, +            const last_name_type&, +            const gender_type&, +            const age_type&, +            const id_type&); +}; + +class people_t +{ +  people_t (); +}; +  </pre> + +  <p>Note also that we set the <code>middle-name</code> element +     on the Jane Doe record by obtaining a reference to that record +     in the object model and setting the <code>middle-name</code> +     value on it. This is a general rule that should be followed +     in order to obtain the best performance: if possible, +     direct modifications to the object model should be preferred +     to modifications on temporaries with subsequent copying. The +     following code fragment shows a semantically equivalent but +     slightly slower version:</p> + +  <pre class="c++"> +// Add the Jane Doe record. +// +person_t jane ("Jane",           // first-name +               "Doe",            // last-name +               gender_t::female, // gender +               28,               // age +               2);               // id + +jane.middle_name ("Mary"); + +ps.push_back (jane); +  </pre> + +  <p>We can also go one step further to reduce copying and improve +     the performance of our application by using the non-copying +    <code>push_back()</code> function which assumes ownership +     of the passed objects:</p> + +  <pre class="c++"> +// Add the Jane Doe record. C++11 version +// +unique_ptr<person_t> jane_p ( +  new person_t ("Jane",           // first-name +                "Doe",            // last-name +                gender_t::female, // gender +                28,               // age +                2));              // id +ps.push_back (std::move (jane_p)); // assumes ownership + +// Add the John Doe record. C++98 version. +// +auto_ptr<person_t> john_p ( +  new person_t ("John",           // first-name +                "Doe",            // last-name +                gender_t::male,   // gender +                32,               // age +                1)); +ps.push_back (john_p); // assumes ownership +  </pre> + +  <p>For more information on the non-copying modifier functions refer to +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#2.8">Section +     2.8, "Mapping for Local Elements and Attributes"</a> in the C++/Tree Mapping +     User Manual. The above application produces the following output:</p> + +  <pre class="xml"> +<?xml version="1.0" ?> +<people xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +        xsi:noNamespaceSchemaLocation="people.xsd"> + +  <person id="1"> +    <first-name>John</first-name> +    <last-name>Doe</last-name> +    <gender>male</gender> +    <age>32</age> +  </person> + +  <person id="2"> +    <first-name>Jane</first-name> +    <middle-name>Mary</middle-name> +    <last-name>Doe</last-name> +    <gender>female</gender> +    <age>28</age> +  </person> + +</people> +  </pre> + +  <h2><a name="4.5">4.5 Mapping for the Built-in XML Schema Types</a></h2> + +  <p>Our person record vocabulary uses several built-in XML Schema +     types: <code>string</code>, <code>short</code>, and +     <code>unsignedInt</code>. Until now we haven't talked about +     the mapping of built-in XML Schema types to C++ types and how +     to work with them. This section provides an overview +     of the built-in types. For more detailed information refer +     to <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#2.5">Section +     2.5, "Mapping for Built-in Data Types"</a> in the C++/Tree Mapping +     User Manual.</p> + +  <p>In XML Schema, built-in types are defined in the XML Schema namespace. +     By default, the C++/Tree mapping maps this namespace to C++ +     namespace <code>xml_schema</code> (this mapping can be altered +     with the <code>--namespace-map</code> option). The following table +     summarizes the mapping of XML Schema built-in types to C++ types:</p> + +  <!-- border="1" is necessary for html2ps --> +  <table id="builtin" border="1"> +    <tr> +      <th>XML Schema type</th> +      <th>Alias in the <code>xml_schema</code> namespace</th> +      <th>C++ type</th> +    </tr> + +    <tr> +      <th colspan="3">fixed-length integral types</th> +    </tr> +    <!-- 8-bit --> +    <tr> +      <td><code>byte</code></td> +      <td><code>byte</code></td> +      <td><code>signed char</code></td> +    </tr> +    <tr> +      <td><code>unsignedByte</code></td> +      <td><code>unsigned_byte</code></td> +      <td><code>unsigned char</code></td> +    </tr> + +    <!-- 16-bit --> +    <tr> +      <td><code>short</code></td> +      <td><code>short_</code></td> +      <td><code>short</code></td> +    </tr> +    <tr> +      <td><code>unsignedShort</code></td> +      <td><code>unsigned_short</code></td> +      <td><code>unsigned short</code></td> +    </tr> + +    <!-- 32-bit --> +    <tr> +      <td><code>int</code></td> +      <td><code>int_</code></td> +      <td><code>int</code></td> +    </tr> +    <tr> +      <td><code>unsignedInt</code></td> +      <td><code>unsigned_int</code></td> +      <td><code>unsigned int</code></td> +    </tr> + +    <!-- 64-bit --> +    <tr> +      <td><code>long</code></td> +      <td><code>long_</code></td> +      <td><code>long long</code></td> +    </tr> +    <tr> +      <td><code>unsignedLong</code></td> +      <td><code>unsigned_long</code></td> +      <td><code>unsigned long long</code></td> +    </tr> + +    <tr> +      <th colspan="3">arbitrary-length integral types</th> +    </tr> +    <tr> +      <td><code>integer</code></td> +      <td><code>integer</code></td> +      <td><code>long long</code></td> +    </tr> +    <tr> +      <td><code>nonPositiveInteger</code></td> +      <td><code>non_positive_integer</code></td> +      <td><code>long long</code></td> +    </tr> +    <tr> +      <td><code>nonNegativeInteger</code></td> +      <td><code>non_negative_integer</code></td> +      <td><code>unsigned long long</code></td> +    </tr> +    <tr> +      <td><code>positiveInteger</code></td> +      <td><code>positive_integer</code></td> +      <td><code>unsigned long long</code></td> +    </tr> +    <tr> +      <td><code>negativeInteger</code></td> +      <td><code>negative_integer</code></td> +      <td><code>long long</code></td> +    </tr> + +    <tr> +      <th colspan="3">boolean types</th> +    </tr> +    <tr> +      <td><code>boolean</code></td> +      <td><code>boolean</code></td> +      <td><code>bool</code></td> +    </tr> + +    <tr> +      <th colspan="3">fixed-precision floating-point types</th> +    </tr> +    <tr> +      <td><code>float</code></td> +      <td><code>float_</code></td> +      <td><code>float</code></td> +    </tr> +    <tr> +      <td><code>double</code></td> +      <td><code>double_</code></td> +      <td><code>double</code></td> +    </tr> + +    <tr> +      <th colspan="3">arbitrary-precision floating-point types</th> +    </tr> +    <tr> +      <td><code>decimal</code></td> +      <td><code>decimal</code></td> +      <td><code>double</code></td> +    </tr> + +    <tr> +      <th colspan="3">string types</th> +    </tr> +    <tr> +      <td><code>string</code></td> +      <td><code>string</code></td> +      <td>type derived from <code>std::basic_string</code></td> +    </tr> +    <tr> +      <td><code>normalizedString</code></td> +      <td><code>normalized_string</code></td> +      <td>type derived from <code>string</code></td> +    </tr> +    <tr> +      <td><code>token</code></td> +      <td><code>token</code></td> +      <td>type derived from <code>normalized_string</code></td> +    </tr> +    <tr> +      <td><code>Name</code></td> +      <td><code>name</code></td> +      <td>type derived from <code>token</code></td> +    </tr> +    <tr> +      <td><code>NMTOKEN</code></td> +      <td><code>nmtoken</code></td> +      <td>type derived from <code>token</code></td> +    </tr> +    <tr> +      <td><code>NMTOKENS</code></td> +      <td><code>nmtokens</code></td> +      <td>type derived from <code>sequence<nmtoken></code></td> +    </tr> +    <tr> +      <td><code>NCName</code></td> +      <td><code>ncname</code></td> +      <td>type derived from <code>name</code></td> +    </tr> +    <tr> +      <td><code>language</code></td> +      <td><code>language</code></td> +      <td>type derived from <code>token</code></td> +    </tr> + +    <tr> +      <th colspan="3">qualified name</th> +    </tr> +    <tr> +      <td><code>QName</code></td> +      <td><code>qname</code></td> +      <td><code>xml_schema::qname</code></td> +    </tr> + +    <tr> +      <th colspan="3">ID/IDREF types</th> +    </tr> +    <tr> +      <td><code>ID</code></td> +      <td><code>id</code></td> +      <td>type derived from <code>ncname</code></td> +    </tr> +    <tr> +      <td><code>IDREF</code></td> +      <td><code>idref</code></td> +      <td>type derived from <code>ncname</code></td> +    </tr> +    <tr> +      <td><code>IDREFS</code></td> +      <td><code>idrefs</code></td> +      <td>type derived from <code>sequence<idref></code></td> +    </tr> + +    <tr> +      <th colspan="3">URI types</th> +    </tr> +    <tr> +      <td><code>anyURI</code></td> +      <td><code>uri</code></td> +      <td>type derived from <code>std::basic_string</code></td> +    </tr> + +    <tr> +      <th colspan="3">binary types</th> +    </tr> +    <tr> +      <td><code>base64Binary</code></td> +      <td><code>base64_binary</code></td> +      <td><code>xml_schema::base64_binary</code></td> +    </tr> +    <tr> +      <td><code>hexBinary</code></td> +      <td><code>hex_binary</code></td> +      <td><code>xml_schema::hex_binary</code></td> +    </tr> + +    <tr> +      <th colspan="3">date/time types</th> +    </tr> +    <tr> +      <td><code>date</code></td> +      <td><code>date</code></td> +      <td><code>xml_schema::date</code></td> +    </tr> +    <tr> +      <td><code>dateTime</code></td> +      <td><code>date_time</code></td> +      <td><code>xml_schema::date_time</code></td> +    </tr> +    <tr> +      <td><code>duration</code></td> +      <td><code>duration</code></td> +      <td><code>xml_schema::duration</code></td> +    </tr> +    <tr> +      <td><code>gDay</code></td> +      <td><code>gday</code></td> +      <td><code>xml_schema::gday</code></td> +    </tr> +    <tr> +      <td><code>gMonth</code></td> +      <td><code>gmonth</code></td> +      <td><code>xml_schema::gmonth</code></td> +    </tr> +    <tr> +      <td><code>gMonthDay</code></td> +      <td><code>gmonth_day</code></td> +      <td><code>xml_schema::gmonth_day</code></td> +    </tr> +    <tr> +      <td><code>gYear</code></td> +      <td><code>gyear</code></td> +      <td><code>xml_schema::gyear</code></td> +    </tr> +    <tr> +      <td><code>gYearMonth</code></td> +      <td><code>gyear_month</code></td> +      <td><code>xml_schema::gyear_month</code></td> +    </tr> +    <tr> +      <td><code>time</code></td> +      <td><code>time</code></td> +      <td><code>xml_schema::time</code></td> +    </tr> + +    <tr> +      <th colspan="3">entity types</th> +    </tr> +    <tr> +      <td><code>ENTITY</code></td> +      <td><code>entity</code></td> +      <td>type derived from <code>name</code></td> +    </tr> +    <tr> +      <td><code>ENTITIES</code></td> +      <td><code>entities</code></td> +      <td>type derived from <code>sequence<entity></code></td> +    </tr> +  </table> + +  <p>As you can see from the table above a number of built-in +     XML Schema types are mapped to fundamental C++ types such +     as <code>int</code> or <code>bool</code>. All string-based +     XML Schema types are mapped to C++ types that are derived +     from either <code>std::string</code> or +     <code>std::wstring</code>, depending on the character +     type selected. For access and modification purposes these +     types can be treated as <code>std::string</code>. A number +     of built-in types, such as <code>qname</code>, the binary +     types, and the date/time types do not have suitable +     fundamental or standard C++ types to map to. As a result, +     these types are implemented from scratch in the XSD runtime. +     For more information on their interfaces refer to +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#2.5">Section +     2.5, "Mapping for Built-in Data Types"</a> in the C++/Tree Mapping +     User Manual.</p> + + +  <!-- Chapater 5 --> + + +  <h1><a name="5">5 Parsing</a></h1> + +  <p>We have already seen how to parse XML to an object model in this guide +     before. In this chapter we will discuss the parsing topic in more +     detail.</p> + +  <p>By default, the C++/Tree mapping provides a total of 14 overloaded +     parsing functions. They differ in the input methods used to +     read XML as well as the error reporting mechanisms. It is also possible +     to generate types for root elements instead of parsing and serialization +     functions. This may be useful if your XML vocabulary has multiple +     root elements. For more information on element types refer to +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#2.9">Section +     2.9, "Mapping for Global Elements"</a> in the C++/Tree Mapping User +     Manual.</p> + + +  <p>In this section we will discuss the most commonly used versions of +     the parsing functions. For a comprehensive description of parsing +     refer to <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#3">Chapter +     3, "Parsing"</a> in the C++/Tree Mapping User Manual. For the <code>people</code> +     global element from our person record vocabulary, we will concentrate +     on the following three parsing functions:</p> + +  <pre class="c++"> +std::[unique|auto]_ptr<people_t> +people (const std::string& uri, +	xml_schema::flags f = 0, +	const xml_schema::properties& p = xml_schema::properties ()); + +std::[unique|auto]_ptr<people_t> +people (std::istream& is, +        xml_schema::flags f = 0, +        const xml_schema::properties& p = xml_schema::properties ()); + +std::[unique|auto]_ptr<people_t> +people (std::istream& is, +        const std::string& resource_id, +        xml_schema::flags f = 0, +        const xml_schema::properties& p = ::xml_schema::properties ()); +  </pre> + +  <p>The first function parses a local file or a URI. We have already +     used this parsing function in the previous chapters. The second +     and third functions read XML from a standard input stream. The +     last function also requires a resource id. This id is used to +     identify the XML document being parser in diagnostics  messages +     as well as to resolve relative paths to other documents (for example, +     schemas) that might be referenced from the XML document.</p> + +  <p>The last two arguments to all three parsing functions are parsing +     flags and properties. The flags argument provides a number of ways +     to fine-tune the parsing process. The properties argument allows +     to pass additional information to the parsing functions. We will +     use these two arguments in <a href="#5.1">Section 5.1, "XML Schema +     Validation and Searching"</a> below. All three functions return +     the object model as either <code>std::unique_ptr</code> (C++11) or +     <code>std::auto_ptr</code> (C++98), depending on the C++ standard +     selected (<code>--std</code> XSD compiler option). The following +     example shows how we can use the above parsing functions:</p> + +  <pre class="c++"> +using std::unique_ptr; + +// Parse a local file or URI. +// +unique_ptr<people_t> p1 (people ("people.xml")); +unique_ptr<people_t> p2 (people ("http://example.com/people.xml")); + +// Parse a local file via ifstream. +// +std::ifstream ifs ("people.xml"); +unique_ptr<people_t> p3 (people (ifs, "people.xml")); + +// Parse an XML string. +// +std::string str ("..."); // XML in a string. +std::istringstream iss (str); +unique_ptr<people_t> p4 (people (iss)); +  </pre> + + +  <h2><a name="5.1">5.1 XML Schema Validation and Searching</a></h2> + +  <p>The C++/Tree mapping relies on the underlying Xerces-C++ XML +     parser for full XML document validation. The XML Schema +     validation is enabled by default and can be disabled by +     passing the <code>xml_schema::flags::dont_validate</code> +     flag to the parsing functions, for example:</p> + +  <pre class="c++"> +unique_ptr<people_t> p ( +  people ("people.xml", xml_schema::flags::dont_validate)); +  </pre> + +  <p>Even when XML Schema validation is disabled, the generated +     code still performs a number of checks to prevent +     construction of an inconsistent object model (for example, an +     object model with missing required attributes or elements).</p> + +  <p>When XML Schema validation is enabled, the XML parser needs +     to locate a schema to validate against. There are several +     methods to provide the schema location information to the +     parser. The easiest and most commonly used method is to +     specify schema locations in the XML document itself +     with the <code>schemaLocation</code> or +     <code>noNamespaceSchemaLocation</code> attributes, for example:</p> + +  <pre class="xml"> +<?xml version="1.0" ?> +<people xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +        xsi:noNamespaceSchemaLocation="people.xsd" +        xsi:schemaLocation="http://www.w3.org/XML/1998/namespace xml.xsd"> +  </pre> + +  <p>As you might have noticed, we used this method in all the sample XML +     documents presented in this guide up until now. Note that the +     schema locations specified with these two attributes are relative +     to the document's path unless they are absolute URIs (that is +     start with <code>http://</code>, <code>file://</code>, etc.). +     In particular, if you specify just file names as your schema +     locations, as we did above, then the schemas should reside in +     the same directory as the XML document itself.</p> + +  <p>Another method of providing the schema location information +     is via the <code>xml_schema::properties</code> argument, as +     shown in the following example:</p> + +  <pre class="c++"> +xml_schema::properties props; +props.no_namespace_schema_location ("people.xsd"); +props.schema_location ("http://www.w3.org/XML/1998/namespace", "xml.xsd"); + +unique_ptr<people_t> p (people ("people.xml", 0, props)); +  </pre> + +  <p>The schema locations provided with this method overrides +     those specified in the XML document. As with the previous +     method, the schema locations specified this way are +     relative to the document's path unless they are absolute URIs. +     In particular, if you want to use local schemas that are +     not related to the document being parsed, then you will +     need to use the <code>file://</code> URI. The following +     example shows how to use schemas that reside in the current +     working directory:</p> + +  <pre class="c++"> +#include <unistd.h> // getcwd +#include <limits.h> // PATH_MAX + +char cwd[PATH_MAX]; +if (getcwd (cwd, PATH_MAX) == 0) +{ +  // Buffer too small? +} + +xml_schema::properties props; + +props.no_namespace_schema_location ( +  "file:///" + std::string (cwd) + "/people.xsd"); + +props.schema_location ( +  "http://www.w3.org/XML/1998/namespace", +  "file:///" + std::string (cwd) + "/xml.xsd"); + +unique_ptr<people_t> p (people ("people.xml", 0, props)); +  </pre> + +  <p>A third method is the most useful if you are planning to parse +     several XML documents of the same vocabulary. In that case +     it may be beneficial to pre-parse and cache the schemas in +     the XML parser which can then be used to parse all documents +     without re-parsing the schemas. For more information on +     this method refer to the <code>caching</code> example in the +     <code>cxx/tree/</code> directory in the +     <a href="https://cppget.org/xsd-examples">xsd-examples</a> package. +     It is also possible to convert the schemas into a pre-compiled +     binary representation and embed this  representation directly into +     the application executable. With this approach your application can +     perform XML Schema validation without depending on any external +     schema files. For more information on how to achieve this refer to +     the <code>embedded</code> example in the <code>cxx/tree/</code> +     directory in the <a href="https://cppget.org/xsd-examples">xsd-examples</a> +     package.</p> + +  <p>When the XML parser cannot locate a schema for the +     XML document, the validation fails and XML document +     elements and attributes for which schema definitions could +     not be located are reported in the diagnostics. For +     example, if we remove the <code>noNamespaceSchemaLocation</code> +     attribute in <code>people.xml</code> from the previous chapter, +     then we will get the following diagnostics if we try to parse +     this file with validation enabled:</p> + +  <pre class="terminal"> +people.xml:2:63 error: no declaration found for element 'people' +people.xml:4:18 error: no declaration found for element 'person' +people.xml:4:18 error: attribute 'id' is not declared for element 'person' +people.xml:5:17 error: no declaration found for element 'first-name' +people.xml:6:18 error: no declaration found for element 'middle-name' +people.xml:7:16 error: no declaration found for element 'last-name' +people.xml:8:13 error: no declaration found for element 'gender' +people.xml:9:10 error: no declaration found for element 'age' +  </pre> + +  <h2><a name="5.2">5.2 Error Handling</a></h2> + +  <p>The parsing functions offer a number of ways to handle error conditions +     with the C++ exceptions being the most commonly used mechanism. All +     C++/Tree exceptions derive from common base <code>xml_schema::exception</code> +     which in turn derives from <code>std::exception</code>. The easiest +     way to uniformly handle all possible C++/Tree exceptions and print +     detailed information about the error is to catch and print +     <code>xml_schema::exception</code>, as shown in the following +     example:</p> + +  <pre class="c++"> +try +{ +  unique_ptr<people_t> p (people ("people.xml")); +} +catch (const xml_schema::exception& e) +{ +  cerr << e << endl; +} +  </pre> + +  <p>Each individual C++/Tree exception also allows you to obtain +     error details programmatically. For example, the +     <code>xml_schema::parsing</code> exception is thrown when +     the XML parsing and validation in the underlying XML parser +     fails. It encapsulates various diagnostics information +     such as the file name, line and column numbers, as well as the +     error or warning message for each entry. For more information +     about this and other exceptions that can be thrown during +     parsing, refer to +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#3.3">Section +     3.3, "Error Handling"</a> in the C++/Tree Mapping +     User Manual.</p> + +  <p>Note that if you are parsing <code>std::istream</code> on which +     exceptions are not enabled, then you will need to check the +     stream state after the call to the parsing function in order +     to detect any possible stream failures, for example:</p> + +  <pre class="c++"> +std::ifstream ifs ("people.xml"); + +if (ifs.fail ()) +{ +  cerr << "people.xml: unable to open" << endl; +  return 1; +} + +unique_ptr<people_t> p (people (ifs, "people.xml")); + +if (ifs.fail ()) +{ +  cerr << "people.xml: read error" << endl; +  return 1; +} +  </pre> + +  <p>The above example can be rewritten to use exceptions as +     shown below:</p> + +  <pre class="c++"> +try +{ +  std::ifstream ifs; +  ifs.exceptions (std::ifstream::badbit | std::ifstream::failbit); +  ifs.open ("people.xml"); + +  unique_ptr<people_t> p (people (ifs, "people.xml")); +} +catch (const std::ifstream::failure&) +{ +  cerr << "people.xml: unable to open or read error" << endl; +  return 1; +} +  </pre> + + +  <!-- Chapater 6 --> + + +  <h1><a name="6">6 Serialization</a></h1> + +  <p>We have already seen how to serialize an object model back to XML +     in this guide before. In this chapter we will discuss the +     serialization topic in more detail.</p> + +  <p>By default, the C++/Tree mapping provides a total of 8 overloaded +     serialization functions. They differ in the output methods used to write +     XML as well as the error reporting mechanisms. It is also possible to +     generate types for root elements instead of parsing and serialization +     functions. This may be useful if your XML vocabulary has multiple +     root elements. For more information on element types refer to +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#2.9">Section +     2.9, "Mapping for Global Elements"</a> in the C++/Tree Mapping User +     Manual.</p> + + +  <p>In this section we will discuss the most commonly +     used version of serialization functions. For a comprehensive description +     of serialization refer to +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#4">Chapter +     4, "Serialization"</a> in the C++/Tree Mapping User Manual. For the +     <code>people</code> global element from our person record vocabulary, +     we will concentrate on the following serialization function:</p> + +  <pre class="c++"> +void +people (std::ostream& os, +        const people_t& x, +        const xml_schema::namespace_infomap& map = +          xml_schema::namespace_infomap (), +        const std::string& encoding = "UTF-8", +        xml_schema::flags f = 0); +  </pre> + +  <p>This function serializes the object model passed as the second +     argument to the standard output stream passed as the first +     argument. The third argument is a namespace information map +     which we will discuss in more detail in the next section. +     The fourth argument is a character encoding that the resulting +     XML document should be in. Possible valid values for this +     argument are "US-ASCII", "ISO8859-1", "UTF-8", "UTF-16BE", +     "UTF-16LE", "UCS-4BE", and "UCS-4LE". Finally, the flags +     argument allows fine-tuning of the serialization process. +     The following example shows how we can use the above serialization +     function:</p> + +  <pre class="c++"> +people_t& p = ... + +xml_schema::namespace_infomap map; +map[""].schema = "people.xsd"; + +// Serialize to stdout. +// +people (std::cout, p, map); + +// Serialize to a file. +// +std::ofstream ofs ("people.xml"); +people (ofs, p, map); + +// Serialize to a string. +// +std::ostringstream oss; +people (oss, p, map); +std::string xml (oss.str ()); +  </pre> + + +  <h2><a name="6.1">6.1 Namespace and Schema Information</a></h2> + +  <p>While XML serialization can be done just from the object +     model alone, it is often desirable to assign meaningful +     prefixes to XML namespaces used in the vocabulary as +     well as to provide the schema location information. +     This is accomplished by passing the namespace information +     map to the serialization function. The key in this map is +     a namespace prefix that should be assigned to an XML namespace +     specified in the <code>name</code> variable of the +     map value. You can also assign an optional schema location for +     this namespace in the <code>schema</code> variable. Based +     on each key-value entry in this map, the serialization +     function adds two attributes to the resulting XML document: +     the namespace-prefix mapping attribute and schema location +     attribute. The empty prefix indicates that the namespace +     should be mapped without a prefix. For example, the following +     map:</p> + +  <pre class="c++"> +xml_schema::namespace_infomap map; + +map[""].name = "http://www.example.com/example"; +map[""].schema = "example.xsd"; + +map["x"].name = "http://www.w3.org/XML/1998/namespace"; +map["x"].schema = "xml.xsd"; +  </pre> + +  <p>Results in the following XML document:</p> + +  <pre class="xml"> +<?xml version="1.0" ?> +<example +  xmlns="http://www.example.com/example" +  xmlns:x="http://www.w3.org/XML/1998/namespace" +  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +  xsi:schemaLocation="http://www.example.com/example example.xsd +                      http://www.w3.org/XML/1998/namespace xml.xsd"> +  </pre> + +  <p>The empty namespace indicates that the vocabulary has no target +     namespace. For example, the following map results in only the +     <code>noNamespaceSchemaLocation</code> attribute being added:</p> + +  <pre class="c++"> +xml_schema::namespace_infomap map; + +map[""].name = ""; +map[""].schema = "example.xsd"; +  </pre> + +  <h2><a name="6.2">6.2 Error Handling</a></h2> + +  <p>Similar to the parsing functions, the serialization functions offer a +     number of ways to handle error conditions with the C++ exceptions being +     the most commonly used mechanisms. As with parsing, the easiest way to +     uniformly handle all possible serialization exceptions and print +     detailed information about the error is to catch and print +     <code>xml_schema::exception</code>:</p> + + <pre class="c++"> +try +{ +  people_t& p = ... + +  xml_schema::namespace_infomap map; +  map[""].schema = "people.xsd"; + +  people (std::cout, p, map)); +} +catch (const xml_schema::exception& e) +{ +  cerr << e << endl; +} +  </pre> + +  <p>The most commonly encountered serialization exception is +     <code>xml_schema::serialization</code>. It is thrown +     when the XML serialization in the underlying XML writer +     fails. It encapsulates various diagnostics information +     such as the file name, line and column numbers, as well as the +     error or warning message for each entry. For more information +     about this and other exceptions that can be thrown during +     serialization, refer to +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#4.4">Section +     4.4, "Error Handling"</a> in the C++/Tree Mapping +     User Manual.</p> + +  <p>Note that if you are serializing to <code>std::ostream</code> on +     which exceptions are not enabled, then you will need to check the +     stream state after the call to the serialization function in order +     to detect any possible stream failures, for example:</p> + +  <pre class="c++"> +std::ofstream ofs ("people.xml"); + +if (ofs.fail ()) +{ +  cerr << "people.xml: unable to open" << endl; +  return 1; +} + +people (ofs, p, map)); + +if (ofs.fail ()) +{ +  cerr << "people.xml: write error" << endl; +  return 1; +} +  </pre> + +  <p>The above example can be rewritten to use exceptions as +     shown below:</p> + +  <pre class="c++"> +try +{ +  std::ofstream ofs; +  ofs.exceptions (std::ofstream::badbit | std::ofstream::failbit); +  ofs.open ("people.xml"); + +  people (ofs, p, map)); +} +catch (const std::ofstream::failure&) +{ +  cerr << "people.xml: unable to open or write error" << endl; +  return 1; +} +  </pre> + +  </div> +</div> + +</body> +</html> diff --git a/doc/cxx/tree/manual/index.xhtml b/doc/cxx/tree/manual/index.xhtml new file mode 100644 index 0000000..f455bff --- /dev/null +++ b/doc/cxx/tree/manual/index.xhtml @@ -0,0 +1,6826 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> + +<head> +  <title>C++/Tree Mapping User Manual</title> + +  <meta name="copyright" content="© 2005-2023 Code Synthesis"/> +  <meta name="keywords" content="xsd,xml,schema,c++,mapping,data,binding,tree,serialization,guide,manual,examples"/> +  <meta name="description" content="C++/Tree Mapping User Manual"/> +  <meta name="revision" content="4.1.0"/> + +  <link rel="stylesheet" type="text/css" href="../../../default.css" /> + +<style type="text/css"> +  pre { +    padding    : 0 0 0 0em; +    margin     : 0em 0em 0em 0; + +    font-size  : 102% +  } + +  body { +    min-width: 48em; +  } + +  h1 { +    font-weight: bold; +    font-size: 200%; +  } + +  h2 { +    font-weight : bold; +    font-size   : 150%; + +    padding-top : 0.8em; +  } + +  h3 { +    font-size   : 130%; +    padding-top : 0.8em; +  } + +  /* Adjust indentation for three levels. */ +  #container { +    max-width: 48em; +  } + +  #content { +    padding: 0 0.1em 0 4em; +    /*background-color: red;*/ +  } + +  #content h1 { +    margin-left: -2.06em; +  } + +  #content h2 { +    margin-left: -1.33em; +  } + +  /* Title page */ + +  #titlepage { +    padding: 2em 0 1em 0; +    border-bottom: 1px solid black; +  } + +  #titlepage #title { +    font-weight: bold; +    font-size: 200%; +    text-align: center; +    padding: 1em 0 2em 0; +  } + +  /* Lists */ +  ul.list li { +    padding-top      : 0.3em; +    padding-bottom   : 0.3em; +  } + + +  /* Built-in table */ +  #builtin { +    margin: 2em 0 2em 0; + +    border-collapse   : collapse; +    border            : 1px solid; +    border-color      : #000000; + +    font-size        : 11px; +    line-height      : 14px; +  } + +  #builtin th, #builtin td { +    border: 1px solid; +    padding           : 0.9em 0.9em 0.7em 0.9em; +  } + +  #builtin th { +    background : #cde8f6; +  } + +  #builtin td { +    text-align: left; +  } + + +  /* default-fixed */ +  #default-fixed { +    margin: 2em 0 2em 0; + +    border-collapse   : collapse; +    border            : 1px solid; +    border-color      : #000000; + +    font-size        : 11px; +    line-height      : 14px; +  } + +  #default-fixed th, #default-fixed td { +    border: 1px solid; +    padding           : 0.9em 0.9em 0.7em 0.9em; +  } + +  #default-fixed th { +    background : #cde8f6; +  } + +  #default-fixed td { +    text-align: center; +  } + + +  /*  */ +  dl dt { +    padding   : 0.8em 0 0 0; +  } + + +  /* TOC */ +  table.toc { +    border-style      : none; +    border-collapse   : separate; +    border-spacing    : 0; + +    margin            : 0.2em 0 0.2em 0; +    padding           : 0 0 0 0; +  } + +  table.toc tr { +    padding           : 0 0 0 0; +    margin            : 0 0 0 0; +  } + +  table.toc * td, table.toc * th { +    border-style      : none; +    margin            : 0 0 0 0; +    vertical-align    : top; +  } + +  table.toc * th { +    font-weight       : normal; +    padding           : 0em 0.1em 0em 0; +    text-align        : left; +    white-space       : nowrap; +  } + +  table.toc * table.toc th { +    padding-left      : 1em; +  } + +  table.toc * td { +    padding           : 0em 0 0em 0.7em; +    text-align        : left; +  } +</style> + + +</head> + +<body> +<div id="container"> +  <div id="content"> + +  <div class="noprint"> + +  <div id="titlepage"> +    <div id="title">C++/Tree Mapping User Manual</div> + +  <p>Copyright © 2005-2023 Code Synthesis.</p> + +  <p>Permission is granted to copy, distribute and/or modify this +     document under the terms of the +     <a href="https://www.codesynthesis.com/licenses/fdl-1.2.txt">GNU Free +     Documentation License, version 1.2</a>; with no Invariant Sections, +     no Front-Cover Texts and no Back-Cover Texts. +  </p> + +  <p>This document is available in the following formats: +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/index.xhtml">XHTML</a>, +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/cxx-tree-manual.pdf">PDF</a>, and +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/cxx-tree-manual.ps">PostScript</a>.</p> +  </div> + +  <h1>Table of Contents</h1> + +  <table class="toc"> +    <tr> +      <th></th><td><a href="#0">Preface</a> +        <table class="toc"> +          <tr><th></th><td><a href="#0.1">About This Document</a></td></tr> +	  <tr><th></th><td><a href="#0.2">More Information</a></td></tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>1</th><td><a href="#1">Introduction</a></td> +    </tr> + +    <tr> +      <th>2</th><td><a href="#2">C++/Tree Mapping</a> +        <table class="toc"> +          <tr> +            <th>2.1</th><td><a href="#2.1">Preliminary Information</a> +              <table class="toc"> +		<tr><th>2.1.1</th><td><a href="#2.1.1">C++ Standard</a></td></tr> +                <tr><th>2.1.2</th><td><a href="#2.1.2">Identifiers</a></td></tr> +                <tr><th>2.1.3</th><td><a href="#2.1.3">Character Type and Encoding</a></td></tr> +                <tr><th>2.1.4</th><td><a href="#2.1.4">XML Schema Namespace</a></td></tr> +		<tr><th>2.1.5</th><td><a href="#2.1.5">Anonymous Types</a></td></tr> +              </table> +            </td> +          </tr> +          <tr> +            <th>2.2</th><td><a href="#2.2">Error Handling</a> +              <table class="toc"> +                <tr><th>2.2.1</th><td><a href="#2.2.1"><code>xml_schema::duplicate_id</code></a></td></tr> +              </table> +            </td> +          </tr> +          <tr> +            <th>2.3</th><td><a href="#2.3">Mapping for <code>import</code> and <code>include</code></a> +              <table class="toc"> +                <tr><th>2.3.1</th><td><a href="#2.3.1">Import</a></td></tr> +		<tr><th>2.3.2</th><td><a href="#2.3.2">Inclusion with Target Namespace</a></td></tr> +		<tr><th>2.3.3</th><td><a href="#2.3.3">Inclusion without Target Namespace</a></td></tr> +              </table> +            </td> +          </tr> +          <tr> +            <th>2.4</th><td><a href="#2.4">Mapping for Namespaces</a></td> +          </tr> +          <tr> +            <th>2.5</th><td><a href="#2.5">Mapping for Built-in Data Types</a> +              <table class="toc"> +                <tr><th>2.5.1</th><td><a href="#2.5.1">Inheritance from Built-in Data Types</a></td></tr> +                <tr><th>2.5.2</th><td><a href="#2.5.2">Mapping for <code>anyType</code></a></td></tr> +                <tr><th>2.5.3</th><td><a href="#2.5.3">Mapping for <code>anySimpleType</code></a></td></tr> +                <tr><th>2.5.4</th><td><a href="#2.5.4">Mapping for <code>QName</code></a></td></tr> +                <tr><th>2.5.5</th><td><a href="#2.5.5">Mapping for <code>IDREF</code></a></td></tr> +		<tr><th>2.5.6</th><td><a href="#2.5.6">Mapping for <code>base64Binary</code> and <code>hexBinary</code></a></td></tr> +		<tr><th>2.5.7</th><td><a href="#2.5.7">Time Zone Representation</a></td></tr> +		<tr><th>2.5.8</th><td><a href="#2.5.8">Mapping for <code>date</code></a></td></tr> +		<tr><th>2.5.9</th><td><a href="#2.5.9">Mapping for <code>dateTime</code></a></td></tr> +		<tr><th>2.5.10</th><td><a href="#2.5.10">Mapping for <code>duration</code></a></td></tr> +		<tr><th>2.5.11</th><td><a href="#2.5.11">Mapping for <code>gDay</code></a></td></tr> +		<tr><th>2.5.12</th><td><a href="#2.5.12">Mapping for <code>gMonth</code></a></td></tr> +		<tr><th>2.5.13</th><td><a href="#2.5.13">Mapping for <code>gMonthDay</code></a></td></tr> +		<tr><th>2.5.14</th><td><a href="#2.5.14">Mapping for <code>gYear</code></a></td></tr> +		<tr><th>2.5.15</th><td><a href="#2.5.15">Mapping for <code>gYearMonth</code></a></td></tr> +		<tr><th>2.5.16</th><td><a href="#2.5.16">Mapping for <code>time</code></a></td></tr> +              </table> +            </td> +          </tr> +          <tr> +            <th>2.6</th><td><a href="#2.6">Mapping for Simple Types</a> +              <table class="toc"> +                <tr><th>2.6.1</th><td><a href="#2.6.1">Mapping for Derivation by Restriction</a></td></tr> +                <tr><th>2.6.2</th><td><a href="#2.6.2">Mapping for Enumerations</a></td></tr> +                <tr><th>2.6.3</th><td><a href="#2.6.3">Mapping for Derivation by List</a></td></tr> +                <tr><th>2.6.4</th><td><a href="#2.6.4">Mapping for Derivation by Union</a></td></tr> +              </table> +            </td> +          </tr> +          <tr> +            <th>2.7</th><td><a href="#2.7">Mapping for Complex Types</a> +              <table class="toc"> +	        <tr><th>2.7.1</th><td><a href="#2.7.1">Mapping for Derivation by Extension</a></td></tr> +                <tr><th>2.7.2</th><td><a href="#2.7.2">Mapping for Derivation by Restriction</a></td></tr> +              </table> +            </td> +          </tr> +          <tr> +            <th>2.8</th><td><a href="#2.8">Mapping for Local Elements and Attributes</a> +              <table class="toc"> +	        <tr><th>2.8.1</th><td><a href="#2.8.1">Mapping for Members with the One Cardinality Class</a></td></tr> +	        <tr><th>2.8.2</th><td><a href="#2.8.2">Mapping for Members with the Optional Cardinality Class</a></td></tr> +	        <tr><th>2.8.3</th><td><a href="#2.8.3">Mapping for Members with the Sequence Cardinality Class</a></td></tr> +		<tr><th>2.8.4</th><td><a href="#2.8.4">Element Order</a></td></tr> +              </table> +            </td> +          </tr> +          <tr> +            <th>2.9</th><td><a href="#2.9">Mapping for Global Elements</a> +              <table class="toc"> +	        <tr><th>2.9.1</th><td><a href="#2.9.1">Element Types</a></td></tr> +	        <tr><th>2.9.2</th><td><a href="#2.9.2">Element Map</a></td></tr> +              </table> +            </td> +          </tr> +          <tr> +            <th>2.10</th><td><a href="#2.10">Mapping for Global Attributes</a></td> +          </tr> +          <tr> +            <th>2.11</th><td><a href="#2.11">Mapping for <code>xsi:type</code> and Substitution Groups</a></td> +          </tr> +          <tr> +            <th>2.12</th><td><a href="#2.12">Mapping for <code>any</code> and <code>anyAttribute</code></a> +              <table class="toc"> +	        <tr><th>2.12.1</th><td><a href="#2.12.1">Mapping for <code>any</code> with the One Cardinality Class</a></td></tr> +	        <tr><th>2.12.2</th><td><a href="#2.12.2">Mapping for <code>any</code> with the Optional Cardinality Class</a></td></tr> +	        <tr><th>2.12.3</th><td><a href="#2.12.3">Mapping for <code>any</code> with the Sequence Cardinality Class</a></td></tr> +		<tr><th>2.12.4</th><td><a href="#2.12.4">Element Wildcard Order</a></td></tr> +		<tr><th>2.12.5</th><td><a href="#2.12.5">Mapping for <code>anyAttribute</code></a></td></tr> +              </table> +            </td> +          </tr> +	  <tr> +            <th>2.13</th><td><a href="#2.13">Mapping for Mixed Content Models</a></td> +          </tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>3</th><td><a href="#3">Parsing</a> +        <table class="toc"> +          <tr> +            <th>3.1</th><td><a href="#3.1">Initializing the Xerces-C++ Runtime</a></td> +          </tr> +          <tr> +            <th>3.2</th><td><a href="#3.2">Flags and Properties</a></td> +          </tr> +          <tr> +            <th>3.3</th><td><a href="#3.3">Error Handling</a> +              <table class="toc"> +	        <tr><th>3.3.1</th><td><a href="#3.3.1"><code>xml_schema::parsing</code></a></td></tr> +	        <tr><th>3.3.2</th><td><a href="#3.3.2"><code>xml_schema::expected_element</code></a></td></tr> +	        <tr><th>3.3.3</th><td><a href="#3.3.3"><code>xml_schema::unexpected_element</code></a></td></tr> +	        <tr><th>3.3.4</th><td><a href="#3.3.4"><code>xml_schema::expected_attribute</code></a></td></tr> +	        <tr><th>3.3.5</th><td><a href="#3.3.5"><code>xml_schema::unexpected_enumerator</code></a></td></tr> +		<tr><th>3.3.6</th><td><a href="#3.3.6"><code>xml_schema::expected_text_content</code></a></td></tr> +	        <tr><th>3.3.7</th><td><a href="#3.3.7"><code>xml_schema::no_type_info</code></a></td></tr> +	        <tr><th>3.3.8</th><td><a href="#3.3.8"><code>xml_schema::not_derived</code></a></td></tr> +		<tr><th>3.3.9</th><td><a href="#3.3.9"><code>xml_schema::not_prefix_mapping</code></a></td></tr> +              </table> +            </td> +          </tr> +          <tr> +            <th>3.4</th><td><a href="#3.4">Reading from a Local File or URI</a></td> +          </tr> +          <tr> +            <th>3.5</th><td><a href="#3.5">Reading from <code>std::istream</code></a></td> +          </tr> +          <tr> +            <th>3.6</th><td><a href="#3.6">Reading from <code>xercesc::InputSource</code></a></td> +          </tr> +          <tr> +            <th>3.7</th><td><a href="#3.7">Reading from DOM</a></td> +          </tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>4</th><td><a href="#4">Serialization</a> +        <table class="toc"> +          <tr> +            <th>4.1</th><td><a href="#4.1">Initializing the Xerces-C++ Runtime</a></td> +          </tr> +          <tr> +            <th>4.2</th><td><a href="#4.2">Namespace Infomap and Character Encoding</a></td> +          </tr> +          <tr> +            <th>4.3</th><td><a href="#4.3">Flags</a></td> +          </tr> +          <tr> +            <th>4.4</th><td><a href="#4.4">Error Handling</a> +              <table class="toc"> +	        <tr><th>4.4.1</th><td><a href="#4.4.1"><code>xml_schema::serialization</code></a></td></tr> +		<tr><th>4.4.2</th><td><a href="#4.4.2"><code>xml_schema::unexpected_element</code></a></td></tr> +		<tr><th>4.4.3</th><td><a href="#4.4.3"><code>xml_schema::no_type_info</code></a></td></tr> +              </table> +            </td> +          </tr> +          <tr> +            <th>4.5</th><td><a href="#4.5">Serializing to <code>std::ostream</code></a></td> +          </tr> +          <tr> +            <th>4.6</th><td><a href="#4.6">Serializing to <code>xercesc::XMLFormatTarget</code></a></td> +          </tr> +          <tr> +            <th>4.7</th><td><a href="#4.7">Serializing to DOM</a></td> +          </tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>5</th><td><a href="#5">Additional Functionality</a> +        <table class="toc"> +          <tr> +            <th>5.1</th><td><a href="#5.1">DOM Association</a></td> +          </tr> +          <tr> +            <th>5.2</th><td><a href="#5.2">Binary Serialization</a></td> +          </tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th></th><td><a href="#A">Appendix A — Default and Fixed Values</a></td> +    </tr> + +  </table> +  </div> + +  <h1><a name="0">Preface</a></h1> + +  <h2><a name="0.1">About This Document</a></h2> + +  <p>This document describes the mapping of W3C XML Schema +     to the C++ programming language as implemented by +     <a href="https://www.codesynthesis.com/products/xsd">CodeSynthesis +     XSD</a> - an XML Schema to C++ data binding compiler. The mapping +     represents information stored in XML instance documents as a +     statically-typed, tree-like in-memory data structure and is +     called C++/Tree. +  </p> + +  <p>Revision 4.1.0<br/> <!-- Remember to change revision in other places --> +     This revision of the manual describes the C++/Tree +     mapping as implemented by CodeSynthesis XSD version 4.1.0. +  </p> + +  <p>This document is available in the following formats: +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/index.xhtml">XHTML</a>, +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/cxx-tree-manual.pdf">PDF</a>, and +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/cxx-tree-manual.ps">PostScript</a>.</p> + +  <h2><a name="0.2">More Information</a></h2> + +  <p>Beyond this manual, you may also find the following sources of +     information useful:</p> + +  <ul class="list"> +    <li><a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/guide/">C++/Tree +        Mapping Getting Started Guide</a></li> + +    <li><a href="http://wiki.codesynthesis.com/Tree/Customization_guide">C++/Tree +        Mapping Customization Guide</a></li> + +    <li><a href="http://wiki.codesynthesis.com/Tree/FAQ">C++/Tree +        Mapping Frequently Asked Questions (FAQ)</a></li> + +    <li><a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD +        Compiler Command Line Manual</a></li> + +    <li>The <code>cxx/tree/</code> directory in the +        <a href="https://cppget.org/xsd-examples">xsd-examples</a> package +        contains a collection of examples and a README file with an overview +        of each example.</li> + +    <li>The <code>README</code> file in the +        <a href="https://cppget.org/xsd-examples">xsd-examples</a> package +        explains how to build the examples.</li> + +    <li>The <a href="https://www.codesynthesis.com/mailman/listinfo/xsd-users">xsd-users</a> +        mailing list is a place to ask questions. Furthermore the +        <a href="https://www.codesynthesis.com/pipermail/xsd-users/">archives</a> +        may already have answers to some of your questions.</li> +  </ul> + + +  <h1><a name="1">1 Introduction</a></h1> + +  <p>C++/Tree is a W3C XML Schema to C++ mapping that represents the +     data stored in XML as a statically-typed, vocabulary-specific +     object model. Based on a formal description of an XML vocabulary +     (schema), the C++/Tree mapping produces a tree-like data structure +     suitable for in-memory processing as well as XML parsing and +     serialization code.</p> + +  <p>A typical application that processes XML documents usually +     performs the following three steps: it first reads (parses) an XML +     instance document to an object model, it then performs +     some useful computations on that model which may involve +     modification of the model, and finally it may write (serialize) +     the modified object model back to XML. +  </p> + +  <p>The C++/Tree mapping consists of C++ types that represent the +     given vocabulary (<a href="#2">Chapter 2, "C++/Tree Mapping"</a>), +     a set of parsing functions that convert XML documents to +     a tree-like in-memory data structure (<a href="#3">Chapter 3, +     "Parsing"</a>), and a set of serialization functions that convert +     the object model back to XML (<a href="#4">Chapter 4, +     "Serialization"</a>). Furthermore, the mapping provides a number +     of additional features, such as DOM association and binary +     serialization, that can be useful in some applications +     (<a href="#5">Chapter 5, "Additional Functionality"</a>). +  </p> + + +  <!-- Chapter 2 --> + + +  <h1><a name="2">2 C++/Tree Mapping</a></h1> + +  <h2><a name="2.1">2.1 Preliminary Information</a></h2> + +  <h3><a name="2.1.1">2.1.1 C++ Standard</a></h3> + +  <p>The C++/Tree mapping provides support for ISO/IEC C++ 2011 (C++11) +     and ISO/IEC C++ 1998/2003 (C++98). To select the C++ standard for the +     generated code we use the <code>--std</code> XSD compiler command +     line option. While the majority of the examples in this guide use +     C++11, the document explains the C++11/98 usage difference and so +     they can easily be converted to C++98.</p> + +  <h3><a name="2.1.2">2.1.2 Identifiers</a></h3> + +  <p>XML Schema names may happen to be reserved C++ keywords or contain +     characters that are illegal in C++ identifiers. To avoid C++ compilation +     problems, such names are changed (escaped) when mapped to C++. If an +     XML Schema name is a C++ keyword, the "_" suffix is added to it. All +     character of an XML Schema name that are not allowed in C++ identifiers +     are replaced with "_". +  </p> + +  <p>For example, XML Schema name <code>try</code> will be mapped to +     C++ identifier <code>try_</code>. Similarly, XML Schema name +     <code>strange.na-me</code> will be mapped to C++ identifier +     <code>strange_na_me</code>. +  </p> + +  <p>Furthermore, conflicts between type names and function names in the +     same scope are resolved using name escaping. Such conflicts include +     both a global element (which is mapped to a set of parsing and/or +     serialization functions or element types, see <a href="#2.9">Section +     2.9, "Mapping for Global Elements"</a>) and a global type sharing the +     same name as well as a local element or attribute inside a type having +     the same name as the type itself.</p> + +  <p>For example, if we had a global type <code>catalog</code> +     and a global element with the same name then the type would be +     mapped to a C++ class with name <code>catalog</code> while the +     parsing functions corresponding to the global element would have +     their names escaped as <code>catalog_</code>. +  </p> + +  <p>By default the mapping uses the so-called K&R (Kernighan and +     Ritchie) identifier naming convention which is also used throughout +     this manual. In this convention both type and function names are in +     lower case and words are separated by underscores. If your application +     code or schemas use a different notation, you may want to change the +     naming convention used by the mapping for consistency. +     The compiler supports a set of widely-used naming conventions +     that you can select with the <code>--type-naming</code> and +     <code>--function-naming</code> options. You can also further +     refine one of the predefined conventions or create a completely +     custom naming scheme by using the  <code>--*-regex</code> options. +     For more detailed information on these options refer to the NAMING +     CONVENTION section in the <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD +     Compiler Command Line Manual</a>.</p> + +  <h3><a name="2.1.3">2.1.3 Character Type and Encoding</a></h3> + +  <p>The code that implements the mapping, depending on the +     <code>--char-type</code>  option, is generated using either +     <code>char</code> or <code>wchar_t</code> as the character +     type. In this document code samples use symbol <code>C</code> +     to refer to the character type you have selected when translating +     your schemas, for example <code>std::basic_string<C></code>. +  </p> + +  <p>Another aspect of the mapping that depends on the character type +     is character encoding. For the <code>char</code> character type +     the default encoding is UTF-8. Other supported encodings are +     ISO-8859-1, Xerces-C++ Local Code Page (LPC), as well as +     custom encodings and can be selected with the +     <code>--char-encoding</code> command line option.</p> + +  <p>For the <code>wchar_t</code> character type the encoding is +     automatically selected between UTF-16 and UTF-32/UCS-4 depending +     on the size of the <code>wchar_t</code> type. On some platforms +     (for example, Windows with Visual C++ and AIX with IBM XL C++) +     <code>wchar_t</code> is 2 bytes long. For these platforms the +     encoding is UTF-16. On other platforms <code>wchar_t</code> is 4 bytes +     long and UTF-32/UCS-4 is used.</p> + +  <h3><a name="2.1.4">2.1.4 XML Schema Namespace</a></h3> + +  <p>The mapping relies on some predefined types, classes, and functions +     that are logically defined in the XML Schema namespace reserved for +     the XML Schema language (<code>http://www.w3.org/2001/XMLSchema</code>). +     By default, this namespace is mapped to C++ namespace +     <code>xml_schema</code>. It is automatically accessible +     from a C++ compilation unit that includes a header file generated +     from an XML Schema definition. +  </p> + +  <p>Note that, if desired, the default mapping of this namespace can be +     changed as described in <a href="#2.4">Section 2.4, "Mapping for +     Namespaces"</a>. +  </p> + + +  <h3><a name="2.1.5">2.1.5 Anonymous Types</a></h3> + +  <p>For the purpose of code generation, anonymous types defined in +     XML Schema are automatically assigned names that are derived +     from enclosing attributes and elements. Otherwise, such types +     follows standard mapping rules for simple and complex type +     definitions (see <a href="#2.6">Section 2.6, "Mapping for Simple Types"</a> +     and <a href="#2.7">Section 2.7, "Mapping for Complex Types"</a>). +     For example, in the following schema fragment: +  </p> + +  <pre class="xml"> +<element name="object"> +  <complexType> +    ... +  </complexType> +</element> +  </pre> + +  <p>The anonymous type defined inside element <code>object</code> will +     be given name <code>object</code>. The compiler has a number of +     options that control the process of anonymous type naming. For more +     information refer to the <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD +     Compiler Command Line Manual</a>.</p> + + +  <h2><a name="2.2">2.2 Error Handling</a></h2> + +  <p>The mapping uses the C++ exception handling mechanism as a primary way +     of reporting error conditions. All exceptions that are specified in +     this mapping derive from <code>xml_schema::exception</code> which +     itself is derived from <code>std::exception</code>: +  </p> + +  <pre class="c++"> +struct exception: virtual std::exception +{ +  friend +  std::basic_ostream<C>& +  operator<< (std::basic_ostream<C>& os, const exception& e) +  { +    e.print (os); +    return os; +  } + +protected: +  virtual void +  print (std::basic_ostream<C>&) const = 0; +}; +  </pre> + +  <p>The exception hierarchy supports "virtual" <code>operator<<</code> +     which allows you to obtain diagnostics corresponding to the thrown +     exception using the base exception interface. For example:</p> + +  <pre class="c++"> +try +{ +  ... +} +catch (const xml_schema::exception& e) +{ +  cerr << e << endl; +} +  </pre> + +  <p>The following sub-sections describe exceptions thrown by the +     types that constitute the object model. +     <a href="#3.3">Section 3.3, "Error Handling"</a> of +     <a href="#3">Chapter 3, "Parsing"</a> describes exceptions +     and error handling mechanisms specific to the parsing functions. +     <a href="#4.4">Section 4.4, "Error Handling"</a> of +     <a href="#4">Chapter 4, "Serialization"</a> describes exceptions +     and error handling mechanisms specific to the serialization functions. +  </p> + + +  <h3><a name="2.2.1">2.2.1 <code>xml_schema::duplicate_id</code></a></h3> + +  <pre class="c++"> +struct duplicate_id: virtual exception +{ +  duplicate_id (const std::basic_string<C>& id); + +  const std::basic_string<C>& +  id () const; + +  virtual const char* +  what () const throw (); +}; +  </pre> + +  <p>The <code>xml_schema::duplicate_id</code> is thrown when +     a conflicting instance of <code>xml_schema::id</code> (see +     <a href="#2.5">Section 2.5, "Mapping for Built-in Data Types"</a>) +     is added to a tree. The offending ID value can be obtained using +     the <code>id</code> function. +  </p> + +  <h2><a name="2.3">2.3 Mapping for <code>import</code> and <code>include</code></a></h2> + +  <h3><a name="2.3.1">2.3.1 Import</a></h3> + +  <p>The XML Schema <code>import</code> element is mapped to the C++ +     Preprocessor <code>#include</code> directive. The value of +     the <code>schemaLocation</code> attribute is used to derive +     the name of the header file that appears in the <code>#include</code> +     directive. For instance: +  </p> + +  <pre class="xml"> +<import namespace="https://www.codesynthesis.com/test" +        schemaLocation="test.xsd"/> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +#include "test.hxx" +  </pre> + +  <p>Note that you will need to compile imported schemas separately +     in order to produce corresponding header files.</p> + +  <h3><a name="2.3.2">2.3.2 Inclusion with Target Namespace</a></h3> + +  <p>The XML Schema <code>include</code> element which refers to a schema +     with a target namespace or appears in a schema without a target namespace +     follows the same mapping rules as the <code>import</code> element, +     see <a href="#2.3.1">Section 2.3.1, "Import"</a>. +  </p> + +  <h3><a name="2.3.3">2.3.3 Inclusion without Target Namespace</a></h3> + +  <p>For the XML Schema <code>include</code> element which refers to a schema +     without a target namespace and appears in a schema with a target +     namespace (such inclusion sometimes called "chameleon inclusion"), +     declarations and definitions from the included schema are generated +     in-line in the namespace of the including schema as if they were +     declared and defined there verbatim. For example, consider the +     following two schemas: +  </p> + +  <pre class="xml"> +<-- common.xsd --> +<schema> +  <complexType name="type"> +  ... +  </complexType> +</schema> + +<-- test.xsd --> +<schema targetNamespace="https://www.codesynthesis.com/test"> +  <include schemaLocation="common.xsd"/> +</schema> +  </pre> + +  <p>The fragment of interest from the generated header file for +     <code>text.xsd</code> would look like this:</p> + +  <pre class="c++"> +// test.hxx +namespace test +{ +  class type +  { +    ... +  }; +} +  </pre> + +  <h2><a name="2.4">2.4 Mapping for Namespaces</a></h2> + +  <p>An XML Schema namespace is mapped to one or more nested C++ +     namespaces. XML Schema namespaces are identified by URIs. +     By default, a namespace URI is mapped to a sequence of +     C++ namespace names by removing the protocol and host parts +     and splitting the rest into a sequence of names with '<code>/</code>' +     as the name separator. For instance: +  </p> + +  <pre class="xml"> +<schema targetNamespace="https://www.codesynthesis.com/system/test"> +  ... +</schema> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +namespace system +{ +  namespace test +  { +    ... +  } +} +  </pre> + +  <p>The default mapping of namespace URIs to C++ namespace names can be +     altered using the <code>--namespace-map</code> and +     <code>--namespace-regex</code> options. See  the +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD +     Compiler Command Line Manual</a> for more information. +  </p> + +  <h2><a name="2.5">2.5 Mapping for Built-in Data Types</a></h2> + +  <p>The mapping of XML Schema built-in data types to C++ types is +     summarized in the table below.</p> + +  <!-- border="1" is necessary for html2ps --> +  <table id="builtin" border="1"> +    <tr> +      <th>XML Schema type</th> +      <th>Alias in the <code>xml_schema</code> namespace</th> +      <th>C++ type</th> +    </tr> + +    <tr> +      <th colspan="3">anyType and anySimpleType types</th> +    </tr> +    <tr> +      <td><code>anyType</code></td> +      <td><code>type</code></td> +      <td><a href="#2.5.2">Section 2.5.2, "Mapping for <code>anyType</code>"</a></td> +    </tr> +    <tr> +      <td><code>anySimpleType</code></td> +      <td><code>simple_type</code></td> +      <td><a href="#2.5.3">Section 2.5.3, "Mapping for <code>anySimpleType</code>"</a></td> +    </tr> + +    <tr> +      <th colspan="3">fixed-length integral types</th> +    </tr> +    <!-- 8-bit --> +    <tr> +      <td><code>byte</code></td> +      <td><code>byte</code></td> +      <td><code>signed char</code></td> +    </tr> +    <tr> +      <td><code>unsignedByte</code></td> +      <td><code>unsigned_byte</code></td> +      <td><code>unsigned char</code></td> +    </tr> + +    <!-- 16-bit --> +    <tr> +      <td><code>short</code></td> +      <td><code>short_</code></td> +      <td><code>short</code></td> +    </tr> +    <tr> +      <td><code>unsignedShort</code></td> +      <td><code>unsigned_short</code></td> +      <td><code>unsigned short</code></td> +    </tr> + +    <!-- 32-bit --> +    <tr> +      <td><code>int</code></td> +      <td><code>int_</code></td> +      <td><code>int</code></td> +    </tr> +    <tr> +      <td><code>unsignedInt</code></td> +      <td><code>unsigned_int</code></td> +      <td><code>unsigned int</code></td> +    </tr> + +    <!-- 64-bit --> +    <tr> +      <td><code>long</code></td> +      <td><code>long_</code></td> +      <td><code>long long</code></td> +    </tr> +    <tr> +      <td><code>unsignedLong</code></td> +      <td><code>unsigned_long</code></td> +      <td><code>unsigned long long</code></td> +    </tr> + +    <tr> +      <th colspan="3">arbitrary-length integral types</th> +    </tr> +    <tr> +      <td><code>integer</code></td> +      <td><code>integer</code></td> +      <td><code>long long</code></td> +    </tr> +    <tr> +      <td><code>nonPositiveInteger</code></td> +      <td><code>non_positive_integer</code></td> +      <td><code>long long</code></td> +    </tr> +    <tr> +      <td><code>nonNegativeInteger</code></td> +      <td><code>non_negative_integer</code></td> +      <td><code>unsigned long long</code></td> +    </tr> +    <tr> +      <td><code>positiveInteger</code></td> +      <td><code>positive_integer</code></td> +      <td><code>unsigned long long</code></td> +    </tr> +    <tr> +      <td><code>negativeInteger</code></td> +      <td><code>negative_integer</code></td> +      <td><code>long long</code></td> +    </tr> + +    <tr> +      <th colspan="3">boolean types</th> +    </tr> +    <tr> +      <td><code>boolean</code></td> +      <td><code>boolean</code></td> +      <td><code>bool</code></td> +    </tr> + +    <tr> +      <th colspan="3">fixed-precision floating-point types</th> +    </tr> +    <tr> +      <td><code>float</code></td> +      <td><code>float_</code></td> +      <td><code>float</code></td> +    </tr> +    <tr> +      <td><code>double</code></td> +      <td><code>double_</code></td> +      <td><code>double</code></td> +    </tr> + +    <tr> +      <th colspan="3">arbitrary-precision floating-point types</th> +    </tr> +    <tr> +      <td><code>decimal</code></td> +      <td><code>decimal</code></td> +      <td><code>double</code></td> +    </tr> + +    <tr> +      <th colspan="3">string types</th> +    </tr> +    <tr> +      <td><code>string</code></td> +      <td><code>string</code></td> +      <td>type derived from <code>std::basic_string</code></td> +    </tr> +    <tr> +      <td><code>normalizedString</code></td> +      <td><code>normalized_string</code></td> +      <td>type derived from <code>string</code></td> +    </tr> +    <tr> +      <td><code>token</code></td> +      <td><code>token</code></td> +      <td>type derived from <code>normalized_string</code></td> +    </tr> +    <tr> +      <td><code>Name</code></td> +      <td><code>name</code></td> +      <td>type derived from <code>token</code></td> +    </tr> +    <tr> +      <td><code>NMTOKEN</code></td> +      <td><code>nmtoken</code></td> +      <td>type derived from <code>token</code></td> +    </tr> +    <tr> +      <td><code>NMTOKENS</code></td> +      <td><code>nmtokens</code></td> +      <td>type derived from <code>sequence<nmtoken></code></td> +    </tr> +    <tr> +      <td><code>NCName</code></td> +      <td><code>ncname</code></td> +      <td>type derived from <code>name</code></td> +    </tr> +    <tr> +      <td><code>language</code></td> +      <td><code>language</code></td> +      <td>type derived from <code>token</code></td> +    </tr> + +    <tr> +      <th colspan="3">qualified name</th> +    </tr> +    <tr> +      <td><code>QName</code></td> +      <td><code>qname</code></td> +      <td><a href="#2.5.4">Section 2.5.4, "Mapping for <code>QName</code>"</a></td> +    </tr> + +    <tr> +      <th colspan="3">ID/IDREF types</th> +    </tr> +    <tr> +      <td><code>ID</code></td> +      <td><code>id</code></td> +      <td>type derived from <code>ncname</code></td> +    </tr> +    <tr> +      <td><code>IDREF</code></td> +      <td><code>idref</code></td> +      <td><a href="#2.5.5">Section 2.5.5, "Mapping for <code>IDREF</code>"</a></td> +    </tr> +    <tr> +      <td><code>IDREFS</code></td> +      <td><code>idrefs</code></td> +      <td>type derived from <code>sequence<idref></code></td> +    </tr> + +    <tr> +      <th colspan="3">URI types</th> +    </tr> +    <tr> +      <td><code>anyURI</code></td> +      <td><code>uri</code></td> +      <td>type derived from <code>std::basic_string</code></td> +    </tr> + +    <tr> +      <th colspan="3">binary types</th> +    </tr> +    <tr> +      <td><code>base64Binary</code></td> +      <td><code>base64_binary</code></td> +      <td rowspan="2"><a href="#2.5.6">Section 2.5.6, "Mapping for +         <code>base64Binary</code> and <code>hexBinary</code>"</a></td> +    </tr> +    <tr> +      <td><code>hexBinary</code></td> +      <td><code>hex_binary</code></td> +    </tr> + +    <tr> +      <th colspan="3">date/time types</th> +    </tr> +    <tr> +      <td><code>date</code></td> +      <td><code>date</code></td> +      <td><a href="#2.5.8">Section 2.5.8, "Mapping for +          <code>date</code>"</a></td> +    </tr> +    <tr> +      <td><code>dateTime</code></td> +      <td><code>date_time</code></td> +      <td><a href="#2.5.9">Section 2.5.9, "Mapping for +          <code>dateTime</code>"</a></td> +    </tr> +    <tr> +      <td><code>duration</code></td> +      <td><code>duration</code></td> +      <td><a href="#2.5.10">Section 2.5.10, "Mapping for +          <code>duration</code>"</a></td> +    </tr> +    <tr> +      <td><code>gDay</code></td> +      <td><code>gday</code></td> +      <td><a href="#2.5.11">Section 2.5.11, "Mapping for +          <code>gDay</code>"</a></td> +    </tr> +    <tr> +      <td><code>gMonth</code></td> +      <td><code>gmonth</code></td> +      <td><a href="#2.5.12">Section 2.5.12, "Mapping for +          <code>gMonth</code>"</a></td> +    </tr> +    <tr> +      <td><code>gMonthDay</code></td> +      <td><code>gmonth_day</code></td> +      <td><a href="#2.5.13">Section 2.5.13, "Mapping for +          <code>gMonthDay</code>"</a></td> +    </tr> +    <tr> +      <td><code>gYear</code></td> +      <td><code>gyear</code></td> +      <td><a href="#2.5.14">Section 2.5.14, "Mapping for +          <code>gYear</code>"</a></td> +    </tr> +    <tr> +      <td><code>gYearMonth</code></td> +      <td><code>gyear_month</code></td> +      <td><a href="#2.5.15">Section 2.5.15, "Mapping for +          <code>gYearMonth</code>"</a></td> +    </tr> +    <tr> +      <td><code>time</code></td> +      <td><code>time</code></td> +      <td><a href="#2.5.16">Section 2.5.16, "Mapping for +          <code>time</code>"</a></td> +    </tr> + +    <tr> +      <th colspan="3">entity types</th> +    </tr> +    <tr> +      <td><code>ENTITY</code></td> +      <td><code>entity</code></td> +      <td>type derived from <code>name</code></td> +    </tr> +    <tr> +      <td><code>ENTITIES</code></td> +      <td><code>entities</code></td> +      <td>type derived from <code>sequence<entity></code></td> +    </tr> +  </table> + +  <p>All XML Schema built-in types are mapped to C++ classes that are +     derived from the <code>xml_schema::simple_type</code> class except +     where the mapping is to a fundamental C++ type.</p> + +  <p>The <code>sequence</code> class template is defined in an +     implementation-specific namespace. It conforms to the +     sequence interface as defined by the ISO/ANSI Standard for +     C++ (ISO/IEC 14882:1998, Section 23.1.1, "Sequences"). +     Practically, this means that you can treat such a sequence +     as if it was <code>std::vector</code>. One notable extension +     to the standard interface that is available only for +     sequences of non-fundamental C++ types is the addition of +     the overloaded <code>push_back</code> and <code>insert</code> +     member functions which instead of the constant reference +     to the element type accept automatic pointer (<code>std::unique_ptr</code> +     or <code>std::auto_ptr</code>, depending on the C++ standard +     selected) to the element type. These functions assume ownership +     of the pointed to object and reset the passed automatic pointer. +  </p> + +  <h3><a name="2.5.1">2.5.1 Inheritance from Built-in Data Types</a></h3> + +  <p>In cases where the mapping calls for an inheritance from a built-in +     type which is mapped to a fundamental C++ type, a proxy type is +     used instead of the fundamental C++ type (C++ does not allow +     inheritance from fundamental types). For instance:</p> + +  <pre class="xml"> +<simpleType name="my_int"> +  <restriction base="int"/> +</simpleType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class my_int: public fundamental_base<int> +{ +  ... +}; +  </pre> + +  <p>The <code>fundamental_base</code> class template provides a close +     emulation (though not exact) of a fundamental C++ type. +     It is defined in an implementation-specific namespace and has the +     following interface:</p> + +  <pre class="c++"> +template <typename X> +class fundamental_base: public simple_type +{ +public: +  fundamental_base (); +  fundamental_base (X) +  fundamental_base (const fundamental_base&) + +public: +  fundamental_base& +  operator= (const X&); + +public: +  operator const X & () const; +  operator X& (); + +  template <typename Y> +  operator Y () const; + +  template <typename Y> +  operator Y (); +}; +  </pre> + +  <h3><a name="2.5.2">2.5.2 Mapping for <code>anyType</code></a></h3> + +  <p>The XML Schema <code>anyType</code> built-in data type is mapped to the +     <code>xml_schema::type</code> C++ class:</p> + +  <pre class="c++"> +class type +{ +public: +  virtual +  ~type (); + +  type (); +  type (const type&); + +  type& +  operator= (const type&); + +  virtual type* +  _clone () const; + +  // anyType DOM content. +  // +public: +  typedef element_optional dom_content_optional; + +  const dom_content_optional& +  dom_content () const; + +  dom_content_optional& +  dom_content (); + +  void +  dom_content (const xercesc::DOMElement&); + +  void +  dom_content (xercesc::DOMElement*); + +  void +  dom_content (const dom_content_optional&); + +  const xercesc::DOMDocument& +  dom_content_document () const; + +  xercesc::DOMDocument& +  dom_content_document (); + +  bool +  null_content () const; + +  // DOM association. +  // +public: +  const xercesc::DOMNode* +  _node () const; + +  xercesc::DOMNode* +  _node (); +}; +  </pre> + +  <p>When <code>xml_schema::type</code> is used to create an instance +     (as opposed to being a base of a derived type), it represents +     the XML Schema <code>anyType</code> type. <code>anyType</code> +     allows any attributes and any content in any order. In the +     C++/Tree mapping this content can be represented as a DOM +     fragment, similar to XML Schema wildcards (<a href="#2.12">Section +     2.12, "Mapping for <code>any</code> and +     <code>anyAttribute</code>"</a>).</p> + +  <p>To enable automatic extraction of <code>anyType</code> content +     during parsing, the <code>--generate-any-type</code> option must be +     specified. Because the DOM API is used to access such content, the +     Xerces-C++ runtime should be initialized by the application prior to +     parsing and should remain initialized for the lifetime of objects +     with the DOM content. For more information on the Xerces-C++ runtime +     initialization see <a href="#3.1">Section 3.1, "Initializing the +     Xerces-C++ Runtime"</a>.</p> + +  <p>The DOM content is stored as the optional DOM element container +     and the DOM content accessors and modifiers presented above are +     identical to those generated for an optional element wildcard. +     Refer to <a href="#2.12.2">Section 2.12.2, "Mapping for <code>any</code> +     with the Optional Cardinality Class"</a> for details on their +     semantics.</p> + +  <p>The <code>dom_content_document()</code> function returns the +     DOM document used to store the raw XML content corresponding +     to the <code>anyType</code> instance. It is equivalent to the +     <code>dom_document()</code> function generated for types +     with wildcards.</p> + +  <p>The <code>null_content()</code> accessor is an optimization function +     that allows us to check for the lack of content without actually +     creating its empty representation, that is, empty DOM document for +     <code>anyType</code> or empty string for <code>anySimpleType</code> +     (see the following section for details on <code>anySimpleType</code>).</p> + +  <p>For more information on DOM association refer to +     <a href="#5.1">Section 5.1, "DOM Association"</a>.</p> + +  <h3><a name="2.5.3">2.5.3 Mapping for <code>anySimpleType</code></a></h3> + +  <p>The XML Schema <code>anySimpleType</code> built-in data type is mapped +     to the <code>xml_schema::simple_type</code> C++ class:</p> + +  <pre class="c++"> +class simple_type: public type +{ +public: +  simple_type (); +  simple_type (const C*); +  simple_type (const std::basic_string<C>&); + +  simple_type (const simple_type&); + +  simple_type& +  operator= (const simple_type&); + +  virtual simple_type* +  _clone () const; + +  // anySimpleType text content. +  // +public: +  const std::basic_string<C>& +  text_content () const; + +  std::basic_string<C>& +  text_content (); + +  void +  text_content (const std::basic_string<C>&); +}; +  </pre> + +  <p>When <code>xml_schema::simple_type</code> is used to create an instance +     (as opposed to being a base of a derived type), it represents +     the XML Schema <code>anySimpleType</code> type. <code>anySimpleType</code> +     allows any simple content. In the C++/Tree mapping this content can +     be represented as a string and accessed or modified with the +     <code>text_content()</code> functions shown above.</p> + +  <h3><a name="2.5.4">2.5.4 Mapping for <code>QName</code></a></h3> + +  <p>The XML Schema <code>QName</code> built-in data type is mapped to the +     <code>xml_schema::qname</code> C++ class:</p> + +  <pre class="c++"> +class qname: public simple_type +{ +public: +  qname (const ncname&); +  qname (const uri&, const ncname&); +  qname (const qname&); + +public: +  qname& +  operator= (const qname&); + +public: +  virtual qname* +  _clone () const; + +public: +  bool +  qualified () const; + +  const uri& +  namespace_ () const; + +  const ncname& +  name () const; +}; +  </pre> + +  <p>The <code>qualified</code> accessor function can be used to determine +     if the name is qualified.</p> + +  <h3><a name="2.5.5">2.5.5 Mapping for <code>IDREF</code></a></h3> + +  <p>The XML Schema <code>IDREF</code> built-in data type is mapped to the +     <code>xml_schema::idref</code> C++ class. This class implements the +     smart pointer C++ idiom:</p> + +  <pre class="c++"> +class idref: public ncname +{ +public: +  idref (const C* s); +  idref (const C* s, std::size_t n); +  idref (std::size_t n, C c); +  idref (const std::basic_string<C>&); +  idref (const std::basic_string<C>&, +         std::size_t pos, +         std::size_t n = npos); + +public: +  idref (const idref&); + +public: +  virtual idref* +  _clone () const; + +public: +  idref& +  operator= (C c); + +  idref& +  operator= (const C* s); + +  idref& +  operator= (const std::basic_string<C>&) + +  idref& +  operator= (const idref&); + +public: +  const type* +  operator-> () const; + +  type* +  operator-> (); + +  const type& +  operator* () const; + +  type& +  operator* (); + +  const type* +  get () const; + +  type* +  get (); + +  // Conversion to bool. +  // +public: +  typedef void (idref::*bool_convertible)(); +  operator bool_convertible () const; +}; +  </pre> + +  <p>The object, <code>idref</code> instance refers to, is the immediate +     container of the matching <code>id</code> instance. For example, +     with the following instance document and schema: +  </p> + + +  <pre class="xml"> +<!-- test.xml --> +<root> +  <object id="obj-1" text="hello"/> +  <reference>obj-1</reference> +</root> + +<!-- test.xsd --> +<schema> +  <complexType name="object_type"> +    <attribute name="id" type="ID"/> +    <attribute name="text" type="string"/> +  </complexType> + +  <complexType name="root_type"> +    <sequence> +      <element name="object" type="object_type"/> +      <element name="reference" type="IDREF"/> +    </sequence> +  </complexType> + +  <element name="root" type="root_type"/> +</schema> +  </pre> + +  <p>The <code>ref</code> instance in the code below will refer to +     an object of type <code>object_type</code>:</p> + +  <pre class="c++"> +root_type& root = ...; +xml_schema::idref& ref (root.reference ()); +object_type& obj (dynamic_cast<object_type&> (*ref)); +cout << obj.text () << endl; +  </pre> + +  <p>The smart pointer interface of the <code>idref</code> class always +     returns a pointer or reference to <code>xml_schema::type</code>. +     This means that you will need to manually cast such pointer or +     reference to its real (dynamic) type before you can use it (unless +     all you need is the base interface provided by +     <code>xml_schema::type</code>). As a special extension to the XML +     Schema language, the mapping supports static typing of <code>idref</code> +     references by employing the <code>refType</code> extension attribute. +     The following example illustrates this mechanism: +  </p> + +  <pre class="xml"> +<!-- test.xsd --> +<schema +  xmlns:xse="https://www.codesynthesis.com/xmlns/xml-schema-extension"> + +  ... + +      <element name="reference" type="IDREF" xse:refType="object_type"/> + +  ... + +</schema> +  </pre> + +  <p>With this modification we do not need to do manual casting anymore: +  </p> + +  <pre class="c++"> +root_type& root = ...; +root_type::reference_type& ref (root.reference ()); +object_type& obj (*ref); +cout << ref->text () << endl; +  </pre> + + +  <h3><a name="2.5.6">2.5.6 Mapping for <code>base64Binary</code> and +      <code>hexBinary</code></a></h3> + +  <p>The XML Schema <code>base64Binary</code> and <code>hexBinary</code> +     built-in data types are mapped to the +     <code>xml_schema::base64_binary</code> and +     <code>xml_schema::hex_binary</code> C++ classes, respectively. The +     <code>base64_binary</code> and <code>hex_binary</code> classes +     support a simple buffer abstraction by inheriting from the +     <code>xml_schema::buffer</code> class: +  </p> + +  <pre class="c++"> +class bounds: public virtual exception +{ +public: +  virtual const char* +  what () const throw (); +}; + +class buffer +{ +public: +  typedef std::size_t size_t; + +public: +  buffer (size_t size = 0); +  buffer (size_t size, size_t capacity); +  buffer (const void* data, size_t size); +  buffer (const void* data, size_t size, size_t capacity); +  buffer (void* data, +          size_t size, +          size_t capacity, +          bool assume_ownership); + +public: +  buffer (const buffer&); + +  buffer& +  operator= (const buffer&); + +  void +  swap (buffer&); + +public: +  size_t +  capacity () const; + +  bool +  capacity (size_t); + +public: +  size_t +  size () const; + +  bool +  size (size_t); + +public: +  const char* +  data () const; + +  char* +  data (); + +  const char* +  begin () const; + +  char* +  begin (); + +  const char* +  end () const; + +  char* +  end (); +}; +  </pre> + +  <p>The last overloaded constructor reuses an existing data buffer instead +     of making a copy. If the <code>assume_ownership</code> argument is +     <code>true</code>, the instance assumes ownership of the +     memory block pointed to by the <code>data</code> argument and will +     eventually release it by calling <code>operator delete</code>. The +     <code>capacity</code> and <code>size</code> modifier functions return +     <code>true</code> if the underlying buffer has moved. +  </p> + +  <p>The <code>bounds</code> exception is thrown if the constructor +     arguments violate the <code>(size <= capacity)</code> +     constraint.</p> + +  <p>The <code>base64_binary</code> and <code>hex_binary</code> classes +     support the <code>buffer</code> interface and perform automatic +     decoding/encoding from/to the Base64 and Hex formats, respectively: +  </p> + +  <pre class="c++"> +class base64_binary: public simple_type, public buffer +{ +public: +  base64_binary (size_t size = 0); +  base64_binary (size_t size, size_t capacity); +  base64_binary (const void* data, size_t size); +  base64_binary (const void* data, size_t size, size_t capacity); +  base64_binary (void* data, +                 size_t size, +                 size_t capacity, +                 bool assume_ownership); + +public: +  base64_binary (const base64_binary&); + +  base64_binary& +  operator= (const base64_binary&); + +  virtual base64_binary* +  _clone () const; + +public: +  std::basic_string<C> +  encode () const; +}; +  </pre> + +  <pre class="c++"> +class hex_binary: public simple_type, public buffer +{ +public: +  hex_binary (size_t size = 0); +  hex_binary (size_t size, size_t capacity); +  hex_binary (const void* data, size_t size); +  hex_binary (const void* data, size_t size, size_t capacity); +  hex_binary (void* data, +              size_t size, +              size_t capacity, +              bool assume_ownership); + +public: +  hex_binary (const hex_binary&); + +  hex_binary& +  operator= (const hex_binary&); + +  virtual hex_binary* +  _clone () const; + +public: +  std::basic_string<C> +  encode () const; +}; +  </pre> + + +  <h2><a name="2.5.7">2.5.7 Time Zone Representation</a></h2> + +  <p>The <code>date</code>, <code>dateTime</code>, <code>gDay</code>, +     <code>gMonth</code>, <code>gMonthDay</code>, <code>gYear</code>, +     <code>gYearMonth</code>, and <code>time</code> XML Schema built-in +     types all include an optional time zone component. The following +     <code>xml_schema::time_zone</code> base class is used to represent +     this information:</p> + +  <pre class="c++"> +class time_zone +{ +public: +  time_zone (); +  time_zone (short hours, short minutes); + +  bool +  zone_present () const; + +  void +  zone_reset (); + +  short +  zone_hours () const; + +  void +  zone_hours (short); + +  short +  zone_minutes () const; + +  void +  zone_minutes (short); +}; + +bool +operator== (const time_zone&, const time_zone&); + +bool +operator!= (const time_zone&, const time_zone&); +  </pre> + +  <p>The <code>zone_present()</code> accessor function returns <code>true</code> +     if the time zone is specified. The <code>zone_reset()</code> modifier +     function resets the time zone object to the <em>not specified</em> +     state. If the time zone offset is negative then both hours and +     minutes components are represented as negative integers.</p> + + +  <h2><a name="2.5.8">2.5.8 Mapping for <code>date</code></a></h2> + + <p>The XML Schema <code>date</code> built-in data type is mapped to the +    <code>xml_schema::date</code> C++ class which represents a year, a day, +    and a month with an optional time zone. Its interface is presented +    below. For more information on the base <code>xml_schema::time_zone</code> +    class refer to <a href="#2.5.7">Section 2.5.7, "Time Zone +    Representation"</a>.</p> + +  <pre class="c++"> +class date: public simple_type, public time_zone +{ +public: +  date (int year, unsigned short month, unsigned short day); +  date (int year, unsigned short month, unsigned short day, +        short zone_hours, short zone_minutes); + +public: +  date (const date&); + +  date& +  operator= (const date&); + +  virtual date* +  _clone () const; + +public: +  int +  year () const; + +  void +  year (int); + +  unsigned short +  month () const; + +  void +  month (unsigned short); + +  unsigned short +  day () const; + +  void +  day (unsigned short); +}; + +bool +operator== (const date&, const date&); + +bool +operator!= (const date&, const date&); +  </pre> + +  <h2><a name="2.5.9">2.5.9 Mapping for <code>dateTime</code></a></h2> + + <p>The XML Schema <code>dateTime</code> built-in data type is mapped to the +    <code>xml_schema::date_time</code> C++ class which represents a year, a month, +    a day, hours, minutes, and seconds with an optional time zone. Its interface +    is presented below. For more information on the base +    <code>xml_schema::time_zone</code> class refer to <a href="#2.5.7">Section +    2.5.7, "Time Zone Representation"</a>.</p> + +  <pre class="c++"> +class date_time: public simple_type, public time_zone +{ +public: +  date_time (int year, unsigned short month, unsigned short day, +             unsigned short hours, unsigned short minutes, +             double seconds); + +  date_time (int year, unsigned short month, unsigned short day, +             unsigned short hours, unsigned short minutes, +             double seconds, short zone_hours, short zone_minutes); +public: +  date_time (const date_time&); + +  date_time& +  operator= (const date_time&); + +  virtual date_time* +  _clone () const; + +public: +  int +  year () const; + +  void +  year (int); + +  unsigned short +  month () const; + +  void +  month (unsigned short); + +  unsigned short +  day () const; + +  void +  day (unsigned short); + +  unsigned short +  hours () const; + +  void +  hours (unsigned short); + +  unsigned short +  minutes () const; + +  void +  minutes (unsigned short); + +  double +  seconds () const; + +  void +  seconds (double); +}; + +bool +operator== (const date_time&, const date_time&); + +bool +operator!= (const date_time&, const date_time&); +  </pre> + + +  <h2><a name="2.5.10">2.5.10 Mapping for <code>duration</code></a></h2> + +  <p>The XML Schema <code>duration</code> built-in data type is mapped to the +    <code>xml_schema::duration</code> C++ class which represents a potentially +     negative duration in the form of years, months, days, hours, minutes, +     and seconds. Its interface is presented below.</p> + +  <pre class="c++"> +class duration: public simple_type +{ +public: +  duration (bool negative, +            unsigned int years, unsigned int months, unsigned int days, +            unsigned int hours, unsigned int minutes, double seconds); +public: +  duration (const duration&); + +  duration& +  operator= (const duration&); + +  virtual duration* +  _clone () const; + +public: +  bool +  negative () const; + +  void +  negative (bool); + +  unsigned int +  years () const; + +  void +  years (unsigned int); + +  unsigned int +  months () const; + +  void +  months (unsigned int); + +  unsigned int +  days () const; + +  void +  days (unsigned int); + +  unsigned int +  hours () const; + +  void +  hours (unsigned int); + +  unsigned int +  minutes () const; + +  void +  minutes (unsigned int); + +  double +  seconds () const; + +  void +  seconds (double); +}; + +bool +operator== (const duration&, const duration&); + +bool +operator!= (const duration&, const duration&); +  </pre> + + +  <h2><a name="2.5.11">2.5.11 Mapping for <code>gDay</code></a></h2> + +  <p>The XML Schema <code>gDay</code> built-in data type is mapped to the +    <code>xml_schema::gday</code> C++ class which represents a day of the +     month with an optional time zone. Its interface is presented below. +     For more information on the base <code>xml_schema::time_zone</code> +     class refer to <a href="#2.5.7">Section 2.5.7, "Time Zone +     Representation"</a>.</p> + +  <pre class="c++"> +class gday: public simple_type, public time_zone +{ +public: +  explicit +  gday (unsigned short day); +  gday (unsigned short day, short zone_hours, short zone_minutes); + +public: +  gday (const gday&); + +  gday& +  operator= (const gday&); + +  virtual gday* +  _clone () const; + +public: +  unsigned short +  day () const; + +  void +  day (unsigned short); +}; + +bool +operator== (const gday&, const gday&); + +bool +operator!= (const gday&, const gday&); +  </pre> + + +  <h2><a name="2.5.12">2.5.12 Mapping for <code>gMonth</code></a></h2> + +  <p>The XML Schema <code>gMonth</code> built-in data type is mapped to the +    <code>xml_schema::gmonth</code> C++ class which represents a month of the +     year with an optional time zone. Its interface is presented below. +     For more information on the base <code>xml_schema::time_zone</code> +     class refer to <a href="#2.5.7">Section 2.5.7, "Time Zone +     Representation"</a>.</p> + +  <pre class="c++"> +class gmonth: public simple_type, public time_zone +{ +public: +  explicit +  gmonth (unsigned short month); +  gmonth (unsigned short month, +          short zone_hours, short zone_minutes); + +public: +  gmonth (const gmonth&); + +  gmonth& +  operator= (const gmonth&); + +  virtual gmonth* +  _clone () const; + +public: +  unsigned short +  month () const; + +  void +  month (unsigned short); +}; + +bool +operator== (const gmonth&, const gmonth&); + +bool +operator!= (const gmonth&, const gmonth&); +  </pre> + + +  <h2><a name="2.5.13">2.5.13 Mapping for <code>gMonthDay</code></a></h2> + +  <p>The XML Schema <code>gMonthDay</code> built-in data type is mapped to the +    <code>xml_schema::gmonth_day</code> C++ class which represents a day and +     a month of the year with an optional time zone. Its interface is presented +     below. For more information on the base <code>xml_schema::time_zone</code> +     class refer to <a href="#2.5.7">Section 2.5.7, "Time Zone +     Representation"</a>.</p> + +  <pre class="c++"> +class gmonth_day: public simple_type, public time_zone +{ +public: +  gmonth_day (unsigned short month, unsigned short day); +  gmonth_day (unsigned short month, unsigned short day, +              short zone_hours, short zone_minutes); + +public: +  gmonth_day (const gmonth_day&); + +  gmonth_day& +  operator= (const gmonth_day&); + +  virtual gmonth_day* +  _clone () const; + +public: +  unsigned short +  month () const; + +  void +  month (unsigned short); + +  unsigned short +  day () const; + +  void +  day (unsigned short); +}; + +bool +operator== (const gmonth_day&, const gmonth_day&); + +bool +operator!= (const gmonth_day&, const gmonth_day&); +  </pre> + + +  <h2><a name="2.5.14">2.5.14 Mapping for <code>gYear</code></a></h2> + +  <p>The XML Schema <code>gYear</code> built-in data type is mapped to the +    <code>xml_schema::gyear</code> C++ class which represents a year with +     an optional time zone. Its interface is presented below. For more +     information on the base <code>xml_schema::time_zone</code> class refer +     to <a href="#2.5.7">Section 2.5.7, "Time Zone Representation"</a>.</p> + +  <pre class="c++"> +class gyear: public simple_type, public time_zone +{ +public: +  explicit +  gyear (int year); +  gyear (int year, short zone_hours, short zone_minutes); + +public: +  gyear (const gyear&); + +  gyear& +  operator= (const gyear&); + +  virtual gyear* +  _clone () const; + +public: +  int +  year () const; + +  void +  year (int); +}; + +bool +operator== (const gyear&, const gyear&); + +bool +operator!= (const gyear&, const gyear&); +  </pre> + + +  <h2><a name="2.5.15">2.5.15 Mapping for <code>gYearMonth</code></a></h2> + +  <p>The XML Schema <code>gYearMonth</code> built-in data type is mapped to +     the <code>xml_schema::gyear_month</code> C++ class which represents +     a year and a month with an optional time zone. Its interface is presented +     below. For more information on the base <code>xml_schema::time_zone</code> +     class refer to <a href="#2.5.7">Section 2.5.7, "Time Zone +     Representation"</a>.</p> + +  <pre class="c++"> +class gyear_month: public simple_type, public time_zone +{ +public: +  gyear_month (int year, unsigned short month); +  gyear_month (int year, unsigned short month, +               short zone_hours, short zone_minutes); +public: +  gyear_month (const gyear_month&); + +  gyear_month& +  operator= (const gyear_month&); + +  virtual gyear_month* +  _clone () const; + +public: +  int +  year () const; + +  void +  year (int); + +  unsigned short +  month () const; + +  void +  month (unsigned short); +}; + +bool +operator== (const gyear_month&, const gyear_month&); + +bool +operator!= (const gyear_month&, const gyear_month&); +  </pre> + + +  <h2><a name="2.5.16">2.5.16 Mapping for <code>time</code></a></h2> + +  <p>The XML Schema <code>time</code> built-in data type is mapped to +     the <code>xml_schema::time</code> C++ class which represents hours, +     minutes, and seconds with an optional time zone. Its interface is +     presented below. For more information on the base +     <code>xml_schema::time_zone</code> class refer to +     <a href="#2.5.7">Section 2.5.7, "Time Zone Representation"</a>.</p> + +  <pre class="c++"> +class time: public simple_type, public time_zone +{ +public: +  time (unsigned short hours, unsigned short minutes, double seconds); +  time (unsigned short hours, unsigned short minutes, double seconds, +        short zone_hours, short zone_minutes); + +public: +  time (const time&); + +  time& +  operator= (const time&); + +  virtual time* +  _clone () const; + +public: +  unsigned short +  hours () const; + +  void +  hours (unsigned short); + +  unsigned short +  minutes () const; + +  void +  minutes (unsigned short); + +  double +  seconds () const; + +  void +  seconds (double); +}; + +bool +operator== (const time&, const time&); + +bool +operator!= (const time&, const time&); +  </pre> + + +  <!-- Mapping for Simple Types --> + +  <h2><a name="2.6">2.6 Mapping for Simple Types</a></h2> + +  <p>An XML Schema simple type is mapped to a C++ class with the same +     name as the simple type. The class defines a public copy constructor, +     a public copy assignment operator, and a public virtual +     <code>_clone</code> function. The <code>_clone</code> function is +     declared <code>const</code>, does not take any arguments, and returns +     a pointer to a complete copy of the instance allocated in the free +     store. The <code>_clone</code> function shall be used to make copies +     when static type and dynamic type of the instance may differ (see +     <a href="#2.11">Section 2.11, "Mapping for <code>xsi:type</code> +     and Substitution Groups"</a>). For instance:</p> + +  <pre class="xml"> +<simpleType name="object"> +  ... +</simpleType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class object: ... +{ +public: +  object (const object&); + +public: +  object& +  operator= (const object&); + +public: +  virtual object* +  _clone () const; + +  ... + +}; +  </pre> + +  <p>The base class specification and the rest of the class definition +     depend on the type of derivation used to define the simple type. </p> + + +  <h3><a name="2.6.1">2.6.1 Mapping for Derivation by Restriction</a></h3> + +  <p>XML Schema derivation by restriction is mapped to C++ public +     inheritance. The base type of the restriction becomes the base +     type for the resulting C++ class. In addition to the members described +     in <a href="#2.6">Section 2.6, "Mapping for Simple Types"</a>, the +     resulting C++ class defines a public constructor with the base type +     as its single argument. For instance:</p> + +  <pre class="xml"> +<simpleType name="object"> +  <restriction base="base"> +    ... +  </restriction> +</simpleType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class object: public base +{ +public: +  object (const base&); +  object (const object&); + +public: +  object& +  operator= (const object&); + +public: +  virtual object* +  _clone () const; +}; +  </pre> + + +  <h3><a name="2.6.2">2.6.2 Mapping for Enumerations</a></h3> + +<p>XML Schema restriction by enumeration is mapped to a C++ class +   with semantics similar to C++ <code>enum</code>. Each XML Schema +   enumeration element is mapped to a C++ enumerator with the +   name derived from the <code>value</code> attribute and defined +   in the class scope. In addition to the members +   described in <a href="#2.6">Section 2.6, "Mapping for Simple Types"</a>, +   the resulting C++ class defines a public constructor that can be called +   with one of the enumerators as its single argument, a public constructor +   that can be called with enumeration's base value as its single +   argument, a public assignment operator that can be used to assign the +   value of one of the enumerators, and a public implicit conversion +   operator to the underlying C++ enum type.</p> + +<p>Furthermore, for string-based enumeration types, the resulting C++ +   class defines a public constructor with a single argument of type +   <code>const C*</code> and a public constructor with a single +   argument of type <code>const std::basic_string<C>&</code>. +   For instance:</p> + +  <pre class="xml"> +<simpleType name="color"> +  <restriction base="string"> +    <enumeration value="red"/> +    <enumeration value="green"/> +    <enumeration value="blue"/> +  </restriction> +</simpleType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class color: public xml_schema::string +{ +public: +  enum value +  { +    red, +    green, +    blue +  }; + +public: +  color (value); +  color (const C*); +  color (const std::basic_string<C>&); +  color (const xml_schema::string&); +  color (const color&); + +public: +  color& +  operator= (value); + +  color& +  operator= (const color&); + +public: +  virtual color* +  _clone () const; + +public: +  operator value () const; +}; +  </pre> + +  <h3><a name="2.6.3">2.6.3 Mapping for Derivation by List</a></h3> + +  <p>XML Schema derivation by list is mapped to C++ public +     inheritance from <code>xml_schema::simple_type</code> +     (<a href="#2.5.3">Section 2.5.3, "Mapping for +     <code>anySimpleType</code>"</a>) and a suitable sequence type. +     The list item type becomes the element type of the sequence. +     In addition to the members described in <a href="#2.6">Section 2.6, +     "Mapping for Simple Types"</a>, the resulting C++ class defines +     a public default constructor, a public constructor +     with the first argument of type <code>size_type</code> and +     the second argument of list item type that creates +     a list object with the specified number of copies of the specified +     element value, and a public constructor with the two arguments +     of an input iterator type that creates a list object from an +     iterator range. For instance: +  </p> + +  <pre class="xml"> +<simpleType name="int_list"> +  <list itemType="int"/> +</simpleType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class int_list: public simple_type, +                public sequence<int> +{ +public: +  int_list (); +  int_list (size_type n, int x); + +  template <typename I> +  int_list (const I& begin, const I& end); +  int_list (const int_list&); + +public: +  int_list& +  operator= (const int_list&); + +public: +  virtual int_list* +  _clone () const; +}; +  </pre> + +  <p>The <code>sequence</code> class template is defined in an +     implementation-specific namespace. It conforms to the +     sequence interface as defined by the ISO/ANSI Standard for +     C++ (ISO/IEC 14882:1998, Section 23.1.1, "Sequences"). +     Practically, this means that you can treat such a sequence +     as if it was <code>std::vector</code>. One notable extension +     to the standard interface that is available only for +     sequences of non-fundamental C++ types is the addition of +     the overloaded <code>push_back</code> and <code>insert</code> +     member functions which instead of the constant reference +     to the element type accept automatic pointer (<code>std::unique_ptr</code> +     or <code>std::auto_ptr</code>, depending on the C++ standard +     selected) to the element type. These functions assume ownership +     of the pointed to object and reset the passed automatic pointer. +  </p> + +  <h3><a name="2.6.4">2.6.4 Mapping for Derivation by Union</a></h3> + +  <p>XML Schema derivation by union is mapped to C++ public +     inheritance from <code>xml_schema::simple_type</code> +     (<a href="#2.5.3">Section 2.5.3, "Mapping for +     <code>anySimpleType</code>"</a>) and <code>std::basic_string<C></code>. +     In addition to the members described in <a href="#2.6">Section 2.6, +     "Mapping for Simple Types"</a>, the resulting C++ class defines a +     public constructor with a single argument of type <code>const C*</code> +     and a public constructor with a single argument of type +     <code>const std::basic_string<C>&</code>. For instance: +  </p> + +  <pre class="xml"> +<simpleType name="int_string_union"> +  <xsd:union memberTypes="xsd:int xsd:string"/> +</simpleType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class int_string_union: public simple_type, +                        public std::basic_string<C> +{ +public: +  int_string_union (const C*); +  int_string_union (const std::basic_string<C>&); +  int_string_union (const int_string_union&); + +public: +  int_string_union& +  operator= (const int_string_union&); + +public: +  virtual int_string_union* +  _clone () const; +}; +  </pre> + +  <h2><a name="2.7">2.7 Mapping for Complex Types</a></h2> + +  <p>An XML Schema complex type is mapped to a C++ class with the same +     name as the complex type. The class defines a public copy constructor, +     a public copy assignment operator, and a public virtual +     <code>_clone</code> function. The <code>_clone</code> function is +     declared <code>const</code>, does not take any arguments, and returns +     a pointer to a complete copy of the instance allocated in the free +     store. The <code>_clone</code> function shall be used to make copies +     when static type and dynamic type of the instance may differ (see +     <a href="#2.11">Section 2.11, "Mapping for <code>xsi:type</code> +     and Substitution Groups"</a>).</p> + +  <p>Additionally, the resulting C++ class +     defines two public constructors that take an initializer for each +     member of the complex type and all its base types that belongs to +     the One cardinality class (see <a href="#2.8">Section 2.8, "Mapping +     for Local Elements and Attributes"</a>). In the first constructor, +     the arguments are passed as constant references and the newly created +     instance is initialized with copies of the passed objects. In the +     second constructor, arguments that are complex types (that is, +     they themselves contain elements or attributes) are passed as +     either <code>std::unique_ptr</code> (C++11) or <code>std::auto_ptr</code> +     (C++98), depending on the C++ standard selected. In this case the newly +     created instance is directly initialized with and assumes ownership +     of the pointed to objects and the <code>std::[unique|auto]_ptr</code> +     arguments are reset to <code>0</code>. For instance:</p> + +  <pre class="xml"> +<complexType name="complex"> +  <sequence> +    <element name="a" type="int"/> +    <element name="b" type="string"/> +  </sequence> +</complexType> + +<complexType name="object"> +  <sequence> +    <element name="s-one" type="boolean"/> +    <element name="c-one" type="complex"/> +    <element name="optional" type="int" minOccurs="0"/> +    <element name="sequence" type="string" maxOccurs="unbounded"/> +  </sequence> +</complexType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class complex: public xml_schema::type +{ +public: +  object (const int& a, const xml_schema::string& b); +  object (const complex&); + +public: +  object& +  operator= (const complex&); + +public: +  virtual complex* +  _clone () const; + +  ... + +}; + +class object: public xml_schema::type +{ +public: +  object (const bool& s_one, const complex& c_one); +  object (const bool& s_one, std::[unique|auto]_ptr<complex> c_one); +  object (const object&); + +public: +  object& +  operator= (const object&); + +public: +  virtual object* +  _clone () const; + +  ... + +}; +  </pre> + +  <p>Notice that the generated <code>complex</code> class does not +     have the second (<code>std::[unique|auto]_ptr</code>) version of the +     constructor since all its required members are of simple types.</p> + +  <p>If an XML Schema complex type has an ultimate base which is an XML +     Schema simple type then the resulting C++ class also defines a public +     constructor that takes an initializer for the base type as well as +     for each member of the complex type and all its base types that +     belongs to the One cardinality class. For instance:</p> + +  <pre class="xml"> +<complexType name="object"> +  <simpleContent> +    <extension base="date"> +      <attribute name="lang" type="language" use="required"/> +    </extension> +  </simpleContent> +</complexType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class object: public xml_schema::string +{ +public: +  object (const xml_schema::language& lang); + +  object (const xml_schema::date& base, +          const xml_schema::language& lang); + +  ... + +}; +  </pre> + +  <p>Furthermore, for string-based XML Schema complex types, the resulting C++ +     class also defines two  public constructors with the first arguments +     of type <code>const C*</code> and <code>std::basic_string<C>&</code>, +     respectively, followed by arguments for each member of the complex +     type and all its base types that belongs to the One cardinality +     class. For enumeration-based complex types the resulting C++ +     class also defines a public constructor with the first arguments +     of the underlying enum type followed by arguments for each member +     of the complex type and all its base types that belongs to the One +     cardinality class. For instance:</p> + +  <pre class="xml"> +<simpleType name="color"> +  <restriction base="string"> +    <enumeration value="red"/> +    <enumeration value="green"/> +    <enumeration value="blue"/> +  </restriction> +</simpleType> + +<complexType name="object"> +  <simpleContent> +    <extension base="color"> +      <attribute name="lang" type="language" use="required"/> +    </extension> +  </simpleContent> +</complexType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class color: public xml_schema::string +{ +public: +  enum value +  { +    red, +    green, +    blue +  }; + +public: +  color (value); +  color (const C*); +  color (const std::basic_string<C>&); + +  ... + +}; + +class object: color +{ +public: +  object (const color& base, +          const xml_schema::language& lang); + +  object (const color::value& base, +          const xml_schema::language& lang); + +  object (const C* base, +          const xml_schema::language& lang); + +  object (const std::basic_string<C>& base, +          const xml_schema::language& lang); + +  ... + +}; +  </pre> + +  <p>Additional constructors can be requested with the +     <code>--generate-default-ctor</code> and +     <code>--generate-from-base-ctor</code> options. See the +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD +     Compiler Command Line Manual</a> for details.</p> + +  <p>If an XML Schema complex type is not explicitly derived from any type, +     the resulting C++ class is derived from <code>xml_schema::type</code>. +     In cases where an XML Schema complex type is defined using derivation +     by extension or restriction, the resulting C++ base class specification +     depends on the type of derivation and is described in the subsequent +     sections. +  </p> + +  <p>The mapping for elements and attributes that are defined in a complex +     type is described in <a href="#2.8">Section 2.8, "Mapping for Local +     Elements and Attributes"</a>. +  </p> + +  <h3><a name="2.7.1">2.7.1 Mapping for Derivation by Extension</a></h3> + +  <p>XML Schema derivation by extension is mapped to C++ public +     inheritance. The base type of the extension becomes the base +     type for the resulting C++ class. +  </p> + +  <h3><a name="2.7.2">2.7.2 Mapping for Derivation by Restriction</a></h3> + +  <p>XML Schema derivation by restriction is mapped to C++ public +     inheritance. The base type of the restriction becomes the base +     type for the resulting C++ class. XML Schema elements and +     attributes defined within restriction do not result in any +     definitions in the resulting C++ class. Instead, corresponding +     (unrestricted) definitions are inherited from the base class. +     In the future versions of this mapping, such elements and +     attributes may result in redefinitions of accessors and +     modifiers to reflect their restricted semantics. +  </p> + +  <!-- 2.8 Mapping for Local Elements and Attributes --> + +  <h2><a name="2.8">2.8 Mapping for Local Elements and Attributes</a></h2> + +   <p>XML Schema element and attribute definitions are called local +      if they appear within a complex type definition, an element group +      definition, or an attribute group definitions. +   </p> + +   <p>Local XML Schema element and attribute definitions have the same +      C++ mapping. Therefore, in this section, local elements and +      attributes are collectively called members. +   </p> + +   <p>While there are many different member cardinality combinations +      (determined by the <code>use</code> attribute for attributes and +       the <code>minOccurs</code> and <code>maxOccurs</code> attributes +       for elements), the mapping divides all possible cardinality +       combinations into three cardinality classes: +   </p> + +   <dl> +     <dt><i>one</i></dt> +     <dd>attributes: <code>use == "required"</code></dd> +     <dd>attributes: <code>use == "optional"</code> and has default or fixed value</dd> +     <dd>elements: <code>minOccurs == "1"</code> and <code>maxOccurs == "1"</code></dd> + +     <dt><i>optional</i></dt> +     <dd>attributes: <code>use == "optional"</code> and doesn't have default or fixed value</dd> +     <dd>elements: <code>minOccurs == "0"</code> and <code>maxOccurs == "1"</code></dd> + +     <dt><i>sequence</i></dt> +     <dd>elements: <code>maxOccurs > "1"</code></dd> +   </dl> + +   <p>An optional attribute with a default or fixed value acquires this value +      if the attribute hasn't been specified in an instance document (see +      <a href="#A">Appendix A, "Default and Fixed Values"</a>). This +      mapping places such optional attributes to the One cardinality +      class.</p> + +   <p>A member is mapped to a set of public type definitions +      (<code>typedef</code>s) and a set of public accessor and modifier +      functions. Type definitions have names derived from the member's +      name. The accessor and modifier functions have the same name as the +      member. For example: +   </p> + +  <pre class="xml"> +<complexType name="object"> +  <sequence> +    <element name="member" type="string"/> +  </sequence> +</complexType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class object: public xml_schema::type +{ +public: +  typedef xml_schema::string member_type; + +  const member_type& +  member () const; + +  ... + +}; +  </pre> + +   <p>In addition, if a member has a default or fixed value, a static +      accessor function is generated that returns this value. For +      example:</p> + +<pre class="xml"> +<complexType name="object"> +  <attribute name="data" type="string" default="test"/> +</complexType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class object: public xml_schema::type +{ +public: +  typedef xml_schema::string data_type; + +  const data_type& +  data () const; + +  static const data_type& +  data_default_value (); + +  ... + +}; +  </pre> + +   <p>Names and semantics of type definitions for the member as well +      as signatures of the accessor and modifier functions depend on +      the member's cardinality class and are described in the following +      sub-sections. +   </p> + + +  <h3><a name="2.8.1">2.8.1 Mapping for Members with the One Cardinality Class</a></h3> + +   <p>For the One cardinality class, the type definitions consist of +      an alias for the member's type with the name created by appending +      the <code>_type</code> suffix to the member's name. +   </p> + +   <p>The accessor functions come in constant and non-constant versions. +      The constant accessor function returns a constant reference to the +      member and can be used for read-only access. The non-constant +      version returns an unrestricted reference to the member and can +      be used for read-write access. +   </p> + +   <p>The first modifier function expects an argument of type reference to +      constant of the member's type. It makes a deep copy of its argument. +      Except for member's types that are mapped to fundamental C++ types, +      the second modifier function is provided that expects an argument +      of type automatic pointer (<code>std::unique_ptr</code> or +      <code>std::auto_ptr</code>, depending on the C++ standard selected) +      to the member's type. It assumes ownership of the pointed to object +      and resets the passed automatic pointer. For instance:</p> + +  <pre class="xml"> +<complexType name="object"> +  <sequence> +    <element name="member" type="string"/> +  </sequence> +</complexType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class object: public xml_schema::type +{ +public: +  // Type definitions. +  // +  typedef xml_schema::string member_type; + +  // Accessors. +  // +  const member_type& +  member () const; + +  member_type& +  member (); + +  // Modifiers. +  // +  void +  member (const member_type&); + +  void +  member (std::[unique|auto]_ptr<member_type>); +  ... + +}; +  </pre> + +   <p>In addition, if requested by specifying the <code>--generate-detach</code> +      option and only for members of non-fundamental C++ types, the mapping +      provides a detach function that returns an automatic pointer to the +      member's type, for example:</p> + +  <pre class="c++"> +class object: public xml_schema::type +{ +public: +  ... + +  std::[unique|auto]_ptr<member_type> +  detach_member (); +  ... + +}; +  </pre> + +   <p>This function detaches the value from the tree leaving the member +      value uninitialized. Accessing such an uninitialized value prior to +      re-initializing it results in undefined behavior.</p> + +  <p>The following code shows how one could use this mapping:</p> + +  <pre class="c++"> +void +f (object& o) +{ +  using xml_schema::string; + +  string s (o.member ());                // get +  object::member_type& sr (o.member ()); // get + +  o.member ("hello");           // set, deep copy +  o.member () = "hello";        // set, deep copy + +  // C++11 version. +  // +  std::unique_ptr<string> p (new string ("hello")); +  o.member (std::move (p));     // set, assumes ownership +  p = o.detach_member ();       // detach, member is uninitialized +  o.member (std::move (p));     // re-attach + +  // C++98 version. +  // +  std::auto_ptr<string> p (new string ("hello")); +  o.member (p);                 // set, assumes ownership +  p = o.detach_member ();       // detach, member is uninitialized +  o.member (p);                 // re-attach +} +  </pre> + + +<h3><a name="2.8.2">2.8.2 Mapping for Members with the Optional Cardinality Class</a></h3> + +   <p>For the Optional cardinality class, the type definitions consist of +      an alias for the member's type with the name created by appending +      the <code>_type</code> suffix to the member's name and an alias for +      the container type with the name created by appending the +      <code>_optional</code> suffix to the member's name. +   </p> + +   <p>Unlike accessor functions for the One cardinality class, accessor +      functions for the Optional cardinality class return references to +      corresponding containers rather than directly to members. The +      accessor functions come in constant and non-constant versions. +      The constant accessor function returns a constant reference to +      the container and can be used for read-only access. The non-constant +      version returns an unrestricted reference to the container +      and can be used for read-write access. +   </p> + +   <p>The modifier functions are overloaded for the member's +      type and the container type. The first modifier function +      expects an argument of type reference to constant of the +      member's type. It makes a deep copy of its argument. +      Except for member's types that are mapped to fundamental C++ types, +      the second modifier function is provided that expects an argument +      of type automatic pointer (<code>std::unique_ptr</code> or +      <code>std::auto_ptr</code>, depending on the C++ standard selected) +      to the member's type. It assumes ownership of the pointed to object +      and resets the passed automatic pointer. The last modifier function +      expects an argument of type reference to constant of the container +      type. It makes a deep copy of its argument. For instance: +   </p> + +  <pre class="xml"> +<complexType name="object"> +  <sequence> +    <element name="member" type="string" minOccurs="0"/> +  </sequence> +</complexType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class object: public xml_schema::type +{ +public: +  // Type definitions. +  // +  typedef xml_schema::string member_type; +  typedef optional<member_type> member_optional; + +  // Accessors. +  // +  const member_optional& +  member () const; + +  member_optional& +  member (); + +  // Modifiers. +  // +  void +  member (const member_type&); + +  void +  member (std::[unique|auto]_ptr<member_type>); + +  void +  member (const member_optional&); + +  ... + +}; +  </pre> + + +  <p>The <code>optional</code> class template is defined in an +     implementation-specific namespace and has the following +     interface. The <code>[unique|auto]_ptr</code>-based constructor +     and modifier function are only available if the template +     argument is not a fundamental C++ type. +  </p> + +  <pre class="c++"> +template <typename X> +class optional +{ +public: +  optional (); + +  // Makes a deep copy. +  // +  explicit +  optional (const X&); + +  // Assumes ownership. +  // +  explicit +  optional (std::[unique|auto]_ptr<X>); + +  optional (const optional&); + +public: +  optional& +  operator= (const X&); + +  optional& +  operator= (const optional&); + +  // Pointer-like interface. +  // +public: +  const X* +  operator-> () const; + +  X* +  operator-> (); + +  const X& +  operator* () const; + +  X& +  operator* (); + +  typedef void (optional::*bool_convertible) (); +  operator bool_convertible () const; + +  // Get/set interface. +  // +public: +  bool +  present () const; + +  const X& +  get () const; + +  X& +  get (); + +  // Makes a deep copy. +  // +  void +  set (const X&); + +  // Assumes ownership. +  // +  void +  set (std::[unique|auto]_ptr<X>); + +  // Detach and return the contained value. +  // +  std::[unique|auto]_ptr<X> +  detach (); + +  void +  reset (); +}; + +template <typename X> +bool +operator== (const optional<X>&, const optional<X>&); + +template <typename X> +bool +operator!= (const optional<X>&, const optional<X>&); + +template <typename X> +bool +operator< (const optional<X>&, const optional<X>&); + +template <typename X> +bool +operator> (const optional<X>&, const optional<X>&); + +template <typename X> +bool +operator<= (const optional<X>&, const optional<X>&); + +template <typename X> +bool +operator>= (const optional<X>&, const optional<X>&); +  </pre> + + +  <p>The following code shows how one could use this mapping:</p> + +  <pre class="c++"> +void +f (object& o) +{ +  using xml_schema::string; + +  if (o.member ().present ())       // test +  { +    string& s (o.member ().get ()); // get +    o.member ("hello");             // set, deep copy +    o.member ().set ("hello");      // set, deep copy +    o.member ().reset ();           // reset +  } + +  // Same as above but using pointer notation: +  // +  if (o.member ())                  // test +  { +    string& s (*o.member ());       // get +    o.member ("hello");             // set, deep copy +    *o.member () = "hello";         // set, deep copy +    o.member ().reset ();           // reset +  } + +  // C++11 version. +  // +  std::unique_ptr<string> p (new string ("hello")); +  o.member (std::move (p));         // set, assumes ownership + +  p.reset (new string ("hello")); +  o.member ().set (std::move (p));  // set, assumes ownership + +  p = o.member ().detach ();        // detach, member is reset +  o.member ().set (std::move (p));  // re-attach + +  // C++98 version. +  // +  std::auto_ptr<string> p (new string ("hello")); +  o.member (p);                     // set, assumes ownership + +  p = new string ("hello"); +  o.member ().set (p);              // set, assumes ownership + +  p = o.member ().detach ();        // detach, member is reset +  o.member ().set (p);              // re-attach +} +  </pre> + + +  <h3><a name="2.8.3">2.8.3 Mapping for Members with the Sequence Cardinality Class</a></h3> + +   <p>For the Sequence cardinality class, the type definitions consist of an +      alias for the member's type with the name created by appending +      the <code>_type</code> suffix to the member's name, an alias of +      the container type with the name created by appending the +      <code>_sequence</code> suffix to the member's name, an alias of +      the iterator type with the name created by appending the +      <code>_iterator</code> suffix to the member's name, and an alias +      of the constant iterator type with the name created by appending the +      <code>_const_iterator</code> suffix to the member's name. +   </p> + +   <p>The accessor functions come in constant and non-constant versions. +      The constant accessor function returns a constant reference to the +      container and can be used for read-only access. The non-constant +      version returns an unrestricted reference to the container and can +      be used for read-write access. +   </p> + +   <p>The modifier function expects an argument of type reference to +      constant of the container type. The modifier function +      makes a deep copy of its argument. For instance: +   </p> + + +  <pre class="xml"> +<complexType name="object"> +  <sequence> +    <element name="member" type="string" minOccurs="unbounded"/> +  </sequence> +</complexType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class object: public xml_schema::type +{ +public: +  // Type definitions. +  // +  typedef xml_schema::string member_type; +  typedef sequence<member_type> member_sequence; +  typedef member_sequence::iterator member_iterator; +  typedef member_sequence::const_iterator member_const_iterator; + +  // Accessors. +  // +  const member_sequence& +  member () const; + +  member_sequence& +  member (); + +  // Modifier. +  // +  void +  member (const member_sequence&); + +  ... + +}; +  </pre> + +  <p>The <code>sequence</code> class template is defined in an +     implementation-specific namespace. It conforms to the +     sequence interface as defined by the ISO/ANSI Standard for +     C++ (ISO/IEC 14882:1998, Section 23.1.1, "Sequences"). +     Practically, this means that you can treat such a sequence +     as if it was <code>std::vector</code>. Two notable extensions +     to the standard interface that are available only for +     sequences of non-fundamental C++ types are the addition of +     the overloaded <code>push_back</code> and <code>insert</code> +     as well as the <code>detach_back</code> and <code>detach</code> +     member functions. The additional <code>push_back</code> and +     <code>insert</code> functions accept an automatic pointer +     (<code>std::unique_ptr</code> or <code>std::auto_ptr</code>, +     depending on the C++ standard selected) to the +     element type instead of the constant reference. They assume +     ownership of the pointed to object and reset the passed +     automatic pointer. The <code>detach_back</code> and +     <code>detach</code> functions detach the element +     value from the sequence container and, by default, remove +     the element from the sequence. These additional functions +     have the following signatures:</p> + +  <pre class="c++"> +template <typename X> +class sequence +{ +public: +  ... + +  void +  push_back (std::[unique|auto]_ptr<X>) + +  iterator +  insert (iterator position, std::[unique|auto]_ptr<X>) + +  std::[unique|auto]_ptr<X> +  detach_back (bool pop = true); + +  iterator +  detach (iterator position, +          std::[unique|auto]_ptr<X>& result, +          bool erase = true) + +  ... +} +  </pre> + +  <p>The following code shows how one could use this mapping:</p> + +  <pre class="c++"> +void +f (object& o) +{ +  using xml_schema::string; + +  object::member_sequence& s (o.member ()); + +  // Iteration. +  // +  for (object::member_iterator i (s.begin ()); i != s.end (); ++i) +  { +    string& value (*i); +  } + +  // Modification. +  // +  s.push_back ("hello");  // deep copy + +  // C++11 version. +  // +  std::unique_ptr<string> p (new string ("hello")); +  s.push_back (std::move (p)); // assumes ownership +  p = s.detach_back ();        // detach and pop +  s.push_back (std::move (p)); // re-append + +  // C++98 version. +  // +  std::auto_ptr<string> p (new string ("hello")); +  s.push_back (p);        // assumes ownership +  p = s.detach_back ();   // detach and pop +  s.push_back (p);        // re-append + +  // Setting a new container. +  // +  object::member_sequence n; +  n.push_back ("one"); +  n.push_back ("two"); +  o.member (n);           // deep copy +} +  </pre> + +  <h3><a name="2.8.4">2.8.4 Element Order</a></h3> + +  <p>C++/Tree is a "flattening" mapping in a sense that many levels of +     nested compositors (<code>choice</code> and <code>sequence</code>), +     all potentially with their own cardinalities, are in the end mapped +     to a flat set of elements with one of the three cardinality classes +     discussed in the previous sections. While this results in a simple +     and easy to use API for most types, in certain cases, the order of +     elements in the actual XML documents is not preserved once parsed +     into the object model. And sometimes such order has +     application-specific significance. As an example, consider a schema +     that defines a batch of bank transactions:</p> + +  <pre class="xml"> +<complexType name="withdraw"> +  <sequence> +    <element name="account" type="unsignedInt"/> +    <element name="amount" type="unsignedInt"/> +  </sequence> +</complexType> + +<complexType name="deposit"> +  <sequence> +    <element name="account" type="unsignedInt"/> +    <element name="amount" type="unsignedInt"/> +  </sequence> +</complexType> + +<complexType name="batch"> +  <choice minOccurs="0" maxOccurs="unbounded"> +    <element name="withdraw" type="withdraw"/> +    <element name="deposit" type="deposit"/> +  </choice> +</complexType> +  </pre> + +  <p>The batch can contain any number of transactions in any order +     but the order of transactions in each actual batch is significant. +     For instance, consider what could happen if we reorder the +     transactions and apply all the withdrawals before deposits.</p> + +  <p>For the <code>batch</code> schema type defined above the default +     C++/Tree mapping will produce a C++ class that contains a pair of +     sequence containers, one for each of the two elements. While this +     will capture the content (transactions), the order of this content +     as it appears in XML will be lost. Also, if we try to serialize the +     batch we just loaded back to XML, all the withdrawal transactions +     will appear before deposits.</p> + +  <p>To overcome this limitation of a flattening mapping, C++/Tree +     allows us to mark certain XML Schema types, for which content +     order is important, as ordered.</p> + +  <p>There are several command line options that control which +     schema types are treated as ordered. To make an individual +     type ordered, we use the <code>--ordered-type</code> option, +     for example:</p> + +  <pre class="term"> +--ordered-type batch +  </pre> + +  <p>To automatically treat all the types that are derived from an ordered +     type also ordered, we use the <code>--ordered-type-derived</code> +     option. This is primarily useful if you would like to iterate +     over the complete hierarchy's content using the content order +     sequence (discussed below).</p> + +  <p>Ordered types are also useful for handling mixed content. To +     automatically mark all the types with mixed content as ordered +     we use the <code>--ordered-type-mixed</code> option. For more +     information on handling mixed content see <a href="#2.13">Section +     2.13, "Mapping for Mixed Content Models"</a>.</p> + +  <p>Finally, we can mark all the types in the schema we are +     compiling with the <code>--ordered-type-all</code> option. +     You should only resort to this option if all the types in +     your schema truly suffer from the loss of content +     order since, as we will discuss shortly, ordered types +     require extra effort to access and, especially, modify. +     See the +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD +     Compiler Command Line Manual</a> for more information on +     these options.</p> + +  <p>Once a type is marked ordered, C++/Tree alters its mapping +     in several ways. Firstly, for each local element, element +     wildcard (<a href="#2.12.4">Section 2.12.4, "Element Wildcard +     Order"</a>), and mixed content text (<a href="#2.13">Section +     2.13, "Mapping for Mixed Content Models"</a>) in this type, a +     content id constant is generated. Secondly, an addition sequence +     is added to the class that captures the content order. Here +     is how the mapping of our <code>batch</code> class changes +     once we make it ordered:</p> + +  <pre class="c++"> +class batch: public xml_schema::type +{ +public: +  // withdraw +  // +  typedef withdraw withdraw_type; +  typedef sequence<withdraw_type> withdraw_sequence; +  typedef withdraw_sequence::iterator withdraw_iterator; +  typedef withdraw_sequence::const_iterator withdraw_const_iterator; + +  static const std::size_t withdraw_id = 1; + +  const withdraw_sequence& +  withdraw () const; + +  withdraw_sequence& +  withdraw (); + +  void +  withdraw (const withdraw_sequence&); + +  // deposit +  // +  typedef deposit deposit_type; +  typedef sequence<deposit_type> deposit_sequence; +  typedef deposit_sequence::iterator deposit_iterator; +  typedef deposit_sequence::const_iterator deposit_const_iterator; + +  static const std::size_t deposit_id = 2; + +  const deposit_sequence& +  deposit () const; + +  deposit_sequence& +  deposit (); + +  void +  deposit (const deposit_sequence&); + +  // content_order +  // +  typedef xml_schema::content_order content_order_type; +  typedef std::vector<content_order_type> content_order_sequence; +  typedef content_order_sequence::iterator content_order_iterator; +  typedef content_order_sequence::const_iterator content_order_const_iterator; + +  const content_order_sequence& +  content_order () const; + +  content_order_sequence& +  content_order (); + +  void +  content_order (const content_order_sequence&); + +  ... +}; +  </pre> + +  <p>Notice the <code>withdraw_id</code> and <code>deposit_id</code> +     content ids as well as the extra <code>content_order</code> +     sequence that does not correspond to any element in the +     schema definition. The other changes to the mapping for ordered +     types has to do with XML parsing and serialization code. During +     parsing the content order is captured in the <code>content_order</code> +     sequence while during serialization this sequence is used to +     determine the order in which content is serialized. The +     <code>content_order</code> sequence is also copied during +     copy construction and assigned during copy assignment. It is also +     taken into account during comparison.</p> + +  <p>The entry type of the <code>content_order</code> sequence is the +     <code>xml_schema::content_order</code> type that has the following +     interface:</p> + +  <pre class="c++"> +namespace xml_schema +{ +  struct content_order +  { +    content_order (std::size_t id, std::size_t index = 0); + +    std::size_t id; +    std::size_t index; +  }; + +  bool +  operator== (const content_order&, const content_order&); + +  bool +  operator!= (const content_order&, const content_order&); + +  bool +  operator< (const content_order&, const content_order&); +} +  </pre> + +  <p>The <code>content_order</code> sequence describes the order of +     content (elements, including wildcards, as well as mixed content +     text). Each entry in this sequence consists of the content id +     (for example, <code>withdraw_id</code> or <code>deposit_id</code> +     in our case) as well as, for elements of the sequence cardinality +     class, an index into the corresponding sequence container (the +     index is unused for the one and optional cardinality classes). +     For example, in our case, if the content id is <code>withdraw_id</code>, +     then the index will point into the <code>withdraw</code> element +     sequence.</p> + +  <p>With all this information we can now examine how to iterate over +     transaction in the batch in content order:</p> + +  <pre class="c++"> +batch& b = ... + +for (batch::content_order_const_iterator i (b.content_order ().begin ()); +     i != b.content_order ().end (); +     ++i) +{ +  switch (i->id) +  { +  case batch::withdraw_id: +    { +      const withdraw& t (b.withdraw ()[i->index]); +      cerr << t.account () << " withdraw " << t.amount () << endl; +      break; +    } +  case batch::deposit_id: +    { +      const deposit& t (b.deposit ()[i->index]); +      cerr << t.account () << " deposit " << t.amount () << endl; +      break; +    } +  default: +    { +      assert (false); // Unknown content id. +    } +  } +} +  </pre> + +  <p>If we serialized our batch back to XML, we would also see that the +     order of transactions in the output is exactly the same as in the +     input rather than all the withdrawals first followed by all the +     deposits.</p> + +  <p>The most complex aspect of working with ordered types is +     modifications. Now we not only need to change the content, +     but also remember to update the order information corresponding +     to this change. As a first example, we add a deposit transaction +     to the batch:</p> + +  <pre class="c++"> +using xml_schema::content_order; + +batch::deposit_sequence& d (b.deposit ()); +batch::withdraw_sequence& w (b.withdraw ()); +batch::content_order_sequence& co (b.content_order ()); + +d.push_back (deposit (123456789, 100000)); +co.push_back (content_order (batch::deposit_id, d.size () - 1)); +  </pre> + +  <p>In the above example we first added the content (deposit +     transaction) and then updated the content order information +     by adding an entry with <code>deposit_id</code> content +     id and the index of the just added deposit transaction.</p> + +  <p>Removing the last transaction can be easy if we know which +     transaction (deposit or withdrawal) is last:</p> + +  <pre class="c++"> +d.pop_back (); +co.pop_back (); +  </pre> + +  <p>If, however, we do not know which transaction is last, then +     things get a bit more complicated:</p> + +  <pre class="c++"> +switch (co.back ().id) +{ +case batch::withdraw_id: +  { +    d.pop_back (); +    break; +  } +case batch::deposit_id: +  { +    w.pop_back (); +    break; +  } +} + +co.pop_back (); +  </pre> + +  <p>The following example shows how to add a transaction at the +     beginning of the batch:</p> + +  <pre class="c++"> +w.push_back (withdraw (123456789, 100000)); +co.insert (co.begin (), +           content_order (batch::withdraw_id, w.size () - 1)); +  </pre> + +  <p>Note also that when we merely modify the content of one +     of the elements in place, we do not need to update its +     order since it doesn't change. For example, here is how +     we can change the amount in the first withdrawal:</p> + +  <pre class="c++"> +w[0].amount (10000); +  </pre> + +  <p>For the complete working code shown in this section refer to the +     <code>order/element</code> example in the +     <code>cxx/tree/</code> directory in the +     <a href="https://cppget.org/xsd-examples">xsd-examples</a> +     package.</p> + +  <p>If both the base and derived types are ordered, then the +     content order sequence is only added to the base and the content +     ids are unique within the whole hierarchy. In this case +     the content order sequence for the derived type contains +     ordering information for both base and derived content.</p> + +  <p>In some applications we may need to perform more complex +     content processing. For example, in our case, we may need +     to remove all the withdrawal transactions. The default +     container, <code>std::vector</code>, is not particularly +     suitable for such operations. What may be required by +     some applications is a multi-index container that not +     only allows us to iterate in content order similar to +     <code>std::vector</code> but also search by the content +     id as well as the content id and index pair.</p> + +  <p>While C++/Tree does not provide this functionality by +     default, it allows us to specify a custom container +     type for content order with the <code>--order-container</code> +     command line option. The only requirement from the +     generated code side for such a container is to provide +     the <code>vector</code>-like <code>push_back()</code>, +     <code>size()</code>, and const iteration interfaces.</p> + +  <p>As an example, here is how we can use the Boost Multi-Index +     container for content order. First we create the +     <code>content-order-container.hxx</code> header with the +     following definition:</p> + +  <pre class="c++"> +#ifndef CONTENT_ORDER_CONTAINER +#define CONTENT_ORDER_CONTAINER + +#include <cstddef> // std::size_t + +#include <boost/multi_index_container.hpp> +#include <boost/multi_index/member.hpp> +#include <boost/multi_index/identity.hpp> +#include <boost/multi_index/ordered_index.hpp> +#include <boost/multi_index/random_access_index.hpp> + +struct by_id {}; +struct by_id_index {}; + +template <typename T> +using content_order_container = +  boost::multi_index::multi_index_container< +    T, +    boost::multi_index::indexed_by< +      boost::multi_index::random_access<>, +      boost::multi_index::ordered_unique< +        boost::multi_index::tag<by_id_index>, +        boost::multi_index::identity<T> +      >, +      boost::multi_index::ordered_non_unique< +        boost::multi_index::tag<by_id>, +        boost::multi_index::member<T, std::size_t, &T::id> +      > +    > +  >; + +#endif +  </pre> + +  <p>Next we add the following two XSD compiler options to include +     this header into every generated header file and to use the +     custom container type (see the XSD compiler command line manual +     for more information on shell quoting for the first option):</p> + +  <pre class="term"> +--hxx-prologue '#include "content-order-container.hxx"' +--order-container content_order_container +  </pre> + +  <p>With these changes we can now use the multi-index functionality, +     for example, to search for a specific content id:</p> + +  <pre class="c++"> +typedef batch::content_order_sequence::index<by_id>::type id_set; +typedef id_set::iterator id_iterator; + +const id_set& ids (b.content_order ().get<by_id> ()); + +std::pair<id_iterator, id_iterator> r ( +  ids.equal_range (std::size_t (batch::deposit_id)); + +for (id_iterator i (r.first); i != r.second; ++i) +{ +  const deposit& t (b.deposit ()[i->index]); +  cerr << t.account () << " deposit " << t.amount () << endl; +} +  </pre> + +  <h2><a name="2.9">2.9 Mapping for Global Elements</a></h2> + +  <p>An XML Schema element definition is called global if it appears +     directly under the <code>schema</code> element. +     A global element is a valid root of an instance document. By +     default, a global element is mapped to a set of overloaded +     parsing and, optionally, serialization functions with the +     same name as the element. It is also possible to generate types +     for root elements instead of parsing and serialization functions. +     This is primarily useful to distinguish object models with the +     same root type but with different root elements. See +     <a href="#2.9.1">Section 2.9.1, "Element Types"</a> for details. +     It is also possible to request the generation of an element map +     which allows uniform parsing and serialization of multiple root +     elements. See <a href="#2.9.2">Section 2.9.2, "Element Map"</a> +     for details. +  </p> + +  <p>The parsing functions read XML instance documents and return +     corresponding object models as an automatic pointer +     (<code>std::unique_ptr</code> or <code>std::auto_ptr</code>, +     depending on the C++ standard selected). Their signatures +     have the following pattern (<code>type</code> denotes +     element's type and <code>name</code> denotes element's +     name): +  </p> + +  <pre class="c++"> +std::[unique|auto]_ptr<type> +name (....); +  </pre> + +  <p>The process of parsing, including the exact signatures of the parsing +     functions, is the subject of <a href="#3">Chapter 3, "Parsing"</a>. +  </p> + +  <p>The serialization functions write object models back to XML instance +     documents. Their signatures have the following pattern: +  </p> + +  <pre class="c++"> +void +name (<stream type>&, const type&, ....); +  </pre> + +  <p>The process of serialization, including the exact signatures of the +     serialization functions, is the subject of <a href="#4">Chapter 4, +     "Serialization"</a>. +  </p> + + +  <h3><a name="2.9.1">2.9.1 Element Types</a></h3> + +  <p>The generation of element types is requested with the +     <code>--generate-element-type</code> option. With this option +     each global element is mapped to a C++ class with the +     same name as the element. Such a class is derived from +     <code>xml_schema::element_type</code> and contains the same set +     of type definitions, constructors, and member function as would a +     type containing a single element with the One cardinality class +     named <code>"value"</code>. In addition, the element type also +     contains a set of member functions for accessing the element +     name and namespace as well as its value in a uniform manner. +     For example:</p> + +  <pre class="xml"> +<complexType name="type"> +  <sequence> +    ... +  </sequence> +</complexType> + +<element name="root" type="type"/> +  </pre> + +<p>is mapped to:</p> + +  <pre class="c++"> +class type +{ +  ... +}; + +class root: public xml_schema::element_type +{ +public: +  // Element value. +  // +  typedef type value_type; + +  const value_type& +  value () const; + +  value_type& +  value (); + +  void +  value (const value_type&); + +  void +  value (std::[unique|auto]_ptr<value_type>); + +  // Constructors. +  // +  root (const value_type&); + +  root (std::[unique|auto]_ptr<value_type>); + +  root (const xercesc::DOMElement&, xml_schema::flags = 0); + +  root (const root&, xml_schema::flags = 0); + +  virtual root* +  _clone (xml_schema::flags = 0) const; + +  // Element name and namespace. +  // +  static const std::string& +  name (); + +  static const std::string& +  namespace_ (); + +  virtual const std::string& +  _name () const; + +  virtual const std::string& +  _namespace () const; + +  // Element value as xml_schema::type. +  // +  virtual const xml_schema::type* +  _value () const; + +  virtual xml_schema::type* +  _value (); +}; + +void +operator<< (xercesc::DOMElement&, const root&); +  </pre> + +  <p>The <code>xml_schema::element_type</code> class is a common +     base type for all element types and is defined as follows:</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class element_type +  { +  public: +    virtual +    ~element_type (); + +    virtual element_type* +    _clone (flags f = 0) const = 0; + +    virtual const std::basic_string<C>& +    _name () const = 0; + +    virtual const std::basic_string<C>& +    _namespace () const = 0; + +    virtual xml_schema::type* +    _value () = 0; + +    virtual const xml_schema::type* +    _value () const = 0; +  }; +} +  </pre> + +  <p>The <code>_value()</code> member function returns a pointer to +     the element value or 0 if the element is of a fundamental C++ +     type and therefore is not derived from <code>xml_schema::type</code>. +  </p> + +  <p>Unlike parsing and serialization functions, element types +     are only capable of parsing and serializing from/to a +     <code>DOMElement</code> object. This means that the application +     will need to perform its own XML-to-DOM parsing and DOM-to-XML +     serialization. The following section describes a mechanism +     provided by the mapping to uniformly parse and serialize +     multiple root elements.</p> + + +  <h3><a name="2.9.2">2.9.2 Element Map</a></h3> + +  <p>When element types are generated for root elements it is also +     possible to request the generation of an element map with the +     <code>--generate-element-map</code> option. The element map +     allows uniform parsing and serialization of multiple root +     elements via the common <code>xml_schema::element_type</code> +     base type. The <code>xml_schema::element_map</code> class is +     defined as follows:</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class element_map +  { +  public: +    static std::[unique|auto]_ptr<xml_schema::element_type> +    parse (const xercesc::DOMElement&, flags = 0); + +    static void +    serialize (xercesc::DOMElement&, const element_type&); +  }; +} +  </pre> + +  <p>The <code>parse()</code> function creates the corresponding +     element type object based on the element name and namespace +     and returns it as an automatic pointer (<code>std::unique_ptr</code> +     or <code>std::auto_ptr</code>, depending on the C++ standard +     selected) to <code>xml_schema::element_type</code>. +     The <code>serialize()</code> function serializes the passed element +     object to <code>DOMElement</code>. Note that in case of +     <code>serialize()</code>, the <code>DOMElement</code> object +     should have the correct name and namespace. If no element type is +     available for an element, both functions throw the +     <code>xml_schema::no_element_info</code> exception:</p> + +  <pre class="c++"> +struct no_element_info: virtual exception +{ +  no_element_info (const std::basic_string<C>& element_name, +                   const std::basic_string<C>& element_namespace); + +  const std::basic_string<C>& +  element_name () const; + +  const std::basic_string<C>& +  element_namespace () const; + +  virtual const char* +  what () const throw (); +}; +  </pre> + +  <p>The application can discover the actual type of the element +     object returned by <code>parse()</code> either using +     <code>dynamic_cast</code> or by comparing element names and +     namespaces. The following code fragments illustrate how the +     element map can be used:</p> + +  <pre class="c++"> +// Parsing. +// +DOMElement& e = ... // Parse XML to DOM. + +unique_ptr<xml_schema::element_type> r ( +  xml_schema::element_map::parse (e)); + +if (root1 r1 = dynamic_cast<root1*> (r.get ())) +{ +  ... +} +else if (r->_name == root2::name () && +         r->_namespace () == root2::namespace_ ()) +{ +  root2& r2 (static_cast<root2&> (*r)); + +  ... +} +  </pre> + +  <pre class="c++"> +// Serialization. +// +xml_schema::element_type& r = ... + +string name (r._name ()); +string ns (r._namespace ()); + +DOMDocument& doc = ... // Create a new DOMDocument with name and ns. +DOMElement& e (*doc->getDocumentElement ()); + +xml_schema::element_map::serialize (e, r); + +// Serialize DOMDocument to XML. +  </pre> + +  <!-- --> + +  <h2><a name="2.10">2.10 Mapping for Global Attributes</a></h2> + +  <p>An XML Schema attribute definition is called global if it appears +     directly under the <code>schema</code> element. A global +     attribute does not have any mapping. +  </p> + +  <!-- +     When it is referenced from +     a local attribute definition (using the <code>ref</code> attribute) +     it is treated as a local attribute (see Section 2.8, "Mapping for +     Local Elements and Attributes"). +  --> + +  <h2><a name="2.11">2.11 Mapping for <code>xsi:type</code> and Substitution +      Groups</a></h2> + +  <p>The mapping provides optional support for the XML Schema polymorphism +     features (<code>xsi:type</code> and substitution groups) which can +     be requested with the <code>--generate-polymorphic</code> option. +     When used, the dynamic type of a member may be different from +     its static type. Consider the following schema definition and +     instance document: +  </p> + +  <pre class="xml"> +<!-- test.xsd --> +<schema> +  <complexType name="base"> +    <attribute name="text" type="string"/> +  </complexType> + +  <complexType name="derived"> +    <complexContent> +      <extension base="base"> +        <attribute name="extra-text" type="string"/> +      </extension> +    </complexContent> +  </complexType> + +  <complexType name="root_type"> +    <sequence> +      <element name="item" type="base" maxOccurs="unbounded"/> +    </sequence> +  </complexType> + +  <element name="root" type="root_type"/> +</schema> + +<!-- test.xml --> +<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> +  <item text="hello"/> +  <item text="hello" extra-text="world" xsi:type="derived"/> +</root> +  </pre> + +  <p>In the resulting object model, the container for +     the <code>root::item</code> member will have two elements: +     the first element's type will be <code>base</code> while +     the second element's (dynamic) type will be +     <code>derived</code>. This can be discovered using the +     <code>dynamic_cast</code> operator as shown in the following +     example: +  </p> + +  <pre class="c++"> +void +f (root& r) +{ +  for (root::item_const_iterator i (r.item ().begin ()); +       i != r.item ().end () +       ++i) +  { +    if (derived* d = dynamic_cast<derived*> (&(*i))) +    { +      // derived +    } +    else +    { +      // base +    } +  } +} +  </pre> + +  <p>The <code>_clone</code> virtual function should be used instead of +     copy constructors to make copies of members that might use +     polymorphism: +  </p> + +  <pre class="c++"> +void +f (root& r) +{ +  for (root::item_const_iterator i (r.item ().begin ()); +       i != r.item ().end () +       ++i) +  { +    std::unique_ptr<base> c (i->_clone ()); +  } +} +  </pre> + +  <p>The mapping can often automatically determine which types are +     polymorphic based on the substitution group declarations. However, +     if your XML vocabulary is not using substitution groups or if +     substitution groups are defined in a separate schema, then you will +     need to use the <code>--polymorphic-type</code> option to specify +     which types are polymorphic. When using this option you only need +     to specify the root of a polymorphic type hierarchy and the mapping +     will assume that all the derived types are also polymorphic. +     Also note that you need to specify this option when compiling every +     schema file that references the polymorphic type. Consider the following +     two schemas as an example:</p> + +  <pre class="xml"> +<!-- base.xsd --> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + +  <xs:complexType name="base"> +    <xs:sequence> +      <xs:element name="b" type="xs:int"/> +    </xs:sequence> +  </xs:complexType> + +  <!-- substitution group root --> +  <xs:element name="base" type="base"/> + +</xs:schema> +  </pre> + +  <pre class="xml"> +<!-- derived.xsd --> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + +  <include schemaLocation="base.xsd"/> + +  <xs:complexType name="derived"> +    <xs:complexContent> +      <xs:extension base="base"> +        <xs:sequence> +          <xs:element name="d" type="xs:string"/> +        </xs:sequence> +      </xs:extension> +    </xs:complexContent> +  </xs:complexType> + +  <xs:element name="derived" type="derived" substitutionGroup="base"/> + +</xs:schema> +  </pre> + +  <p>In this example we need to specify "<code>--polymorphic-type base</code>" +     when compiling both schemas because the substitution group is declared +     in a schema other than the one defining type <code>base</code>.</p> + +  <p>You can also indicate that all types should be treated as polymorphic +     with the <code>--polymorphic-type-all</code>. However, this may result +     in slower generated code with a greater footprint.</p> + + +  <!-- Mapping for any and anyAttribute --> + + +  <h2><a name="2.12">2.12 Mapping for <code>any</code> and <code>anyAttribute</code></a></h2> + +  <p>For the XML Schema <code>any</code> and <code>anyAttribute</code> +     wildcards an optional mapping can be requested with the +     <code>--generate-wildcard</code> option. The mapping represents +     the content matched by wildcards as DOM fragments. Because the +     DOM API is used to access such content, the Xerces-C++ runtime +     should be initialized by the application prior to parsing and +     should remain initialized for the lifetime of objects with +     the wildcard content. For more information on the Xerces-C++ +     runtime initialization see <a href="#3.1">Section 3.1, +     "Initializing the Xerces-C++ Runtime"</a>. +  </p> + +  <p>The mapping for <code>any</code> is similar to the mapping for +     local elements (see <a href="#2.8">Section 2.8, "Mapping for Local +     Elements and Attributes"</a>) except that the type used in the +     wildcard mapping is <code>xercesc::DOMElement</code>. As with local +     elements, the mapping divides all possible cardinality combinations +     into three cardinality classes: <i>one</i>, <i>optional</i>, and +     <i>sequence</i>. +  </p> + +  <p>The mapping for <code>anyAttribute</code> represents the attributes +     matched by this wildcard as a set of <code>xercesc::DOMAttr</code> +     objects with a key being the attribute's name and namespace.</p> + +  <p>Similar to local elements and attributes, the <code>any</code> and +     <code>anyAttribute</code> wildcards are mapped to a set of public type +     definitions (typedefs) and a set of public accessor and modifier +     functions. Type definitions have names derived from <code>"any"</code> +     for the <code>any</code> wildcard and <code>"any_attribute"</code> +     for the <code>anyAttribute</code> wildcard. The accessor and modifier +     functions are named <code>"any"</code> for the <code>any</code> wildcard +     and <code>"any_attribute"</code> for the <code>anyAttribute</code> +     wildcard. Subsequent wildcards in the same type have escaped names +     such as <code>"any1"</code> or <code>"any_attribute1"</code>. +  </p> + +  <p>Because Xerces-C++ DOM nodes always belong to a <code>DOMDocument</code>, +     each type with a wildcard has an associated <code>DOMDocument</code> +     object. The reference to this object can be obtained using the accessor +     function called <code>dom_document</code>. The access to the document +     object from the application code may be necessary to create or modify +     the wildcard content. For example: +  </p> + +  <pre class="xml"> +<complexType name="object"> +  <sequence> +    <any namespace="##other"/> +  </sequence> +  <anyAttribute namespace="##other"/> +</complexType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class object: public xml_schema::type +{ +public: +  // any +  // +  const xercesc::DOMElement& +  any () const; + +  void +  any (const xercesc::DOMElement&); + +  ... + +  // any_attribute +  // +  typedef attribute_set any_attribute_set; +  typedef any_attribute_set::iterator any_attribute_iterator; +  typedef any_attribute_set::const_iterator any_attribute_const_iterator; + +  const any_attribute_set& +  any_attribute () const; + +  any_attribute_set& +  any_attribute (); + +  ... + +  // DOMDocument object for wildcard content. +  // +  const xercesc::DOMDocument& +  dom_document () const; + +  xercesc::DOMDocument& +  dom_document (); + +  ... +}; +  </pre> + + +  <p>Names and semantics of type definitions for the wildcards as well +     as signatures of the accessor and modifier functions depend on the +     wildcard type as well as the cardinality class for the <code>any</code> +     wildcard. They are described in the following sub-sections. +  </p> + + +  <h3><a name="2.12.1">2.12.1 Mapping for <code>any</code> with the One Cardinality Class</a></h3> + +  <p>For <code>any</code> with the One cardinality class, +     there are no type definitions. The accessor functions come in +     constant and non-constant versions. The constant accessor function +     returns a constant reference to <code>xercesc::DOMElement</code> and +     can be used for read-only access. The non-constant version returns +     an unrestricted reference to <code>xercesc::DOMElement</code> and can +     be used for read-write access. +  </p> + +  <p>The first modifier function expects an argument of type reference +     to constant <code>xercesc::DOMElement</code> and makes a deep copy +     of its argument. The second modifier function expects an argument of +     type pointer to <code>xercesc::DOMElement</code>. This modifier +     function assumes ownership of its argument and expects the element +     object to be created using the DOM document associated with this +     instance. For example: +  </p> + +  <pre class="xml"> +<complexType name="object"> +  <sequence> +    <any namespace="##other"/> +  </sequence> +</complexType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class object: public xml_schema::type +{ +public: +  // Accessors. +  // +  const xercesc::DOMElement& +  any () const; + +  xercesc::DOMElement& +  any (); + +  // Modifiers. +  // +  void +  any (const xercesc::DOMElement&); + +  void +  any (xercesc::DOMElement*); + +  ... + +}; +  </pre> + + +  <p>The following code shows how one could use this mapping:</p> + +  <pre class="c++"> +void +f (object& o, const xercesc::DOMElement& e) +{ +  using namespace xercesc; + +  DOMElement& e1 (o.any ());             // get +  o.any (e)                              // set, deep copy +  DOMDocument& doc (o.dom_document ()); +  o.any (doc.createElement (...));       // set, assumes ownership +} +  </pre> + +  <h3><a name="2.12.2">2.12.2 Mapping for <code>any</code> with the Optional Cardinality Class</a></h3> + +  <p>For <code>any</code> with the Optional cardinality class, the type +     definitions consist of an alias for the container type with name +     <code>any_optional</code> (or <code>any1_optional</code>, etc., for +     subsequent wildcards in the type definition). +  </p> + +  <p>Unlike accessor functions for the One cardinality class, accessor +     functions for the Optional cardinality class return references to +     corresponding containers rather than directly to <code>DOMElement</code>. +     The accessor functions come in constant and non-constant versions. +     The constant accessor function returns a constant reference to +     the container and can be used for read-only access. The non-constant +     version returns an unrestricted reference to the container +     and can be used for read-write access. +  </p> + +  <p>The modifier functions are overloaded for <code>xercesc::DOMElement</code> +     and the container type. The first modifier function expects an argument of +     type reference to constant <code>xercesc::DOMElement</code> and +     makes a deep copy of its argument. The second modifier function +     expects an argument of type pointer to <code>xercesc::DOMElement</code>. +     This modifier function assumes ownership of its argument and expects +     the element object to be created using the DOM document associated +     with this instance. The third modifier function expects an argument +     of type reference to constant of the container type and makes a +     deep copy of its argument. For instance: +  </p> + +  <pre class="xml"> +<complexType name="object"> +  <sequence> +    <any namespace="##other" minOccurs="0"/> +  </sequence> +</complexType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class object: public xml_schema::type +{ +public: +  // Type definitions. +  // +  typedef element_optional any_optional; + +  // Accessors. +  // +  const any_optional& +  any () const; + +  any_optional& +  any (); + +  // Modifiers. +  // +  void +  any (const xercesc::DOMElement&); + +  void +  any (xercesc::DOMElement*); + +  void +  any (const any_optional&); + +  ... + +}; +  </pre> + + +  <p>The <code>element_optional</code> container is a +     specialization of the <code>optional</code> class template described +     in <a href="#2.8.2">Section 2.8.2, "Mapping for Members with the Optional +     Cardinality Class"</a>. Its interface is presented below: +  </p> + +  <pre class="c++"> +class element_optional +{ +public: +  explicit +  element_optional (xercesc::DOMDocument&); + +  // Makes a deep copy. +  // +  element_optional (const xercesc::DOMElement&, xercesc::DOMDocument&); + +  // Assumes ownership. +  // +  element_optional (xercesc::DOMElement*, xercesc::DOMDocument&); + +  element_optional (const element_optional&, xercesc::DOMDocument&); + +public: +  element_optional& +  operator= (const xercesc::DOMElement&); + +  element_optional& +  operator= (const element_optional&); + +  // Pointer-like interface. +  // +public: +  const xercesc::DOMElement* +  operator-> () const; + +  xercesc::DOMElement* +  operator-> (); + +  const xercesc::DOMElement& +  operator* () const; + +  xercesc::DOMElement& +  operator* (); + +  typedef void (element_optional::*bool_convertible) (); +  operator bool_convertible () const; + +  // Get/set interface. +  // +public: +  bool +  present () const; + +  const xercesc::DOMElement& +  get () const; + +  xercesc::DOMElement& +  get (); + +  // Makes a deep copy. +  // +  void +  set (const xercesc::DOMElement&); + +  // Assumes ownership. +  // +  void +  set (xercesc::DOMElement*); + +  void +  reset (); +}; + +bool +operator== (const element_optional&, const element_optional&); + +bool +operator!= (const element_optional&, const element_optional&); +  </pre> + + +  <p>The following code shows how one could use this mapping:</p> + +  <pre class="c++"> +void +f (object& o, const xercesc::DOMElement& e) +{ +  using namespace xercesc; + +  DOMDocument& doc (o.dom_document ()); + +  if (o.any ().present ())                  // test +  { +    DOMElement& e1 (o.any ().get ());       // get +    o.any ().set (e);                       // set, deep copy +    o.any ().set (doc.createElement (...)); // set, assumes ownership +    o.any ().reset ();                      // reset +  } + +  // Same as above but using pointer notation: +  // +  if (o.member ())                          // test +  { +    DOMElement& e1 (*o.any ());             // get +    o.any (e);                              // set, deep copy +    o.any (doc.createElement (...));        // set, assumes ownership +    o.any ().reset ();                      // reset +  } +} +  </pre> + + + +  <h3><a name="2.12.3">2.12.3 Mapping for <code>any</code> with the Sequence Cardinality Class</a></h3> + +  <p>For <code>any</code> with the Sequence cardinality class, the type +     definitions consist of an alias of the container type with name +     <code>any_sequence</code> (or <code>any1_sequence</code>, etc., for +     subsequent wildcards in the type definition), an alias of the iterator +     type with name <code>any_iterator</code> (or <code>any1_iterator</code>, +     etc., for subsequent wildcards in the type definition), and an alias +     of the constant iterator type with name <code>any_const_iterator</code> +     (or <code>any1_const_iterator</code>, etc., for subsequent wildcards +     in the type definition). +  </p> + +  <p>The accessor functions come in constant and non-constant versions. +     The constant accessor function returns a constant reference to the +     container and can be used for read-only access. The non-constant +     version returns an unrestricted reference to the container and can +     be used for read-write access. +  </p> + +  <p>The modifier function expects an argument of type reference to +     constant of the container type. The modifier function makes +     a deep copy of its argument. For instance: +  </p> + + +  <pre class="xml"> +<complexType name="object"> +  <sequence> +    <any namespace="##other" minOccurs="unbounded"/> +  </sequence> +</complexType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class object: public xml_schema::type +{ +public: +  // Type definitions. +  // +  typedef element_sequence any_sequence; +  typedef any_sequence::iterator any_iterator; +  typedef any_sequence::const_iterator any_const_iterator; + +  // Accessors. +  // +  const any_sequence& +  any () const; + +  any_sequence& +  any (); + +  // Modifier. +  // +  void +  any (const any_sequence&); + +  ... + +}; +  </pre> + +  <p>The <code>element_sequence</code> container is a +     specialization of the <code>sequence</code> class template described +     in <a href="#2.8.3">Section 2.8.3, "Mapping for Members with the +     Sequence Cardinality Class"</a>. Its interface is similar to +     the sequence interface as defined by the ISO/ANSI Standard for +     C++ (ISO/IEC 14882:1998, Section 23.1.1, "Sequences") and is +     presented below: +  </p> + +  <pre class="c++"> +class element_sequence +{ +public: +  typedef xercesc::DOMElement        value_type; +  typedef xercesc::DOMElement*       pointer; +  typedef const xercesc::DOMElement* const_pointer; +  typedef xercesc::DOMElement&       reference; +  typedef const xercesc::DOMElement& const_reference; + +  typedef <implementation-defined>   iterator; +  typedef <implementation-defined>   const_iterator; +  typedef <implementation-defined>   reverse_iterator; +  typedef <implementation-defined>   const_reverse_iterator; + +  typedef <implementation-defined>   size_type; +  typedef <implementation-defined>   difference_type; +  typedef <implementation-defined>   allocator_type; + +public: +  explicit +  element_sequence (xercesc::DOMDocument&); + +  // DOMElement cannot be default-constructed. +  // +  // explicit +  // element_sequence (size_type n); + +  element_sequence (size_type n, +                    const xercesc::DOMElement&, +                    xercesc::DOMDocument&); + +  template <typename I> +  element_sequence (const I& begin, +                    const I& end, +                    xercesc::DOMDocument&); + +  element_sequence (const element_sequence&, xercesc::DOMDocument&); + +  element_sequence& +  operator= (const element_sequence&); + +public: +  void +  assign (size_type n, const xercesc::DOMElement&); + +  template <typename I> +  void +  assign (const I& begin, const I& end); + +public: +  // This version of resize can only be used to shrink the +  // sequence because DOMElement cannot be default-constructed. +  // +  void +  resize (size_type); + +  void +  resize (size_type, const xercesc::DOMElement&); + +public: +  size_type +  size () const; + +  size_type +  max_size () const; + +  size_type +  capacity () const; + +  bool +  empty () const; + +  void +  reserve (size_type); + +  void +  clear (); + +public: +  const_iterator +  begin () const; + +  const_iterator +  end () const; + +  iterator +  begin (); + +  iterator +  end (); + +  const_reverse_iterator +  rbegin () const; + +  const_reverse_iterator +  rend () const + +    reverse_iterator +  rbegin (); + +  reverse_iterator +  rend (); + +public: +  xercesc::DOMElement& +  operator[] (size_type); + +  const xercesc::DOMElement& +  operator[] (size_type) const; + +  xercesc::DOMElement& +  at (size_type); + +  const xercesc::DOMElement& +  at (size_type) const; + +  xercesc::DOMElement& +  front (); + +  const xercesc::DOMElement& +  front () const; + +  xercesc::DOMElement& +  back (); + +  const xercesc::DOMElement& +  back () const; + +public: +  // Makes a deep copy. +  // +  void +  push_back (const xercesc::DOMElement&); + +  // Assumes ownership. +  // +  void +  push_back (xercesc::DOMElement*); + +  void +  pop_back (); + +  // Makes a deep copy. +  // +  iterator +  insert (iterator position, const xercesc::DOMElement&); + +  // Assumes ownership. +  // +  iterator +  insert (iterator position, xercesc::DOMElement*); + +  void +  insert (iterator position, size_type n, const xercesc::DOMElement&); + +  template <typename I> +  void +  insert (iterator position, const I& begin, const I& end); + +  iterator +  erase (iterator position); + +  iterator +  erase (iterator begin, iterator end); + +public: +  // Note that the DOMDocument object of the two sequences being +  // swapped should be the same. +  // +  void +  swap (sequence& x); +}; + +inline bool +operator== (const element_sequence&, const element_sequence&); + +inline bool +operator!= (const element_sequence&, const element_sequence&); +  </pre> + + +  <p>The following code shows how one could use this mapping:</p> + +  <pre class="c++"> +void +f (object& o, const xercesc::DOMElement& e) +{ +  using namespace xercesc; + +  object::any_sequence& s (o.any ()); + +  // Iteration. +  // +  for (object::any_iterator i (s.begin ()); i != s.end (); ++i) +  { +    DOMElement& e (*i); +  } + +  // Modification. +  // +  s.push_back (e);                       // deep copy +  DOMDocument& doc (o.dom_document ()); +  s.push_back (doc.createElement (...)); // assumes ownership +} +  </pre> + +  <h3><a name="2.12.4">2.12.4 Element Wildcard Order</a></h3> + +  <p>Similar to elements, element wildcards in ordered types +     (<a href="#2.8.4">Section 2.8.4, "Element Order"</a>) are assigned +     content ids and are included in the content order sequence. +     Continuing with the bank transactions example started in Section +     2.8.4, we can extend the batch by allowing custom transactions:</p> + +  <pre class="xml"> +<complexType name="batch"> +  <choice minOccurs="0" maxOccurs="unbounded"> +    <element name="withdraw" type="withdraw"/> +    <element name="deposit" type="deposit"/> +    <any namespace="##other" processContents="lax"/> +  </choice> +</complexType> +  </pre> + +  <p>This will lead to the following changes in the generated +     <code>batch</code> C++ class:</p> + +  <pre class="c++"> +class batch: public xml_schema::type +{ +public: +  ... + +  // any +  // +  typedef element_sequence any_sequence; +  typedef any_sequence::iterator any_iterator; +  typedef any_sequence::const_iterator any_const_iterator; + +  static const std::size_t any_id = 3UL; + +  const any_sequence& +  any () const; + +  any_sequence& +  any (); + +  void +  any (const any_sequence&); + +  ... +}; +  </pre> + +  <p>With this change we also need to update the iteration code to handle +     the new content id:</p> + +  <pre class="c++"> +for (batch::content_order_const_iterator i (b.content_order ().begin ()); +     i != b.content_order ().end (); +     ++i) +{ +  switch (i->id) +  { +    ... + +  case batch::any_id: +    { +      const DOMElement& e (b.any ()[i->index]); +      ... +      break; +    } + +    ... +  } +} +  </pre> + +  <p>For the complete working code that shows the use of wildcards in +     ordered types refer to the <code>order/element</code> example in +     the <code>cxx/tree/</code> directory in the +     <a href="https://cppget.org/xsd-examples">xsd-examples</a> +     package.</p> + +  <h3><a name="2.12.5">2.12.5 Mapping for <code>anyAttribute</code></a></h3> + +  <p>For <code>anyAttribute</code> the type definitions consist of an alias +     of the container type with name <code>any_attribute_set</code> +     (or <code>any1_attribute_set</code>, etc., for subsequent wildcards +     in the type definition), an alias of the iterator type with name +     <code>any_attribute_iterator</code> (or <code>any1_attribute_iterator</code>, +     etc., for subsequent wildcards in the type definition), and an alias +     of the constant iterator type with name <code>any_attribute_const_iterator</code> +     (or <code>any1_attribute_const_iterator</code>, etc., for subsequent +     wildcards in the type definition). +  </p> + +  <p>The accessor functions come in constant and non-constant versions. +     The constant accessor function returns a constant reference to the +     container and can be used for read-only access. The non-constant +     version returns an unrestricted reference to the container and can +     be used for read-write access. +  </p> + +  <p>The modifier function expects an argument of type reference to +     constant of the container type. The modifier function makes +     a deep copy of its argument. For instance: +  </p> + + +  <pre class="xml"> +<complexType name="object"> +  <sequence> +    ... +  </sequence> +  <anyAttribute namespace="##other"/> +</complexType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class object: public xml_schema::type +{ +public: +  // Type definitions. +  // +  typedef attribute_set any_attribute_set; +  typedef any_attribute_set::iterator any_attribute_iterator; +  typedef any_attribute_set::const_iterator any_attribute_const_iterator; + +  // Accessors. +  // +  const any_attribute_set& +  any_attribute () const; + +  any_attribute_set& +  any_attribute (); + +  // Modifier. +  // +  void +  any_attribute (const any_attribute_set&); + +  ... + +}; +  </pre> + +  <p>The <code>attribute_set</code> class is an associative container +     similar to the <code>std::set</code> class template as defined by +     the ISO/ANSI Standard for C++ (ISO/IEC 14882:1998, Section 23.3.3, +     "Class template set") with the key being the attribute's name +     and namespace. Unlike <code>std::set</code>, <code>attribute_set</code> +     allows searching using names and namespaces instead of +     <code>xercesc::DOMAttr</code> objects. It is defined in an +     implementation-specific namespace and its interface is presented +     below: +  </p> + +  <pre class="c++"> +class attribute_set +{ +public: +  typedef xercesc::DOMAttr         key_type; +  typedef xercesc::DOMAttr         value_type; +  typedef xercesc::DOMAttr*        pointer; +  typedef const xercesc::DOMAttr*  const_pointer; +  typedef xercesc::DOMAttr&        reference; +  typedef const xercesc::DOMAttr&  const_reference; + +  typedef <implementation-defined> iterator; +  typedef <implementation-defined> const_iterator; +  typedef <implementation-defined> reverse_iterator; +  typedef <implementation-defined> const_reverse_iterator; + +  typedef <implementation-defined> size_type; +  typedef <implementation-defined> difference_type; +  typedef <implementation-defined> allocator_type; + +public: +  attribute_set (xercesc::DOMDocument&); + +  template <typename I> +  attribute_set (const I& begin, const I& end, xercesc::DOMDocument&); + +  attribute_set (const attribute_set&, xercesc::DOMDocument&); + +  attribute_set& +  operator= (const attribute_set&); + +public: +  const_iterator +  begin () const; + +  const_iterator +  end () const; + +  iterator +  begin (); + +  iterator +  end (); + +  const_reverse_iterator +  rbegin () const; + +  const_reverse_iterator +  rend () const; + +  reverse_iterator +  rbegin (); + +  reverse_iterator +  rend (); + +public: +  size_type +  size () const; + +  size_type +  max_size () const; + +  bool +  empty () const; + +  void +  clear (); + +public: +  // Makes a deep copy. +  // +  std::pair<iterator, bool> +  insert (const xercesc::DOMAttr&); + +  // Assumes ownership. +  // +  std::pair<iterator, bool> +  insert (xercesc::DOMAttr*); + +  // Makes a deep copy. +  // +  iterator +  insert (iterator position, const xercesc::DOMAttr&); + +  // Assumes ownership. +  // +  iterator +  insert (iterator position, xercesc::DOMAttr*); + +  template <typename I> +  void +  insert (const I& begin, const I& end); + +public: +  void +  erase (iterator position); + +  size_type +  erase (const std::basic_string<C>& name); + +  size_type +  erase (const std::basic_string<C>& namespace_, +         const std::basic_string<C>& name); + +  size_type +  erase (const XMLCh* name); + +  size_type +  erase (const XMLCh* namespace_, const XMLCh* name); + +  void +  erase (iterator begin, iterator end); + +public: +  size_type +  count (const std::basic_string<C>& name) const; + +  size_type +  count (const std::basic_string<C>& namespace_, +         const std::basic_string<C>& name) const; + +  size_type +  count (const XMLCh* name) const; + +  size_type +  count (const XMLCh* namespace_, const XMLCh* name) const; + +  iterator +  find (const std::basic_string<C>& name); + +  iterator +  find (const std::basic_string<C>& namespace_, +        const std::basic_string<C>& name); + +  iterator +  find (const XMLCh* name); + +  iterator +  find (const XMLCh* namespace_, const XMLCh* name); + +  const_iterator +  find (const std::basic_string<C>& name) const; + +  const_iterator +  find (const std::basic_string<C>& namespace_, +        const std::basic_string<C>& name) const; + +  const_iterator +  find (const XMLCh* name) const; + +  const_iterator +  find (const XMLCh* namespace_, const XMLCh* name) const; + +public: +  // Note that the DOMDocument object of the two sets being +  // swapped should be the same. +  // +  void +  swap (attribute_set&); +}; + +bool +operator== (const attribute_set&, const attribute_set&); + +bool +operator!= (const attribute_set&, const attribute_set&); +  </pre> + +  <p>The following code shows how one could use this mapping:</p> + +  <pre class="c++"> +void +f (object& o, const xercesc::DOMAttr& a) +{ +  using namespace xercesc; + +  object::any_attribute_set& s (o.any_attribute ()); + +  // Iteration. +  // +  for (object::any_attribute_iterator i (s.begin ()); i != s.end (); ++i) +  { +    DOMAttr& a (*i); +  } + +  // Modification. +  // +  s.insert (a);                         // deep copy +  DOMDocument& doc (o.dom_document ()); +  s.insert (doc.createAttribute (...)); // assumes ownership + +  // Searching. +  // +  object::any_attribute_iterator i (s.find ("name")); +  i = s.find ("http://www.w3.org/XML/1998/namespace", "lang"); +} +  </pre> + +  <!-- Mapping for Mixed Content Models --> + +  <h2><a name="2.13">2.13 Mapping for Mixed Content Models</a></h2> + +  <p>For XML Schema types with mixed content models C++/Tree provides +     mapping support only if the type is marked as ordered +     (<a href="#2.8.4">Section 2.8.4, "Element Order"</a>). Use the +     <code>--ordered-type-mixed</code> XSD compiler option to +     automatically mark all types with mixed content as ordered.</p> + +  <p>For an ordered type with mixed content, C++/Tree adds an extra +     text content sequence that is used to store the text fragments. +     This text content sequence is also assigned the content id and +     its entries are included in the content order sequence, just +     like elements. As a result, it is possible to capture the order +     between elements and text fragments.</p> + +  <p>As an example, consider the following schema that describes text +     with embedded links:</p> + +  <pre class="xml"> +<complexType name="anchor"> +  <simpleContent> +    <extension base="string"> +      <attribute name="href" type="anyURI" use="required"/> +    </extension> +  </simpleContent> +</complexType> + +<complexType name="text" mixed="true"> +  <sequence> +    <element name="a" type="anchor" minOccurs="0" maxOccurs="unbounded"/> +  </sequence> +</complexType> +  </pre> + +  <p>The generated <code>text</code> C++ class will provide the following +     API (assuming it is marked as ordered):</p> + +  <pre class="c++"> +class text: public xml_schema::type +{ +public: +  // a +  // +  typedef anchor a_type; +  typedef sequence<a_type> a_sequence; +  typedef a_sequence::iterator a_iterator; +  typedef a_sequence::const_iterator a_const_iterator; + +  static const std::size_t a_id = 1UL; + +  const a_sequence& +  a () const; + +  a_sequence& +  a (); + +  void +  a (const a_sequence&); + +  // text_content +  // +  typedef xml_schema::string text_content_type; +  typedef sequence<text_content_type> text_content_sequence; +  typedef text_content_sequence::iterator text_content_iterator; +  typedef text_content_sequence::const_iterator text_content_const_iterator; + +  static const std::size_t text_content_id = 2UL; + +  const text_content_sequence& +  text_content () const; + +  text_content_sequence& +  text_content (); + +  void +  text_content (const text_content_sequence&); + +  // content_order +  // +  typedef xml_schema::content_order content_order_type; +  typedef std::vector<content_order_type> content_order_sequence; +  typedef content_order_sequence::iterator content_order_iterator; +  typedef content_order_sequence::const_iterator content_order_const_iterator; + +  const content_order_sequence& +  content_order () const; + +  content_order_sequence& +  content_order (); + +  void +  content_order (const content_order_sequence&); + +  ... +}; +  </pre> + +  <p>Given this interface we can iterate over both link elements +     and text in content order. The following code fragment converts +     our format to plain text with references.</p> + +  <pre class="c++"> +const text& t = ... + +for (text::content_order_const_iterator i (t.content_order ().begin ()); +     i != t.content_order ().end (); +     ++i) +{ +  switch (i->id) +  { +  case text::a_id: +    { +      const anchor& a (t.a ()[i->index]); +      cerr << a << "[" << a.href () << "]"; +      break; +    } +  case text::text_content_id: +    { +      const xml_schema::string& s (t.text_content ()[i->index]); +      cerr << s; +      break; +    } +  default: +    { +      assert (false); // Unknown content id. +    } +  } +} +  </pre> + +  <p>For the complete working code that shows the use of mixed content +     in ordered types refer to the <code>order/mixed</code> example in +     the <code>cxx/tree/</code> directory in the +     <a href="https://cppget.org/xsd-examples">xsd-examples</a> +     package.</p> + +  <!-- Parsing --> + + +  <h1><a name="3">3 Parsing</a></h1> + +  <p>This chapter covers various aspects of parsing XML instance +     documents in order to obtain corresponding tree-like object +     model. +  </p> + +  <p>Each global XML Schema element in the form:</p> + +  <pre class="xml"> +<element name="name" type="type"/> +  </pre> + +  <p>is mapped to 14 overloaded C++ functions in the form:</p> + +  <pre class="c++"> +// Read from a URI or a local file. +// + +std::[unique|auto]_ptr<type> +name (const std::basic_string<C>& uri, +      xml_schema::flags = 0, +      const xml_schema::properties& = xml_schema::properties ()); + +std::[unique|auto]_ptr<type> +name (const std::basic_string<C>& uri, +      xml_schema::error_handler&, +      xml_schema::flags = 0, +      const xml_schema::properties& = xml_schema::properties ()); + +std::[unique|auto]_ptr<type> +name (const std::basic_string<C>& uri, +      xercesc::DOMErrorHandler&, +      xml_schema::flags = 0, +      const xml_schema::properties& = xml_schema::properties ()); + + +// Read from std::istream. +// + +std::[unique|auto]_ptr<type> +name (std::istream&, +      xml_schema::flags = 0, +      const xml_schema::properties& = xml_schema::properties ()); + +std::[unique|auto]_ptr<type> +name (std::istream&, +      xml_schema::error_handler&, +      xml_schema::flags = 0, +      const xml_schema::properties& = xml_schema::properties ()); + +std::[unique|auto]_ptr<type> +name (std::istream&, +      xercesc::DOMErrorHandler&, +      xml_schema::flags = 0, +      const xml_schema::properties& = xml_schema::properties ()); + + +std::[unique|auto]_ptr<type> +name (std::istream&, +      const std::basic_string<C>& id, +      xml_schema::flags = 0, +      const xml_schema::properties& = xml_schema::properties ()); + +std::[unique|auto]_ptr<type> +name (std::istream&, +      const std::basic_string<C>& id, +      xml_schema::error_handler&, +      xml_schema::flags = 0, +      const xml_schema::properties& = xml_schema::properties ()); + +std::[unique|auto]_ptr<type> +name (std::istream&, +      const std::basic_string<C>& id, +      xercesc::DOMErrorHandler&, +      xml_schema::flags = 0, +      const xml_schema::properties& = xml_schema::properties ()); + + +// Read from InputSource. +// + +std::[unique|auto]_ptr<type> +name (xercesc::InputSource&, +      xml_schema::flags = 0, +      const xml_schema::properties& = xml_schema::properties ()); + +std::[unique|auto]_ptr<type> +name (xercesc::InputSource&, +      xml_schema::error_handler&, +      xml_schema::flags = 0, +      const xml_schema::properties& = xml_schema::properties ()); + +std::[unique|auto]_ptr<type> +name (xercesc::InputSource&, +      xercesc::DOMErrorHandler&, +      xml_schema::flags = 0, +      const xml_schema::properties& = xml_schema::properties ()); + + +// Read from DOM. +// + +std::[unique|auto]_ptr<type> +name (const xercesc::DOMDocument&, +      xml_schema::flags = 0, +      const xml_schema::properties& = xml_schema::properties ()); + +std::[unique|auto]_ptr<type> +name (xml_schema::dom::[unique|auto]_ptr<xercesc::DOMDocument>, +      xml_schema::flags = 0, +      const xml_schema::properties& = xml_schema::properties ()); +  </pre> + +  <p>You can choose between reading an XML instance from a local file, +     URI, <code>std::istream</code>, <code>xercesc::InputSource</code>, +     or a pre-parsed DOM instance in the form of +     <code>xercesc::DOMDocument</code>. All the parsing functions +     return a dynamically allocated object model as either +     <code>std::unique_ptr</code> or <code>std::auto_ptr</code>, +     depending on the C++ standard selected. Each of these parsing +     functions is discussed in more detail in the following sections. +  </p> + +  <h2><a name="3.1">3.1 Initializing the Xerces-C++ Runtime</a></h2> + +  <p>Some parsing functions expect you to initialize the Xerces-C++ +     runtime while others initialize and terminate it as part of their +     work. The general rule is as follows: if a function has any arguments +     or return a value that is an instance of a Xerces-C++ type, then +     this function expects you to initialize the Xerces-C++ runtime. +     Otherwise, the function initializes and terminates the runtime for +     you. Note that it is legal to have nested calls to the Xerces-C++ +     initialize and terminate functions as long as the calls are balanced. +  </p> + +  <p>You can instruct parsing functions that initialize and terminate +     the runtime not to do so by passing the +     <code>xml_schema::flags::dont_initialize</code> flag (see +     <a href="#3.2">Section 3.2, "Flags and Properties"</a>). +  </p> + + +  <h2><a name="3.2">3.2 Flags and Properties</a></h2> + +  <p>Parsing flags and properties are the last two arguments of every +     parsing function. They allow you to fine-tune the process of +     instance validation and parsing. Both arguments are optional. +  </p> + + +  <p>The following flags are recognized by the parsing functions:</p> + +  <dl> +    <dt><code>xml_schema::flags::keep_dom</code></dt> +    <dd>Keep association between DOM nodes and the resulting +        object model nodes. For more information about DOM association +        refer to <a href="#5.1">Section 5.1, "DOM Association"</a>.</dd> + +    <dt><code>xml_schema::flags::own_dom</code></dt> +    <dd>Assume ownership of the DOM document passed. This flag only +        makes sense together with the <code>keep_dom</code> flag in +        the call to the parsing function with the +        <code>xml_schema::dom::[unique|auto]_ptr<DOMDocument></code> +        argument.</dd> + +    <dt><code>xml_schema::flags::dont_validate</code></dt> +    <dd>Do not validate instance documents against schemas.</dd> + +    <dt><code>xml_schema::flags::dont_initialize</code></dt> +    <dd>Do not initialize the Xerces-C++ runtime.</dd> +  </dl> + +  <p>You can pass several flags by combining them using the bit-wise OR +     operator. For example:</p> + +  <pre class="c++"> +using xml_schema::flags; + +std::unique_ptr<type> r ( +  name ("test.xml", flags::keep_dom | flags::dont_validate)); +  </pre> + +  <p>By default, validation of instance documents is turned on even +     though parsers generated by XSD do not assume instance +     documents are valid. They include a number of checks that prevent +     construction of inconsistent object models. This, +     however, does not mean that an instance document that was +     successfully parsed by the XSD-generated parsers is +     valid per the corresponding schema. If an instance document is not +     "valid enough" for the generated parsers to construct consistent +     object model, one of the exceptions defined in +     <code>xml_schema</code> namespace is thrown (see +     <a href="#3.3">Section 3.3, "Error Handling"</a>). +  </p> + +  <p>For more information on the Xerces-C++ runtime initialization +     refer to <a href="#3.1">Section 3.1, "Initializing the Xerces-C++ +     Runtime"</a>. +  </p> + +  <p>The <code>xml_schema::properties</code> class allows you to +     programmatically specify schema locations to be used instead +     of those specified with the <code>xsi::schemaLocation</code> +     and <code>xsi::noNamespaceSchemaLocation</code> attributes +     in instance documents. The interface of the <code>properties</code> +     class is presented below: +  </p> + +  <pre class="c++"> +class properties +{ +public: +  void +  schema_location (const std::basic_string<C>& namespace_, +                   const std::basic_string<C>& location); +  void +  no_namespace_schema_location (const std::basic_string<C>& location); +}; +  </pre> + +  <p>Note that all locations are relative to an instance document unless +     they are URIs. For example, if you want to use a local file as your +     schema, then you will need to pass +     <code>file:///absolute/path/to/your/schema</code> as the location +     argument. +  </p> + +  <h2><a name="3.3">3.3 Error Handling</a></h2> + +  <p>As discussed in <a href="#2.2">Section 2.2, "Error Handling"</a>, +     the mapping uses the C++ exception handling mechanism as its primary +     way of reporting error conditions. However, to handle recoverable +     parsing and validation errors and warnings, a callback interface maybe +     preferred by the application.</p> + +  <p>To better understand error handling and reporting strategies employed +     by the parsing functions, it is useful to know that the +     transformation of an XML instance document to a statically-typed +     tree happens in two stages. The first stage, performed by Xerces-C++, +     consists of parsing an XML document into a DOM instance. For short, +     we will call this stage the XML-DOM stage. Validation, if not disabled, +     happens during this stage. The second stage, +     performed by the generated parsers, consist of parsing the DOM +     instance into the statically-typed tree. We will call this stage +     the DOM-Tree stage. Additional checks are performed during this +     stage in order to prevent construction of inconsistent tree which +     could otherwise happen when validation is disabled, for example.</p> + +  <p>All parsing functions except the one that operates on a DOM instance +     come in overloaded triples. The first function in such a triple +     reports error conditions exclusively by throwing exceptions. It +     accumulates all the parsing and validation errors of the XML-DOM +     stage and throws them in a single instance of the +     <code>xml_schema::parsing</code> exception (described below). +     The second and the third functions in the triple use callback +     interfaces to report parsing and validation errors and warnings. +     The two callback interfaces are <code>xml_schema::error_handler</code> +     and <code>xercesc::DOMErrorHandler</code>. For more information +     on the <code>xercesc::DOMErrorHandler</code> interface refer to +     the Xerces-C++ documentation. The <code>xml_schema::error_handler</code> +     interface is presented below: +  </p> + +  <pre class="c++"> +class error_handler +{ +public: +  struct severity +  { +    enum value +    { +      warning, +      error, +      fatal +    }; +  }; + +  virtual bool +  handle (const std::basic_string<C>& id, +          unsigned long line, +          unsigned long column, +          severity, +          const std::basic_string<C>& message) = 0; + +  virtual +  ~error_handler (); +}; +  </pre> + +  <p>The <code>id</code> argument of the <code>error_handler::handle</code> +     function identifies the resource being parsed (e.g., a file name or +     URI). +  </p> + +  <p>By returning <code>true</code> from the <code>handle</code> function +     you instruct the parser to recover and continue parsing. Returning +     <code>false</code> results in termination of the parsing process. +     An error with the <code>fatal</code> severity level results in +     termination of the parsing process no matter what is returned from +     the <code>handle</code> function. It is safe to throw an exception +     from the <code>handle</code> function. +  </p> + +  <p>The DOM-Tree stage reports error conditions exclusively by throwing +     exceptions. Individual exceptions thrown by the parsing functions +     are described in the following sub-sections. +  </p> + + +  <h3><a name="3.3.1">3.3.1 <code>xml_schema::parsing</code></a></h3> + +  <pre class="c++"> +struct severity +{ +  enum value +  { +    warning, +    error +  }; + +  severity (value); +  operator value () const; +}; + +struct error +{ +  error (severity, +         const std::basic_string<C>& id, +         unsigned long line, +         unsigned long column, +         const std::basic_string<C>& message); + +  severity +  severity () const; + +  const std::basic_string<C>& +  id () const; + +  unsigned long +  line () const; + +  unsigned long +  column () const; + +  const std::basic_string<C>& +  message () const; +}; + +std::basic_ostream<C>& +operator<< (std::basic_ostream<C>&, const error&); + +struct diagnostics: std::vector<error> +{ +}; + +std::basic_ostream<C>& +operator<< (std::basic_ostream<C>&, const diagnostics&); + +struct parsing: virtual exception +{ +  parsing (); +  parsing (const diagnostics&); + +  const diagnostics& +  diagnostics () const; + +  virtual const char* +  what () const throw (); +}; +  </pre> + +  <p>The <code>xml_schema::parsing</code> exception is thrown if there +     were parsing or validation errors reported during the XML-DOM stage. +     If no callback interface was provided to the parsing function, the +     exception contains a list of errors and warnings accessible using +     the <code>diagnostics</code> function. The usual conditions when +     this exception is thrown include malformed XML instances and, if +     validation is turned on, invalid instance documents. +  </p> + +  <h3><a name="3.3.2">3.3.2 <code>xml_schema::expected_element</code></a></h3> + +  <pre class="c++"> +struct expected_element: virtual exception +{ +  expected_element (const std::basic_string<C>& name, +                    const std::basic_string<C>& namespace_); + + +  const std::basic_string<C>& +  name () const; + +  const std::basic_string<C>& +  namespace_ () const; + + +  virtual const char* +  what () const throw (); +}; +  </pre> + +  <p>The <code>xml_schema::expected_element</code> exception is thrown +     when an expected element is not encountered by the DOM-Tree stage. +     The name and namespace of the expected element can be obtained using +     the <code>name</code> and <code>namespace_</code> functions respectively. +  </p> + + +  <h3><a name="3.3.3">3.3.3 <code>xml_schema::unexpected_element</code></a></h3> + +  <pre class="c++"> +struct unexpected_element: virtual exception +{ +  unexpected_element (const std::basic_string<C>& encountered_name, +                      const std::basic_string<C>& encountered_namespace, +                      const std::basic_string<C>& expected_name, +                      const std::basic_string<C>& expected_namespace) + + +  const std::basic_string<C>& +  encountered_name () const; + +  const std::basic_string<C>& +  encountered_namespace () const; + + +  const std::basic_string<C>& +  expected_name () const; + +  const std::basic_string<C>& +  expected_namespace () const; + + +  virtual const char* +  what () const throw (); +}; +  </pre> + +  <p>The <code>xml_schema::unexpected_element</code> exception is thrown +     when an unexpected element is encountered by the DOM-Tree stage. +     The name and namespace of the encountered element can be obtained +     using the <code>encountered_name</code> and +     <code>encountered_namespace</code> functions respectively. If an +     element was expected instead of the encountered one, its name +     and namespace can be obtained using the <code>expected_name</code> and +     <code>expected_namespace</code> functions respectively. Otherwise +     these functions return empty strings. +  </p> + +  <h3><a name="3.3.4">3.3.4 <code>xml_schema::expected_attribute</code></a></h3> + +  <pre class="c++"> +struct expected_attribute: virtual exception +{ +  expected_attribute (const std::basic_string<C>& name, +                      const std::basic_string<C>& namespace_); + + +  const std::basic_string<C>& +  name () const; + +  const std::basic_string<C>& +  namespace_ () const; + + +  virtual const char* +  what () const throw (); +}; +  </pre> + +  <p>The <code>xml_schema::expected_attribute</code> exception is thrown +     when an expected attribute is not encountered by the DOM-Tree stage. +     The name and namespace of the expected attribute can be obtained using +     the <code>name</code> and <code>namespace_</code> functions respectively. +  </p> + + +  <h3><a name="3.3.5">3.3.5 <code>xml_schema::unexpected_enumerator</code></a></h3> + +  <pre class="c++"> +struct unexpected_enumerator: virtual exception +{ +  unexpected_enumerator (const std::basic_string<C>& enumerator); + +  const std::basic_string<C>& +  enumerator () const; + +  virtual const char* +  what () const throw (); +}; +  </pre> + +  <p>The <code>xml_schema::unexpected_enumerator</code> exception is thrown +     when an unexpected enumerator is encountered by the DOM-Tree stage. +     The enumerator can be obtained using the <code>enumerator</code> +     functions. +  </p> + +  <h3><a name="3.3.6">3.3.6 <code>xml_schema::expected_text_content</code></a></h3> + +  <pre class="c++"> +struct expected_text_content: virtual exception +{ +  virtual const char* +  what () const throw (); +}; +  </pre> + +  <p>The <code>xml_schema::expected_text_content</code> exception is thrown +     when a content other than text is encountered and the text content was +     expected by the DOM-Tree stage. +  </p> + +  <h3><a name="3.3.7">3.3.7 <code>xml_schema::no_type_info</code></a></h3> + +  <pre class="c++"> +struct no_type_info: virtual exception +{ +  no_type_info (const std::basic_string<C>& type_name, +                const std::basic_string<C>& type_namespace); + +  const std::basic_string<C>& +  type_name () const; + +  const std::basic_string<C>& +  type_namespace () const; + +  virtual const char* +  what () const throw (); +}; +  </pre> + +  <p>The <code>xml_schema::no_type_info</code> exception is thrown +     when there is no type information associated with a type specified +     by the <code>xsi:type</code> attribute. This exception is thrown +     by the DOM-Tree stage. The name and namespace of the type in question +     can be obtained using the <code>type_name</code> and +     <code>type_namespace</code> functions respectively. Usually, catching +     this exception means that you haven't linked the code generated +     from the schema defining the type in question with your application +     or this schema has been compiled without the +     <code>--generate-polymorphic</code> option. +  </p> + + +  <h3><a name="3.3.8">3.3.8 <code>xml_schema::not_derived</code></a></h3> + +  <pre class="c++"> +struct not_derived: virtual exception +{ +  not_derived (const std::basic_string<C>& base_type_name, +               const std::basic_string<C>& base_type_namespace, +               const std::basic_string<C>& derived_type_name, +               const std::basic_string<C>& derived_type_namespace); + +  const std::basic_string<C>& +  base_type_name () const; + +  const std::basic_string<C>& +  base_type_namespace () const; + + +  const std::basic_string<C>& +  derived_type_name () const; + +  const std::basic_string<C>& +  derived_type_namespace () const; + +  virtual const char* +  what () const throw (); +}; +  </pre> + +  <p>The <code>xml_schema::not_derived</code> exception is thrown +     when a type specified by the <code>xsi:type</code> attribute is +     not derived from the expected base type. This exception is thrown +     by the DOM-Tree stage. The name and namespace of the expected +     base type can be obtained using the <code>base_type_name</code> and +     <code>base_type_namespace</code> functions respectively. The name +     and namespace of the offending type can be obtained using the +     <code>derived_type_name</code> and +     <code>derived_type_namespace</code> functions respectively. +  </p> + +  <h3><a name="3.3.9">3.3.9 <code>xml_schema::no_prefix_mapping</code></a></h3> + +  <pre class="c++"> +struct no_prefix_mapping: virtual exception +{ +  no_prefix_mapping (const std::basic_string<C>& prefix); + +  const std::basic_string<C>& +  prefix () const; + +  virtual const char* +  what () const throw (); +}; +  </pre> + +  <p>The <code>xml_schema::no_prefix_mapping</code> exception is thrown +     during the DOM-Tree stage if a namespace prefix is encountered for +     which a prefix-namespace mapping hasn't been provided. The namespace +     prefix in question can be obtained using the <code>prefix</code> +     function. +  </p> + +  <h2><a name="3.4">3.4 Reading from a Local File or URI</a></h2> + +  <p>Using a local file or URI is the simplest way to parse an XML instance. +     For example:</p> + +  <pre class="c++"> +using std::unique_ptr; + +unique_ptr<type> r1 (name ("test.xml")); +unique_ptr<type> r2 (name ("https://www.codesynthesis.com/test.xml")); +  </pre> + +  <p>Or, in the C++98 mode:</p> + +  <pre class="c++"> +using std::auto_ptr; + +auto_ptr<type> r1 (name ("test.xml")); +auto_ptr<type> r2 (name ("https://www.codesynthesis.com/test.xml")); +  </pre> + +  <h2><a name="3.5">3.5 Reading from <code>std::istream</code></a></h2> + +  <p>When using an <code>std::istream</code> instance, you may also +     pass an optional resource id. This id is used to identify the +     resource (for example in error messages) as well as to resolve +     relative paths. For instance:</p> + +  <pre class="c++"> +using std::unique_ptr; + +{ +  std::ifstream ifs ("test.xml"); +  unique_ptr<type> r (name (ifs, "test.xml")); +} + +{ +  std::string str ("..."); // Some XML fragment. +  std::istringstream iss (str); +  unique_ptr<type> r (name (iss)); +} +  </pre> + +  <h2><a name="3.6">3.6 Reading from <code>xercesc::InputSource</code></a></h2> + +  <p>Reading from a <code>xercesc::InputSource</code> instance +     is similar to the <code>std::istream</code> case except +     the resource id is maintained by the <code>InputSource</code> +     object. For instance:</p> + +  <pre class="c++"> +xercesc::StdInInputSource is; +std::unique_ptr<type> r (name (is)); +  </pre> + +  <h2><a name="3.7">3.7 Reading from DOM</a></h2> + +  <p>Reading from a <code>xercesc::DOMDocument</code> instance allows +     you to setup a custom XML-DOM stage. Things like DOM +     parser reuse, schema pre-parsing, and schema caching can be achieved +     with this approach. For more information on how to obtain DOM +     representation from an XML instance refer to the Xerces-C++ +     documentation. In addition, the +     <a href="http://wiki.codesynthesis.com/Tree/FAQ">C++/Tree Mapping +     FAQ</a> shows how to parse an XML instance to a Xerces-C++ +     DOM document using the XSD runtime utilities. +  </p> + +  <p>The last parsing function is useful when you would like to perform +     your own XML-to-DOM parsing and associate the resulting DOM document +     with the object model nodes. The automatic <code>DOMDocument</code> +     pointer is reset and the resulting object model assumes ownership +     of the DOM document passed. For example:</p> + +  <pre class="c++"> +// C++11 version. +// +xml_schema::dom::unique_ptr<xercesc::DOMDocument> doc = ... + +std::unique_ptr<type> r ( +  name (std::move (doc), +        xml_schema::flags::keep_dom | xml_schema::flags::own_dom)); + +// At this point doc is reset to 0. + +// C++98 version. +// +xml_schema::dom::auto_ptr<xercesc::DOMDocument> doc = ... + +std::auto_ptr<type> r ( +  name (doc, xml_schema::flags::keep_dom | xml_schema::flags::own_dom)); + +// At this point doc is reset to 0. +  </pre> + +  <h1><a name="4">4 Serialization</a></h1> + +  <p>This chapter covers various aspects of serializing a +     tree-like object model to DOM or XML. +     In this regard, serialization is complimentary to the reverse +     process of parsing a DOM or XML instance into an object model +     which is discussed in <a href="#3">Chapter 3, +     "Parsing"</a>. Note that the generation of the serialization code +     is optional and should be explicitly requested with the +     <code>--generate-serialization</code> option. See the +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD +     Compiler Command Line Manual</a> for more information. +  </p> + +  <p>Each global XML Schema element in the form: +  </p> + + +  <pre class="xml"> +<xsd:element name="name" type="type"/> +  </pre> + +  <p>is mapped to 8 overloaded C++ functions in the form:</p> + +  <pre class="c++"> +// Serialize to std::ostream. +// +void +name (std::ostream&, +      const type&, +      const xml_schema::namespace_fomap& = +        xml_schema::namespace_infomap (), +      const std::basic_string<C>& encoding = "UTF-8", +      xml_schema::flags = 0); + +void +name (std::ostream&, +      const type&, +      xml_schema::error_handler&, +      const xml_schema::namespace_infomap& = +        xml_schema::namespace_infomap (), +      const std::basic_string<C>& encoding = "UTF-8", +      xml_schema::flags = 0); + +void +name (std::ostream&, +      const type&, +      xercesc::DOMErrorHandler&, +      const xml_schema::namespace_infomap& = +        xml_schema::namespace_infomap (), +      const std::basic_string<C>& encoding = "UTF-8", +      xml_schema::flags = 0); + + +// Serialize to XMLFormatTarget. +// +void +name (xercesc::XMLFormatTarget&, +      const type&, +      const xml_schema::namespace_infomap& = +        xml_schema::namespace_infomap (), +      const std::basic_string<C>& encoding = "UTF-8", +      xml_schema::flags = 0); + +void +name (xercesc::XMLFormatTarget&, +      const type&, +      xml_schema::error_handler&, +      const xml_schema::namespace_infomap& = +        xml_schema::namespace_infomap (), +      const std::basic_string<C>& encoding = "UTF-8", +      xml_schema::flags = 0); + +void +name (xercesc::XMLFormatTarget&, +      const type&, +      xercesc::DOMErrorHandler&, +      const xml_schema::namespace_infomap& = +        xml_schema::namespace_infomap (), +      const std::basic_string<C>& encoding = "UTF-8", +      xml_schema::flags = 0); + + +// Serialize to DOM. +// +xml_schema::dom::[unique|auto]_ptr<xercesc::DOMDocument> +name (const type&, +      const xml_schema::namespace_infomap& +        xml_schema::namespace_infomap (), +      xml_schema::flags = 0); + +void +name (xercesc::DOMDocument&, +      const type&, +      xml_schema::flags = 0); +  </pre> + +  <p>You can choose between writing XML to <code>std::ostream</code> or +     <code>xercesc::XMLFormatTarget</code> and creating a DOM instance +     in the form of <code>xercesc::DOMDocument</code>. Serialization +     to <code>ostream</code> or <code>XMLFormatTarget</code> requires a +     considerably less work while serialization to DOM provides +     for greater flexibility. Each of these serialization functions +     is discussed in more detail in the following sections. +  </p> + + +  <h2><a name="4.1">4.1 Initializing the Xerces-C++ Runtime</a></h2> + +  <p>Some serialization functions expect you to initialize the Xerces-C++ +     runtime while others initialize and terminate it as part of their +     work. The general rule is as follows: if a function has any arguments +     or return a value that is an instance of a Xerces-C++ type, then +     this function expects you to initialize the Xerces-C++ runtime. +     Otherwise, the function initializes and terminates the runtime for +     you. Note that it is legal to have nested calls to the Xerces-C++ +     initialize and terminate functions as long as the calls are balanced. +  </p> + +  <p>You can instruct serialization functions that initialize and terminate +     the runtime not to do so by passing the +     <code>xml_schema::flags::dont_initialize</code> flag (see +     <a href="#4.3">Section 4.3, "Flags"</a>). +  </p> + +  <h2><a name="4.2">4.2 Namespace Infomap and Character Encoding</a></h2> + +  <p>When a document being serialized uses XML namespaces, custom +     prefix-namespace associations can to be established. If custom +     prefix-namespace mapping is not provided then generic prefixes +     (<code>p1</code>, <code>p2</code>, etc) are automatically assigned +     to namespaces as needed. Also, if +     you would like the resulting instance document to contain the +     <code>schemaLocation</code> or <code>noNamespaceSchemaLocation</code> +     attributes, you will need to provide namespace-schema associations. +     The <code>xml_schema::namespace_infomap</code> class is used +     to capture this information:</p> + +  <pre class="c++"> +struct namespace_info +{ +  namespace_info (); +  namespace_info (const std::basic_string<C>& name, +                  const std::basic_string<C>& schema); + +  std::basic_string<C> name; +  std::basic_string<C> schema; +}; + +// Map of namespace prefix to namespace_info. +// +struct namespace_infomap: public std::map<std::basic_string<C>, +                                          namespace_info> +{ +}; +  </pre> + +  <p>Consider the following associations as an example:</p> + +  <pre class="c++"> +xml_schema::namespace_infomap map; + +map["t"].name = "https://www.codesynthesis.com/test"; +map["t"].schema = "test.xsd"; +  </pre> + +  <p>This map, if passed to one of the serialization functions, +     could result in the following XML fragment:</p> + +  <pre class="xml"> +<?xml version="1.0" ?> +<t:name xmlns:t="https://www.codesynthesis.com/test" +        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +        xsi:schemaLocation="https://www.codesynthesis.com/test test.xsd"> +  </pre> + +  <p>As you can see, the serialization function automatically added namespace +     mapping for the <code>xsi</code> prefix. You can change this by +     providing your own prefix:</p> + +  <pre class="c++"> +xml_schema::namespace_infomap map; + +map["xsn"].name = "http://www.w3.org/2001/XMLSchema-instance"; + +map["t"].name = "https://www.codesynthesis.com/test"; +map["t"].schema = "test.xsd"; +  </pre> + +  <p>This could result in the following XML fragment:</p> + +  <pre class="xml"> +<?xml version="1.0" ?> +<t:name xmlns:t="https://www.codesynthesis.com/test" +        xmlns:xsn="http://www.w3.org/2001/XMLSchema-instance" +        xsn:schemaLocation="https://www.codesynthesis.com/test test.xsd"> +  </pre> + +  <p>To specify the location of a schema without a namespace you can use +     an empty prefix as in the example below: </p> + +  <pre class="c++"> +xml_schema::namespace_infomap map; + +map[""].schema = "test.xsd"; +  </pre> + +  <p>This would result in the following XML fragment:</p> + +  <pre class="xml"> +<?xml version="1.0" ?> +<name xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +      xsi:noNamespaceSchemaLocation="test.xsd"> +  </pre> + +  <p>To make a particular namespace default you can use an empty +     prefix, for example:</p> + +  <pre class="c++"> +xml_schema::namespace_infomap map; + +map[""].name = "https://www.codesynthesis.com/test"; +map[""].schema = "test.xsd"; +  </pre> + +  <p>This could result in the following XML fragment:</p> + +  <pre class="xml"> +<?xml version="1.0" ?> +<name xmlns="https://www.codesynthesis.com/test" +      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +      xsi:schemaLocation="https://www.codesynthesis.com/test test.xsd"> +  </pre> + + +  <p>Another bit of information that you can pass to the serialization +     functions is the character encoding method that you would like to use. +     Common values for this argument are <code>"US-ASCII"</code>, +     <code>"ISO8859-1"</code>, <code>"UTF-8"</code>, +     <code>"UTF-16BE"</code>, <code>"UTF-16LE"</code>, +     <code>"UCS-4BE"</code>, and <code>"UCS-4LE"</code>. The default +     encoding is <code>"UTF-8"</code>. For more information on +     encoding methods see the +     "<a href="http://en.wikipedia.org/wiki/Character_code">Character +     Encoding</a>" article from Wikipedia. +  </p> + +  <h2><a name="4.3">4.3 Flags</a></h2> + +  <p>Serialization flags are the last argument of every serialization +     function. They allow you to fine-tune the process of serialization. +     The flags argument is optional. +  </p> + + +  <p>The following flags are recognized by the serialization +     functions:</p> + +  <dl> +    <dt><code>xml_schema::flags::dont_initialize</code></dt> +    <dd>Do not initialize the Xerces-C++ runtime.</dd> + +    <dt><code>xml_schema::flags::dont_pretty_print</code></dt> +    <dd>Do not add extra spaces or new lines that make the resulting XML +        slightly bigger but easier to read.</dd> + +    <dt><code>xml_schema::flags::no_xml_declaration</code></dt> +    <dd>Do not write XML declaration (<?xml ... ?>).</dd> +  </dl> + +  <p>You can pass several flags by combining them using the bit-wise OR +     operator. For example:</p> + +  <pre class="c++"> +std::unique_ptr<type> r = ... +std::ofstream ofs ("test.xml"); +xml_schema::namespace_infomap map; +name (ofs, +      *r, +      map, +      "UTF-8", +      xml_schema::flags::no_xml_declaration | +      xml_schema::flags::dont_pretty_print); +  </pre> + +  <p>For more information on the Xerces-C++ runtime initialization +     refer to <a href="#4.1">Section 4.1, "Initializing the Xerces-C++ +     Runtime"</a>. +  </p> + +  <h2><a name="4.4">4.4 Error Handling</a></h2> + +  <p>As with the parsing functions (see <a href="#3.3">Section 3.3, +     "Error Handling"</a>), to better understand error handling and +     reporting strategies employed by the serialization functions, it +     is useful to know that the transformation of a statically-typed +     tree to an XML instance document happens in two stages. The first +     stage, performed by the generated code, consist of building a DOM +     instance from the statically-typed tree . For short, we will call +     this stage the Tree-DOM stage. The second stage, performed by +     Xerces-C++, consists of serializing the DOM instance into the XML +     document. We will call this stage the DOM-XML stage. +  </p> + +  <p>All serialization functions except the two that serialize into +     a DOM instance come in overloaded triples. The first function +     in such a triple reports error conditions exclusively by throwing +     exceptions. It accumulates all the serialization errors of the +     DOM-XML stage and throws them in a single instance of the +     <code>xml_schema::serialization</code> exception (described below). +     The second and the third functions in the triple use callback +     interfaces to report serialization errors and warnings. The two +     callback interfaces are <code>xml_schema::error_handler</code> and +     <code>xercesc::DOMErrorHandler</code>. The +     <code>xml_schema::error_handler</code> interface is described in +     <a href="#3.3">Section 3.3, "Error Handling"</a>. For more information +     on the <code>xercesc::DOMErrorHandler</code> interface refer to the +     Xerces-C++ documentation. +  </p> + +  <p>The Tree-DOM stage reports error conditions exclusively by throwing +     exceptions. Individual exceptions thrown by the serialization functions +     are described in the following sub-sections. +  </p> + +  <h3><a name="4.4.1">4.4.1 <code>xml_schema::serialization</code></a></h3> + +  <pre class="c++"> +struct serialization: virtual exception +{ +  serialization (); +  serialization (const diagnostics&); + +  const diagnostics& +  diagnostics () const; + +  virtual const char* +  what () const throw (); +}; +  </pre> + +  <p>The <code>xml_schema::diagnostics</code> class is described in +     <a href="#3.3.1">Section 3.3.1, "<code>xml_schema::parsing</code>"</a>. +     The <code>xml_schema::serialization</code> exception is thrown if +     there were serialization errors reported during the DOM-XML stage. +     If no callback interface was provided to the serialization function, +     the exception contains a list of errors and warnings accessible using +     the <code>diagnostics</code> function. +  </p> + + +  <h3><a name="4.4.2">4.4.2 <code>xml_schema::unexpected_element</code></a></h3> + +  <p>The <code>xml_schema::unexpected_element</code> exception is +     described in <a href="#3.3.3">Section 3.3.3, +     "<code>xml_schema::unexpected_element</code>"</a>. It is thrown +     by the serialization functions during the Tree-DOM stage if the +     root element name of the provided DOM instance does not match with +     the name of the element this serialization function is for. +  </p> + +  <h3><a name="4.4.3">4.4.3 <code>xml_schema::no_type_info</code></a></h3> + +  <p>The <code>xml_schema::no_type_info</code> exception is +     described in <a href="#3.3.7">Section 3.3.7, +     "<code>xml_schema::no_type_info</code>"</a>. It is thrown +     by the serialization functions during the Tree-DOM stage when there +     is no type information associated with a dynamic type of an +     element. Usually, catching this exception means that you haven't +     linked the code generated from the schema defining the type in +     question with your application or this schema has been compiled +     without the <code>--generate-polymorphic</code> option. +  </p> + +  <h2><a name="4.5">4.5 Serializing to <code>std::ostream</code></a></h2> + +  <p>In order to serialize to <code>std::ostream</code> you will need +     an object model, an output stream and, optionally, a namespace +     infomap. For instance:</p> + +  <pre class="c++"> +// Obtain the object model. +// +std::unique_ptr<type> r = ... + +// Prepare namespace mapping and schema location information. +// +xml_schema::namespace_infomap map; + +map["t"].name = "https://www.codesynthesis.com/test"; +map["t"].schema = "test.xsd"; + +// Write it out. +// +name (std::cout, *r, map); +  </pre> + +  <p>Note that the output stream is treated as a binary stream. This +     becomes important when you use a character encoding that is wider +     than 8-bit <code>char</code>, for instance UTF-16 or UCS-4. For +     example, things will most likely break if you try to serialize +     to <code>std::ostringstream</code> with UTF-16 or UCS-4 as an +     encoding. This is due to the special value, +     <code>'\0'</code>, that will most likely occur as part of such +     serialization and it won't have the special meaning assumed by +     <code>std::ostringstream</code>. +  </p> + + +  <h2><a name="4.6">4.6 Serializing to <code>xercesc::XMLFormatTarget</code></a></h2> + +  <p>Serializing to an <code>xercesc::XMLFormatTarget</code> instance +     is similar the <code>std::ostream</code> case. For instance: +  </p> + +  <pre class="c++"> +using std::unique_ptr; + +// Obtain the object model. +// +unique_ptr<type> r = ... + +// Prepare namespace mapping and schema location information. +// +xml_schema::namespace_infomap map; + +map["t"].name = "https://www.codesynthesis.com/test"; +map["t"].schema = "test.xsd"; + +using namespace xercesc; + +XMLPlatformUtils::Initialize (); + +{ +  // Choose a target. +  // +  unique_ptr<XMLFormatTarget> ft; + +  if (argc != 2) +  { +    ft = unique_ptr<XMLFormatTarget> (new StdOutFormatTarget ()); +  } +  else +  { +    ft = unique_ptr<XMLFormatTarget> ( +      new LocalFileFormatTarget (argv[1])); +  } + +  // Write it out. +  // +  name (*ft, *r, map); +} + +XMLPlatformUtils::Terminate (); +  </pre> + +  <p>Note that we had to initialize the Xerces-C++ runtime before we +     could call this serialization function.</p> + +  <h2><a name="4.7">4.7 Serializing to DOM</a></h2> + +  <p>The mapping provides two overloaded functions that implement +     serialization to a DOM instance. The first creates a DOM instance +     for you and the second serializes to an existing DOM instance. +     While serializing to a new DOM instance is similar to serializing +     to <code>std::ostream</code> or <code>xercesc::XMLFormatTarget</code>, +     serializing to an existing DOM instance requires quite a bit of work +     from your side. You will need to set all the custom namespace mapping +     attributes as well as the <code>schemaLocation</code> and/or +     <code>noNamespaceSchemaLocation</code> attributes. The following +     listing should give you an idea about what needs to be done: +  </p> + +  <pre class="c++"> +// Obtain the object model. +// +std::unique_ptr<type> r = ... + +using namespace xercesc; + +XMLPlatformUtils::Initialize (); + +{ +  // Create a DOM instance. Set custom namespace mapping and schema +  // location attributes. +  // +  DOMDocument& doc = ... + +  // Serialize to DOM. +  // +  name (doc, *r); + +  // Serialize the DOM document to XML. +  // +  ... +} + +XMLPlatformUtils::Terminate (); +  </pre> + +  <p>For more information on how to create and serialize a DOM instance +     refer to the Xerces-C++ documentation. In addition, the +     <a href="http://wiki.codesynthesis.com/Tree/FAQ">C++/Tree Mapping +     FAQ</a> shows how to implement these operations using the XSD +     runtime utilities. +  </p> + +  <h1><a name="5">5 Additional Functionality</a></h1> + +  <p>The C++/Tree mapping provides a number of optional features +     that can be useful in certain situations. They are described +     in the following sections.</p> + +  <h2><a name="5.1">5.1 DOM Association</a></h2> + +  <p>Normally, after parsing is complete, the DOM document which +     was used to extract the data is discarded. However, the parsing +     functions can be instructed to preserve the DOM document +     and create an association between the DOM nodes and object model +     nodes. When there is an association between the DOM and +     object model nodes, you can obtain the corresponding DOM element +     or attribute node from an object model node as well as perform +     the reverse transition: obtain the corresponding object model +     from a DOM element or attribute node.</p> + +  <p>Maintaining DOM association is normally useful when the application +     needs access to XML constructs that are not preserved in the +     object model, for example, XML comments. +     Another useful aspect of DOM association is the ability of the +     application to navigate the document tree using the generic DOM +     interface (for example, with the help of an XPath processor) +     and then move back to the statically-typed object model. Note +     also that while you can change the underlying DOM document, +     these changes are not reflected in the object model and will +     be ignored during serialization. If you need to not only access +     but also modify some aspects of XML that are not preserved in +     the object model, then type customization with custom parsing +     constructors and serialization operators should be used instead.</p> + +  <p>To request DOM association you will need to pass the +     <code>xml_schema::flags::keep_dom</code> flag to one of the +     parsing functions (see <a href="#3.2">Section 3.2, +     "Flags and Properties"</a> for more information). In this case the +     DOM document is retained and will be released when the object model +     is deleted. Note that since DOM nodes "out-live" the parsing function +     call, you need to initialize the Xerces-C++ runtime before calling +     one of the parsing functions with the <code>keep_dom</code> flag and +     terminate it after the object model is destroyed (see +     <a href="#3.1">Section 3.1, "Initializing the Xerces-C++ Runtime"</a>).</p> + +   <p>If the <code>keep_dom</code> flag is passed +      as the second argument to the copy constructor and the copy +      being made is of a complete tree, then the DOM association +      is also maintained in the copy by cloning the underlying +      DOM document and reestablishing the associations. For example:</p> + +  <pre class="c++"> +using namespace xercesc; + +XMLPlatformUtils::Initialize (); + +{ +  // Parse XML to object model. +  // +  std::unique_ptr<type> r (root ( +    "root.xml", +     xml_schema::flags::keep_dom | +     xml_schema::flags::dont_initialize)); + +   // Copy without DOM association. +   // +   type copy1 (*r); + +   // Copy with DOM association. +   // +   type copy2 (*r, xml_schema::flags::keep_dom); +} + +XMLPlatformUtils::Terminate (); +  </pre> + + +  <p>To obtain the corresponding DOM node from an object model node +     you will need to call the <code>_node</code> accessor function +     which returns a pointer to <code>DOMNode</code>. You can then query +     this DOM node's type and cast it to either <code>DOMAttr*</code> +     or <code>DOMElement*</code>. To obtain the corresponding object +     model node from a DOM node, the DOM user data API is used. The +     <code>xml_schema::dom::tree_node_key</code> variable contains +     the key for object model nodes. The following schema and code +     fragment show how to navigate from DOM to object model nodes +     and in the opposite direction:</p> + +  <pre class="xml"> +<complexType name="object"> +  <sequence> +    <element name="a" type="string"/> +  </sequence> +</complexType> + +<element name="root" type="object"/> +  </pre> + +  <pre class="c++"> +using namespace xercesc; + +XMLPlatformUtils::Initialize (); + +{ +  // Parse XML to object model. +  // +  std::unique_ptr<type> r (root ( +    "root.xml", +     xml_schema::flags::keep_dom | +     xml_schema::flags::dont_initialize)); + +  DOMNode* n = r->_node (); +  assert (n->getNodeType () == DOMNode::ELEMENT_NODE); +  DOMElement* re = static_cast<DOMElement*> (n); + +  // Get the 'a' element. Note that it is not necessarily the +  // first child node of 'root' since there could be whitespace +  // nodes before it. +  // +  DOMElement* ae; + +  for (n = re->getFirstChild (); n != 0; n = n->getNextSibling ()) +  { +    if (n->getNodeType () == DOMNode::ELEMENT_NODE) +    { +      ae = static_cast<DOMElement*> (n); +      break; +    } +  } + +  // Get from the 'a' DOM element to xml_schema::string object model +  // node. +  // +  xml_schema::type& t ( +    *reinterpret_cast<xml_schema::type*> ( +       ae->getUserData (xml_schema::dom::tree_node_key))); + +  xml_schema::string& a (dynamic_cast<xml_schema::string&> (t)); +} + +XMLPlatformUtils::Terminate (); +  </pre> + +  <p>The 'mixed' example which can be found in the XSD distribution +     shows how to handle the mixed content using DOM association.</p> + +  <h2><a name="5.2">5.2 Binary Serialization</a></h2> + +  <p>Besides reading from and writing to XML, the C++/Tree mapping +     also allows you to save the object model to and load it from a +     number of predefined as well as custom data representation +     formats. The predefined binary formats are CDR (Common Data +     Representation) and XDR (eXternal Data Representation). A +     custom format can easily be supported by providing +     insertion and extraction operators for basic types.</p> + +  <p>Binary serialization saves only the data without any meta +     information or markup. As a result, saving to and loading +     from a binary representation can be an order of magnitude +     faster than parsing and serializing the same data in XML. +     Furthermore, the resulting representation is normally several +     times smaller than the equivalent XML representation. These +     properties make binary serialization ideal for internal data +     exchange and storage. A typical application that uses this +     facility stores the data and communicates within the +     system using a binary format and reads/writes the data +     in XML when communicating with the outside world.</p> + +  <p>In order to request the generation of insertion operators and +     extraction constructors for a specific predefined or custom +     data representation stream, you will need to use the +     <code>--generate-insertion</code> and <code>--generate-extraction</code> +     compiler options. See the +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD +     Compiler Command Line Manual</a> for more information.</p> + +  <p>Once the insertion operators and extraction constructors are +     generated, you can use the <code>xml_schema::istream</code> +     and <code>xml_schema::ostream</code> wrapper stream templates +     to save the object model to and load it from a specific format. +     The following code fragment shows how to do this using ACE +     (Adaptive Communication Environment) CDR streams as an example:</p> + +  <pre class="xml"> +<complexType name="object"> +  <sequence> +    <element name="a" type="string"/> +    <element name="b" type="int"/> +  </sequence> +</complexType> + +<element name="root" type="object"/> +  </pre> + +  <pre class="c++"> +// Parse XML to object model. +// +std::unique_ptr<type> r (root ("root.xml")); + +// Save to a CDR stream. +// +ACE_OutputCDR ace_ocdr; +xml_schema::ostream<ACE_OutputCDR> ocdr (ace_ocdr); + +ocdr << *r; + +// Load from a CDR stream. +// +ACE_InputCDR ace_icdr (buf, size); +xml_schema::istream<ACE_InputCDR> icdr (ace_icdr); + +std::unique_ptr<object> copy (new object (icdr)); + +// Serialize to XML. +// +root (std::cout, *copy); +  </pre> + +  <p>The XSD distribution contains a number of examples that +     show how to save the object model to and load it from +     CDR, XDR, and a custom format.</p> + +  <!--  Appendix A --> + + +  <h1><a name="A">Appendix A — Default and Fixed Values</a></h1> + +  <p>The following table summarizes the effect of default and fixed +     values (specified with the <code>default</code> and <code>fixed</code> +     attributes, respectively) on attribute and element values. The +     <code>default</code> and <code>fixed</code> attributes are mutually +     exclusive. It is also worthwhile to note that the fixed value semantics +     is a superset of the default value semantics. +  </p> + +  <!-- border="1" is necessary for html2ps --> +  <table id="default-fixed" border="1"> +    <tr> +      <th></th> +      <th></th> +      <th colspan="2">default</th> +      <th colspan="2">fixed</th> +    </tr> + +    <!-- element --> + +    <tr> +      <th rowspan="4">element</th> +      <th rowspan="2">not present</th> +      <th>optional</th> +      <th>required</th> +      <th>optional</th> +      <th>required</th> +    </tr> +    <tr> +      <td>not present</td> +      <td>invalid instance</td> +      <td>not present</td> +      <td>invalid instance</td> +    </tr> + + +    <tr> +      <th>empty</th> +      <td colspan="2">default value is used</td> +      <td colspan="2">fixed value is used</td> +    </tr> + +    <tr> +      <th>value</th> +      <td colspan="2">value is used</td> +      <td colspan="2">value is used provided it's the same as fixed</td> +    </tr> + +    <!-- attribute --> + +    <!-- element --> + +    <tr> +      <th rowspan="4">attribute</th> +      <th rowspan="2">not present</th> +      <th>optional</th> +      <th>required</th> +      <th>optional</th> +      <th>required</th> +    </tr> +    <tr> +      <td>default value is used</td> +      <td>invalid schema</td> +      <td>fixed value is used</td> +      <td>invalid instance</td> +    </tr> + + +    <tr> +      <th>empty</th> +      <td colspan="2">empty value is used</td> +      <td colspan="2">empty value is used provided it's the same as fixed</td> +    </tr> + +    <tr> +      <th>value</th> +      <td colspan="2">value is used</td> +      <td colspan="2">value is used provided it's the same as fixed</td> +    </tr> + +  </table> + +  </div> +</div> + + +</body> +</html> diff --git a/doc/cxx/tree/manual/index.xhtml.in b/doc/cxx/tree/manual/index.xhtml.in new file mode 100644 index 0000000..5a7240a --- /dev/null +++ b/doc/cxx/tree/manual/index.xhtml.in @@ -0,0 +1,6826 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> + +<head> +  <title>C++/Tree Mapping User Manual</title> + +  <meta name="copyright" content="© @copyright@"/> +  <meta name="keywords" content="xsd,xml,schema,c++,mapping,data,binding,tree,serialization,guide,manual,examples"/> +  <meta name="description" content="C++/Tree Mapping User Manual"/> +  <meta name="revision" content="4.1.0"/> + +  <link rel="stylesheet" type="text/css" href="../../../default.css" /> + +<style type="text/css"> +  pre { +    padding    : 0 0 0 0em; +    margin     : 0em 0em 0em 0; + +    font-size  : 102% +  } + +  body { +    min-width: 48em; +  } + +  h1 { +    font-weight: bold; +    font-size: 200%; +  } + +  h2 { +    font-weight : bold; +    font-size   : 150%; + +    padding-top : 0.8em; +  } + +  h3 { +    font-size   : 130%; +    padding-top : 0.8em; +  } + +  /* Adjust indentation for three levels. */ +  #container { +    max-width: 48em; +  } + +  #content { +    padding: 0 0.1em 0 4em; +    /*background-color: red;*/ +  } + +  #content h1 { +    margin-left: -2.06em; +  } + +  #content h2 { +    margin-left: -1.33em; +  } + +  /* Title page */ + +  #titlepage { +    padding: 2em 0 1em 0; +    border-bottom: 1px solid black; +  } + +  #titlepage #title { +    font-weight: bold; +    font-size: 200%; +    text-align: center; +    padding: 1em 0 2em 0; +  } + +  /* Lists */ +  ul.list li { +    padding-top      : 0.3em; +    padding-bottom   : 0.3em; +  } + + +  /* Built-in table */ +  #builtin { +    margin: 2em 0 2em 0; + +    border-collapse   : collapse; +    border            : 1px solid; +    border-color      : #000000; + +    font-size        : 11px; +    line-height      : 14px; +  } + +  #builtin th, #builtin td { +    border: 1px solid; +    padding           : 0.9em 0.9em 0.7em 0.9em; +  } + +  #builtin th { +    background : #cde8f6; +  } + +  #builtin td { +    text-align: left; +  } + + +  /* default-fixed */ +  #default-fixed { +    margin: 2em 0 2em 0; + +    border-collapse   : collapse; +    border            : 1px solid; +    border-color      : #000000; + +    font-size        : 11px; +    line-height      : 14px; +  } + +  #default-fixed th, #default-fixed td { +    border: 1px solid; +    padding           : 0.9em 0.9em 0.7em 0.9em; +  } + +  #default-fixed th { +    background : #cde8f6; +  } + +  #default-fixed td { +    text-align: center; +  } + + +  /*  */ +  dl dt { +    padding   : 0.8em 0 0 0; +  } + + +  /* TOC */ +  table.toc { +    border-style      : none; +    border-collapse   : separate; +    border-spacing    : 0; + +    margin            : 0.2em 0 0.2em 0; +    padding           : 0 0 0 0; +  } + +  table.toc tr { +    padding           : 0 0 0 0; +    margin            : 0 0 0 0; +  } + +  table.toc * td, table.toc * th { +    border-style      : none; +    margin            : 0 0 0 0; +    vertical-align    : top; +  } + +  table.toc * th { +    font-weight       : normal; +    padding           : 0em 0.1em 0em 0; +    text-align        : left; +    white-space       : nowrap; +  } + +  table.toc * table.toc th { +    padding-left      : 1em; +  } + +  table.toc * td { +    padding           : 0em 0 0em 0.7em; +    text-align        : left; +  } +</style> + + +</head> + +<body> +<div id="container"> +  <div id="content"> + +  <div class="noprint"> + +  <div id="titlepage"> +    <div id="title">C++/Tree Mapping User Manual</div> + +  <p>Copyright © @copyright@.</p> + +  <p>Permission is granted to copy, distribute and/or modify this +     document under the terms of the +     <a href="https://www.codesynthesis.com/licenses/fdl-1.2.txt">GNU Free +     Documentation License, version 1.2</a>; with no Invariant Sections, +     no Front-Cover Texts and no Back-Cover Texts. +  </p> + +  <p>This document is available in the following formats: +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/index.xhtml">XHTML</a>, +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/cxx-tree-manual.pdf">PDF</a>, and +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/cxx-tree-manual.ps">PostScript</a>.</p> +  </div> + +  <h1>Table of Contents</h1> + +  <table class="toc"> +    <tr> +      <th></th><td><a href="#0">Preface</a> +        <table class="toc"> +          <tr><th></th><td><a href="#0.1">About This Document</a></td></tr> +	  <tr><th></th><td><a href="#0.2">More Information</a></td></tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>1</th><td><a href="#1">Introduction</a></td> +    </tr> + +    <tr> +      <th>2</th><td><a href="#2">C++/Tree Mapping</a> +        <table class="toc"> +          <tr> +            <th>2.1</th><td><a href="#2.1">Preliminary Information</a> +              <table class="toc"> +		<tr><th>2.1.1</th><td><a href="#2.1.1">C++ Standard</a></td></tr> +                <tr><th>2.1.2</th><td><a href="#2.1.2">Identifiers</a></td></tr> +                <tr><th>2.1.3</th><td><a href="#2.1.3">Character Type and Encoding</a></td></tr> +                <tr><th>2.1.4</th><td><a href="#2.1.4">XML Schema Namespace</a></td></tr> +		<tr><th>2.1.5</th><td><a href="#2.1.5">Anonymous Types</a></td></tr> +              </table> +            </td> +          </tr> +          <tr> +            <th>2.2</th><td><a href="#2.2">Error Handling</a> +              <table class="toc"> +                <tr><th>2.2.1</th><td><a href="#2.2.1"><code>xml_schema::duplicate_id</code></a></td></tr> +              </table> +            </td> +          </tr> +          <tr> +            <th>2.3</th><td><a href="#2.3">Mapping for <code>import</code> and <code>include</code></a> +              <table class="toc"> +                <tr><th>2.3.1</th><td><a href="#2.3.1">Import</a></td></tr> +		<tr><th>2.3.2</th><td><a href="#2.3.2">Inclusion with Target Namespace</a></td></tr> +		<tr><th>2.3.3</th><td><a href="#2.3.3">Inclusion without Target Namespace</a></td></tr> +              </table> +            </td> +          </tr> +          <tr> +            <th>2.4</th><td><a href="#2.4">Mapping for Namespaces</a></td> +          </tr> +          <tr> +            <th>2.5</th><td><a href="#2.5">Mapping for Built-in Data Types</a> +              <table class="toc"> +                <tr><th>2.5.1</th><td><a href="#2.5.1">Inheritance from Built-in Data Types</a></td></tr> +                <tr><th>2.5.2</th><td><a href="#2.5.2">Mapping for <code>anyType</code></a></td></tr> +                <tr><th>2.5.3</th><td><a href="#2.5.3">Mapping for <code>anySimpleType</code></a></td></tr> +                <tr><th>2.5.4</th><td><a href="#2.5.4">Mapping for <code>QName</code></a></td></tr> +                <tr><th>2.5.5</th><td><a href="#2.5.5">Mapping for <code>IDREF</code></a></td></tr> +		<tr><th>2.5.6</th><td><a href="#2.5.6">Mapping for <code>base64Binary</code> and <code>hexBinary</code></a></td></tr> +		<tr><th>2.5.7</th><td><a href="#2.5.7">Time Zone Representation</a></td></tr> +		<tr><th>2.5.8</th><td><a href="#2.5.8">Mapping for <code>date</code></a></td></tr> +		<tr><th>2.5.9</th><td><a href="#2.5.9">Mapping for <code>dateTime</code></a></td></tr> +		<tr><th>2.5.10</th><td><a href="#2.5.10">Mapping for <code>duration</code></a></td></tr> +		<tr><th>2.5.11</th><td><a href="#2.5.11">Mapping for <code>gDay</code></a></td></tr> +		<tr><th>2.5.12</th><td><a href="#2.5.12">Mapping for <code>gMonth</code></a></td></tr> +		<tr><th>2.5.13</th><td><a href="#2.5.13">Mapping for <code>gMonthDay</code></a></td></tr> +		<tr><th>2.5.14</th><td><a href="#2.5.14">Mapping for <code>gYear</code></a></td></tr> +		<tr><th>2.5.15</th><td><a href="#2.5.15">Mapping for <code>gYearMonth</code></a></td></tr> +		<tr><th>2.5.16</th><td><a href="#2.5.16">Mapping for <code>time</code></a></td></tr> +              </table> +            </td> +          </tr> +          <tr> +            <th>2.6</th><td><a href="#2.6">Mapping for Simple Types</a> +              <table class="toc"> +                <tr><th>2.6.1</th><td><a href="#2.6.1">Mapping for Derivation by Restriction</a></td></tr> +                <tr><th>2.6.2</th><td><a href="#2.6.2">Mapping for Enumerations</a></td></tr> +                <tr><th>2.6.3</th><td><a href="#2.6.3">Mapping for Derivation by List</a></td></tr> +                <tr><th>2.6.4</th><td><a href="#2.6.4">Mapping for Derivation by Union</a></td></tr> +              </table> +            </td> +          </tr> +          <tr> +            <th>2.7</th><td><a href="#2.7">Mapping for Complex Types</a> +              <table class="toc"> +	        <tr><th>2.7.1</th><td><a href="#2.7.1">Mapping for Derivation by Extension</a></td></tr> +                <tr><th>2.7.2</th><td><a href="#2.7.2">Mapping for Derivation by Restriction</a></td></tr> +              </table> +            </td> +          </tr> +          <tr> +            <th>2.8</th><td><a href="#2.8">Mapping for Local Elements and Attributes</a> +              <table class="toc"> +	        <tr><th>2.8.1</th><td><a href="#2.8.1">Mapping for Members with the One Cardinality Class</a></td></tr> +	        <tr><th>2.8.2</th><td><a href="#2.8.2">Mapping for Members with the Optional Cardinality Class</a></td></tr> +	        <tr><th>2.8.3</th><td><a href="#2.8.3">Mapping for Members with the Sequence Cardinality Class</a></td></tr> +		<tr><th>2.8.4</th><td><a href="#2.8.4">Element Order</a></td></tr> +              </table> +            </td> +          </tr> +          <tr> +            <th>2.9</th><td><a href="#2.9">Mapping for Global Elements</a> +              <table class="toc"> +	        <tr><th>2.9.1</th><td><a href="#2.9.1">Element Types</a></td></tr> +	        <tr><th>2.9.2</th><td><a href="#2.9.2">Element Map</a></td></tr> +              </table> +            </td> +          </tr> +          <tr> +            <th>2.10</th><td><a href="#2.10">Mapping for Global Attributes</a></td> +          </tr> +          <tr> +            <th>2.11</th><td><a href="#2.11">Mapping for <code>xsi:type</code> and Substitution Groups</a></td> +          </tr> +          <tr> +            <th>2.12</th><td><a href="#2.12">Mapping for <code>any</code> and <code>anyAttribute</code></a> +              <table class="toc"> +	        <tr><th>2.12.1</th><td><a href="#2.12.1">Mapping for <code>any</code> with the One Cardinality Class</a></td></tr> +	        <tr><th>2.12.2</th><td><a href="#2.12.2">Mapping for <code>any</code> with the Optional Cardinality Class</a></td></tr> +	        <tr><th>2.12.3</th><td><a href="#2.12.3">Mapping for <code>any</code> with the Sequence Cardinality Class</a></td></tr> +		<tr><th>2.12.4</th><td><a href="#2.12.4">Element Wildcard Order</a></td></tr> +		<tr><th>2.12.5</th><td><a href="#2.12.5">Mapping for <code>anyAttribute</code></a></td></tr> +              </table> +            </td> +          </tr> +	  <tr> +            <th>2.13</th><td><a href="#2.13">Mapping for Mixed Content Models</a></td> +          </tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>3</th><td><a href="#3">Parsing</a> +        <table class="toc"> +          <tr> +            <th>3.1</th><td><a href="#3.1">Initializing the Xerces-C++ Runtime</a></td> +          </tr> +          <tr> +            <th>3.2</th><td><a href="#3.2">Flags and Properties</a></td> +          </tr> +          <tr> +            <th>3.3</th><td><a href="#3.3">Error Handling</a> +              <table class="toc"> +	        <tr><th>3.3.1</th><td><a href="#3.3.1"><code>xml_schema::parsing</code></a></td></tr> +	        <tr><th>3.3.2</th><td><a href="#3.3.2"><code>xml_schema::expected_element</code></a></td></tr> +	        <tr><th>3.3.3</th><td><a href="#3.3.3"><code>xml_schema::unexpected_element</code></a></td></tr> +	        <tr><th>3.3.4</th><td><a href="#3.3.4"><code>xml_schema::expected_attribute</code></a></td></tr> +	        <tr><th>3.3.5</th><td><a href="#3.3.5"><code>xml_schema::unexpected_enumerator</code></a></td></tr> +		<tr><th>3.3.6</th><td><a href="#3.3.6"><code>xml_schema::expected_text_content</code></a></td></tr> +	        <tr><th>3.3.7</th><td><a href="#3.3.7"><code>xml_schema::no_type_info</code></a></td></tr> +	        <tr><th>3.3.8</th><td><a href="#3.3.8"><code>xml_schema::not_derived</code></a></td></tr> +		<tr><th>3.3.9</th><td><a href="#3.3.9"><code>xml_schema::not_prefix_mapping</code></a></td></tr> +              </table> +            </td> +          </tr> +          <tr> +            <th>3.4</th><td><a href="#3.4">Reading from a Local File or URI</a></td> +          </tr> +          <tr> +            <th>3.5</th><td><a href="#3.5">Reading from <code>std::istream</code></a></td> +          </tr> +          <tr> +            <th>3.6</th><td><a href="#3.6">Reading from <code>xercesc::InputSource</code></a></td> +          </tr> +          <tr> +            <th>3.7</th><td><a href="#3.7">Reading from DOM</a></td> +          </tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>4</th><td><a href="#4">Serialization</a> +        <table class="toc"> +          <tr> +            <th>4.1</th><td><a href="#4.1">Initializing the Xerces-C++ Runtime</a></td> +          </tr> +          <tr> +            <th>4.2</th><td><a href="#4.2">Namespace Infomap and Character Encoding</a></td> +          </tr> +          <tr> +            <th>4.3</th><td><a href="#4.3">Flags</a></td> +          </tr> +          <tr> +            <th>4.4</th><td><a href="#4.4">Error Handling</a> +              <table class="toc"> +	        <tr><th>4.4.1</th><td><a href="#4.4.1"><code>xml_schema::serialization</code></a></td></tr> +		<tr><th>4.4.2</th><td><a href="#4.4.2"><code>xml_schema::unexpected_element</code></a></td></tr> +		<tr><th>4.4.3</th><td><a href="#4.4.3"><code>xml_schema::no_type_info</code></a></td></tr> +              </table> +            </td> +          </tr> +          <tr> +            <th>4.5</th><td><a href="#4.5">Serializing to <code>std::ostream</code></a></td> +          </tr> +          <tr> +            <th>4.6</th><td><a href="#4.6">Serializing to <code>xercesc::XMLFormatTarget</code></a></td> +          </tr> +          <tr> +            <th>4.7</th><td><a href="#4.7">Serializing to DOM</a></td> +          </tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th>5</th><td><a href="#5">Additional Functionality</a> +        <table class="toc"> +          <tr> +            <th>5.1</th><td><a href="#5.1">DOM Association</a></td> +          </tr> +          <tr> +            <th>5.2</th><td><a href="#5.2">Binary Serialization</a></td> +          </tr> +        </table> +      </td> +    </tr> + +    <tr> +      <th></th><td><a href="#A">Appendix A — Default and Fixed Values</a></td> +    </tr> + +  </table> +  </div> + +  <h1><a name="0">Preface</a></h1> + +  <h2><a name="0.1">About This Document</a></h2> + +  <p>This document describes the mapping of W3C XML Schema +     to the C++ programming language as implemented by +     <a href="https://www.codesynthesis.com/products/xsd">CodeSynthesis +     XSD</a> - an XML Schema to C++ data binding compiler. The mapping +     represents information stored in XML instance documents as a +     statically-typed, tree-like in-memory data structure and is +     called C++/Tree. +  </p> + +  <p>Revision 4.1.0<br/> <!-- Remember to change revision in other places --> +     This revision of the manual describes the C++/Tree +     mapping as implemented by CodeSynthesis XSD version 4.1.0. +  </p> + +  <p>This document is available in the following formats: +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/index.xhtml">XHTML</a>, +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/cxx-tree-manual.pdf">PDF</a>, and +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/cxx-tree-manual.ps">PostScript</a>.</p> + +  <h2><a name="0.2">More Information</a></h2> + +  <p>Beyond this manual, you may also find the following sources of +     information useful:</p> + +  <ul class="list"> +    <li><a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/guide/">C++/Tree +        Mapping Getting Started Guide</a></li> + +    <li><a href="http://wiki.codesynthesis.com/Tree/Customization_guide">C++/Tree +        Mapping Customization Guide</a></li> + +    <li><a href="http://wiki.codesynthesis.com/Tree/FAQ">C++/Tree +        Mapping Frequently Asked Questions (FAQ)</a></li> + +    <li><a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD +        Compiler Command Line Manual</a></li> + +    <li>The <code>cxx/tree/</code> directory in the +        <a href="https://cppget.org/xsd-examples">xsd-examples</a> package +        contains a collection of examples and a README file with an overview +        of each example.</li> + +    <li>The <code>README</code> file in the +        <a href="https://cppget.org/xsd-examples">xsd-examples</a> package +        explains how to build the examples.</li> + +    <li>The <a href="https://www.codesynthesis.com/mailman/listinfo/xsd-users">xsd-users</a> +        mailing list is a place to ask questions. Furthermore the +        <a href="https://www.codesynthesis.com/pipermail/xsd-users/">archives</a> +        may already have answers to some of your questions.</li> +  </ul> + + +  <h1><a name="1">1 Introduction</a></h1> + +  <p>C++/Tree is a W3C XML Schema to C++ mapping that represents the +     data stored in XML as a statically-typed, vocabulary-specific +     object model. Based on a formal description of an XML vocabulary +     (schema), the C++/Tree mapping produces a tree-like data structure +     suitable for in-memory processing as well as XML parsing and +     serialization code.</p> + +  <p>A typical application that processes XML documents usually +     performs the following three steps: it first reads (parses) an XML +     instance document to an object model, it then performs +     some useful computations on that model which may involve +     modification of the model, and finally it may write (serialize) +     the modified object model back to XML. +  </p> + +  <p>The C++/Tree mapping consists of C++ types that represent the +     given vocabulary (<a href="#2">Chapter 2, "C++/Tree Mapping"</a>), +     a set of parsing functions that convert XML documents to +     a tree-like in-memory data structure (<a href="#3">Chapter 3, +     "Parsing"</a>), and a set of serialization functions that convert +     the object model back to XML (<a href="#4">Chapter 4, +     "Serialization"</a>). Furthermore, the mapping provides a number +     of additional features, such as DOM association and binary +     serialization, that can be useful in some applications +     (<a href="#5">Chapter 5, "Additional Functionality"</a>). +  </p> + + +  <!-- Chapter 2 --> + + +  <h1><a name="2">2 C++/Tree Mapping</a></h1> + +  <h2><a name="2.1">2.1 Preliminary Information</a></h2> + +  <h3><a name="2.1.1">2.1.1 C++ Standard</a></h3> + +  <p>The C++/Tree mapping provides support for ISO/IEC C++ 2011 (C++11) +     and ISO/IEC C++ 1998/2003 (C++98). To select the C++ standard for the +     generated code we use the <code>--std</code> XSD compiler command +     line option. While the majority of the examples in this guide use +     C++11, the document explains the C++11/98 usage difference and so +     they can easily be converted to C++98.</p> + +  <h3><a name="2.1.2">2.1.2 Identifiers</a></h3> + +  <p>XML Schema names may happen to be reserved C++ keywords or contain +     characters that are illegal in C++ identifiers. To avoid C++ compilation +     problems, such names are changed (escaped) when mapped to C++. If an +     XML Schema name is a C++ keyword, the "_" suffix is added to it. All +     character of an XML Schema name that are not allowed in C++ identifiers +     are replaced with "_". +  </p> + +  <p>For example, XML Schema name <code>try</code> will be mapped to +     C++ identifier <code>try_</code>. Similarly, XML Schema name +     <code>strange.na-me</code> will be mapped to C++ identifier +     <code>strange_na_me</code>. +  </p> + +  <p>Furthermore, conflicts between type names and function names in the +     same scope are resolved using name escaping. Such conflicts include +     both a global element (which is mapped to a set of parsing and/or +     serialization functions or element types, see <a href="#2.9">Section +     2.9, "Mapping for Global Elements"</a>) and a global type sharing the +     same name as well as a local element or attribute inside a type having +     the same name as the type itself.</p> + +  <p>For example, if we had a global type <code>catalog</code> +     and a global element with the same name then the type would be +     mapped to a C++ class with name <code>catalog</code> while the +     parsing functions corresponding to the global element would have +     their names escaped as <code>catalog_</code>. +  </p> + +  <p>By default the mapping uses the so-called K&R (Kernighan and +     Ritchie) identifier naming convention which is also used throughout +     this manual. In this convention both type and function names are in +     lower case and words are separated by underscores. If your application +     code or schemas use a different notation, you may want to change the +     naming convention used by the mapping for consistency. +     The compiler supports a set of widely-used naming conventions +     that you can select with the <code>--type-naming</code> and +     <code>--function-naming</code> options. You can also further +     refine one of the predefined conventions or create a completely +     custom naming scheme by using the  <code>--*-regex</code> options. +     For more detailed information on these options refer to the NAMING +     CONVENTION section in the <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD +     Compiler Command Line Manual</a>.</p> + +  <h3><a name="2.1.3">2.1.3 Character Type and Encoding</a></h3> + +  <p>The code that implements the mapping, depending on the +     <code>--char-type</code>  option, is generated using either +     <code>char</code> or <code>wchar_t</code> as the character +     type. In this document code samples use symbol <code>C</code> +     to refer to the character type you have selected when translating +     your schemas, for example <code>std::basic_string<C></code>. +  </p> + +  <p>Another aspect of the mapping that depends on the character type +     is character encoding. For the <code>char</code> character type +     the default encoding is UTF-8. Other supported encodings are +     ISO-8859-1, Xerces-C++ Local Code Page (LPC), as well as +     custom encodings and can be selected with the +     <code>--char-encoding</code> command line option.</p> + +  <p>For the <code>wchar_t</code> character type the encoding is +     automatically selected between UTF-16 and UTF-32/UCS-4 depending +     on the size of the <code>wchar_t</code> type. On some platforms +     (for example, Windows with Visual C++ and AIX with IBM XL C++) +     <code>wchar_t</code> is 2 bytes long. For these platforms the +     encoding is UTF-16. On other platforms <code>wchar_t</code> is 4 bytes +     long and UTF-32/UCS-4 is used.</p> + +  <h3><a name="2.1.4">2.1.4 XML Schema Namespace</a></h3> + +  <p>The mapping relies on some predefined types, classes, and functions +     that are logically defined in the XML Schema namespace reserved for +     the XML Schema language (<code>http://www.w3.org/2001/XMLSchema</code>). +     By default, this namespace is mapped to C++ namespace +     <code>xml_schema</code>. It is automatically accessible +     from a C++ compilation unit that includes a header file generated +     from an XML Schema definition. +  </p> + +  <p>Note that, if desired, the default mapping of this namespace can be +     changed as described in <a href="#2.4">Section 2.4, "Mapping for +     Namespaces"</a>. +  </p> + + +  <h3><a name="2.1.5">2.1.5 Anonymous Types</a></h3> + +  <p>For the purpose of code generation, anonymous types defined in +     XML Schema are automatically assigned names that are derived +     from enclosing attributes and elements. Otherwise, such types +     follows standard mapping rules for simple and complex type +     definitions (see <a href="#2.6">Section 2.6, "Mapping for Simple Types"</a> +     and <a href="#2.7">Section 2.7, "Mapping for Complex Types"</a>). +     For example, in the following schema fragment: +  </p> + +  <pre class="xml"> +<element name="object"> +  <complexType> +    ... +  </complexType> +</element> +  </pre> + +  <p>The anonymous type defined inside element <code>object</code> will +     be given name <code>object</code>. The compiler has a number of +     options that control the process of anonymous type naming. For more +     information refer to the <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD +     Compiler Command Line Manual</a>.</p> + + +  <h2><a name="2.2">2.2 Error Handling</a></h2> + +  <p>The mapping uses the C++ exception handling mechanism as a primary way +     of reporting error conditions. All exceptions that are specified in +     this mapping derive from <code>xml_schema::exception</code> which +     itself is derived from <code>std::exception</code>: +  </p> + +  <pre class="c++"> +struct exception: virtual std::exception +{ +  friend +  std::basic_ostream<C>& +  operator<< (std::basic_ostream<C>& os, const exception& e) +  { +    e.print (os); +    return os; +  } + +protected: +  virtual void +  print (std::basic_ostream<C>&) const = 0; +}; +  </pre> + +  <p>The exception hierarchy supports "virtual" <code>operator<<</code> +     which allows you to obtain diagnostics corresponding to the thrown +     exception using the base exception interface. For example:</p> + +  <pre class="c++"> +try +{ +  ... +} +catch (const xml_schema::exception& e) +{ +  cerr << e << endl; +} +  </pre> + +  <p>The following sub-sections describe exceptions thrown by the +     types that constitute the object model. +     <a href="#3.3">Section 3.3, "Error Handling"</a> of +     <a href="#3">Chapter 3, "Parsing"</a> describes exceptions +     and error handling mechanisms specific to the parsing functions. +     <a href="#4.4">Section 4.4, "Error Handling"</a> of +     <a href="#4">Chapter 4, "Serialization"</a> describes exceptions +     and error handling mechanisms specific to the serialization functions. +  </p> + + +  <h3><a name="2.2.1">2.2.1 <code>xml_schema::duplicate_id</code></a></h3> + +  <pre class="c++"> +struct duplicate_id: virtual exception +{ +  duplicate_id (const std::basic_string<C>& id); + +  const std::basic_string<C>& +  id () const; + +  virtual const char* +  what () const throw (); +}; +  </pre> + +  <p>The <code>xml_schema::duplicate_id</code> is thrown when +     a conflicting instance of <code>xml_schema::id</code> (see +     <a href="#2.5">Section 2.5, "Mapping for Built-in Data Types"</a>) +     is added to a tree. The offending ID value can be obtained using +     the <code>id</code> function. +  </p> + +  <h2><a name="2.3">2.3 Mapping for <code>import</code> and <code>include</code></a></h2> + +  <h3><a name="2.3.1">2.3.1 Import</a></h3> + +  <p>The XML Schema <code>import</code> element is mapped to the C++ +     Preprocessor <code>#include</code> directive. The value of +     the <code>schemaLocation</code> attribute is used to derive +     the name of the header file that appears in the <code>#include</code> +     directive. For instance: +  </p> + +  <pre class="xml"> +<import namespace="https://www.codesynthesis.com/test" +        schemaLocation="test.xsd"/> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +#include "test.hxx" +  </pre> + +  <p>Note that you will need to compile imported schemas separately +     in order to produce corresponding header files.</p> + +  <h3><a name="2.3.2">2.3.2 Inclusion with Target Namespace</a></h3> + +  <p>The XML Schema <code>include</code> element which refers to a schema +     with a target namespace or appears in a schema without a target namespace +     follows the same mapping rules as the <code>import</code> element, +     see <a href="#2.3.1">Section 2.3.1, "Import"</a>. +  </p> + +  <h3><a name="2.3.3">2.3.3 Inclusion without Target Namespace</a></h3> + +  <p>For the XML Schema <code>include</code> element which refers to a schema +     without a target namespace and appears in a schema with a target +     namespace (such inclusion sometimes called "chameleon inclusion"), +     declarations and definitions from the included schema are generated +     in-line in the namespace of the including schema as if they were +     declared and defined there verbatim. For example, consider the +     following two schemas: +  </p> + +  <pre class="xml"> +<-- common.xsd --> +<schema> +  <complexType name="type"> +  ... +  </complexType> +</schema> + +<-- test.xsd --> +<schema targetNamespace="https://www.codesynthesis.com/test"> +  <include schemaLocation="common.xsd"/> +</schema> +  </pre> + +  <p>The fragment of interest from the generated header file for +     <code>text.xsd</code> would look like this:</p> + +  <pre class="c++"> +// test.hxx +namespace test +{ +  class type +  { +    ... +  }; +} +  </pre> + +  <h2><a name="2.4">2.4 Mapping for Namespaces</a></h2> + +  <p>An XML Schema namespace is mapped to one or more nested C++ +     namespaces. XML Schema namespaces are identified by URIs. +     By default, a namespace URI is mapped to a sequence of +     C++ namespace names by removing the protocol and host parts +     and splitting the rest into a sequence of names with '<code>/</code>' +     as the name separator. For instance: +  </p> + +  <pre class="xml"> +<schema targetNamespace="https://www.codesynthesis.com/system/test"> +  ... +</schema> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +namespace system +{ +  namespace test +  { +    ... +  } +} +  </pre> + +  <p>The default mapping of namespace URIs to C++ namespace names can be +     altered using the <code>--namespace-map</code> and +     <code>--namespace-regex</code> options. See  the +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD +     Compiler Command Line Manual</a> for more information. +  </p> + +  <h2><a name="2.5">2.5 Mapping for Built-in Data Types</a></h2> + +  <p>The mapping of XML Schema built-in data types to C++ types is +     summarized in the table below.</p> + +  <!-- border="1" is necessary for html2ps --> +  <table id="builtin" border="1"> +    <tr> +      <th>XML Schema type</th> +      <th>Alias in the <code>xml_schema</code> namespace</th> +      <th>C++ type</th> +    </tr> + +    <tr> +      <th colspan="3">anyType and anySimpleType types</th> +    </tr> +    <tr> +      <td><code>anyType</code></td> +      <td><code>type</code></td> +      <td><a href="#2.5.2">Section 2.5.2, "Mapping for <code>anyType</code>"</a></td> +    </tr> +    <tr> +      <td><code>anySimpleType</code></td> +      <td><code>simple_type</code></td> +      <td><a href="#2.5.3">Section 2.5.3, "Mapping for <code>anySimpleType</code>"</a></td> +    </tr> + +    <tr> +      <th colspan="3">fixed-length integral types</th> +    </tr> +    <!-- 8-bit --> +    <tr> +      <td><code>byte</code></td> +      <td><code>byte</code></td> +      <td><code>signed char</code></td> +    </tr> +    <tr> +      <td><code>unsignedByte</code></td> +      <td><code>unsigned_byte</code></td> +      <td><code>unsigned char</code></td> +    </tr> + +    <!-- 16-bit --> +    <tr> +      <td><code>short</code></td> +      <td><code>short_</code></td> +      <td><code>short</code></td> +    </tr> +    <tr> +      <td><code>unsignedShort</code></td> +      <td><code>unsigned_short</code></td> +      <td><code>unsigned short</code></td> +    </tr> + +    <!-- 32-bit --> +    <tr> +      <td><code>int</code></td> +      <td><code>int_</code></td> +      <td><code>int</code></td> +    </tr> +    <tr> +      <td><code>unsignedInt</code></td> +      <td><code>unsigned_int</code></td> +      <td><code>unsigned int</code></td> +    </tr> + +    <!-- 64-bit --> +    <tr> +      <td><code>long</code></td> +      <td><code>long_</code></td> +      <td><code>long long</code></td> +    </tr> +    <tr> +      <td><code>unsignedLong</code></td> +      <td><code>unsigned_long</code></td> +      <td><code>unsigned long long</code></td> +    </tr> + +    <tr> +      <th colspan="3">arbitrary-length integral types</th> +    </tr> +    <tr> +      <td><code>integer</code></td> +      <td><code>integer</code></td> +      <td><code>long long</code></td> +    </tr> +    <tr> +      <td><code>nonPositiveInteger</code></td> +      <td><code>non_positive_integer</code></td> +      <td><code>long long</code></td> +    </tr> +    <tr> +      <td><code>nonNegativeInteger</code></td> +      <td><code>non_negative_integer</code></td> +      <td><code>unsigned long long</code></td> +    </tr> +    <tr> +      <td><code>positiveInteger</code></td> +      <td><code>positive_integer</code></td> +      <td><code>unsigned long long</code></td> +    </tr> +    <tr> +      <td><code>negativeInteger</code></td> +      <td><code>negative_integer</code></td> +      <td><code>long long</code></td> +    </tr> + +    <tr> +      <th colspan="3">boolean types</th> +    </tr> +    <tr> +      <td><code>boolean</code></td> +      <td><code>boolean</code></td> +      <td><code>bool</code></td> +    </tr> + +    <tr> +      <th colspan="3">fixed-precision floating-point types</th> +    </tr> +    <tr> +      <td><code>float</code></td> +      <td><code>float_</code></td> +      <td><code>float</code></td> +    </tr> +    <tr> +      <td><code>double</code></td> +      <td><code>double_</code></td> +      <td><code>double</code></td> +    </tr> + +    <tr> +      <th colspan="3">arbitrary-precision floating-point types</th> +    </tr> +    <tr> +      <td><code>decimal</code></td> +      <td><code>decimal</code></td> +      <td><code>double</code></td> +    </tr> + +    <tr> +      <th colspan="3">string types</th> +    </tr> +    <tr> +      <td><code>string</code></td> +      <td><code>string</code></td> +      <td>type derived from <code>std::basic_string</code></td> +    </tr> +    <tr> +      <td><code>normalizedString</code></td> +      <td><code>normalized_string</code></td> +      <td>type derived from <code>string</code></td> +    </tr> +    <tr> +      <td><code>token</code></td> +      <td><code>token</code></td> +      <td>type derived from <code>normalized_string</code></td> +    </tr> +    <tr> +      <td><code>Name</code></td> +      <td><code>name</code></td> +      <td>type derived from <code>token</code></td> +    </tr> +    <tr> +      <td><code>NMTOKEN</code></td> +      <td><code>nmtoken</code></td> +      <td>type derived from <code>token</code></td> +    </tr> +    <tr> +      <td><code>NMTOKENS</code></td> +      <td><code>nmtokens</code></td> +      <td>type derived from <code>sequence<nmtoken></code></td> +    </tr> +    <tr> +      <td><code>NCName</code></td> +      <td><code>ncname</code></td> +      <td>type derived from <code>name</code></td> +    </tr> +    <tr> +      <td><code>language</code></td> +      <td><code>language</code></td> +      <td>type derived from <code>token</code></td> +    </tr> + +    <tr> +      <th colspan="3">qualified name</th> +    </tr> +    <tr> +      <td><code>QName</code></td> +      <td><code>qname</code></td> +      <td><a href="#2.5.4">Section 2.5.4, "Mapping for <code>QName</code>"</a></td> +    </tr> + +    <tr> +      <th colspan="3">ID/IDREF types</th> +    </tr> +    <tr> +      <td><code>ID</code></td> +      <td><code>id</code></td> +      <td>type derived from <code>ncname</code></td> +    </tr> +    <tr> +      <td><code>IDREF</code></td> +      <td><code>idref</code></td> +      <td><a href="#2.5.5">Section 2.5.5, "Mapping for <code>IDREF</code>"</a></td> +    </tr> +    <tr> +      <td><code>IDREFS</code></td> +      <td><code>idrefs</code></td> +      <td>type derived from <code>sequence<idref></code></td> +    </tr> + +    <tr> +      <th colspan="3">URI types</th> +    </tr> +    <tr> +      <td><code>anyURI</code></td> +      <td><code>uri</code></td> +      <td>type derived from <code>std::basic_string</code></td> +    </tr> + +    <tr> +      <th colspan="3">binary types</th> +    </tr> +    <tr> +      <td><code>base64Binary</code></td> +      <td><code>base64_binary</code></td> +      <td rowspan="2"><a href="#2.5.6">Section 2.5.6, "Mapping for +         <code>base64Binary</code> and <code>hexBinary</code>"</a></td> +    </tr> +    <tr> +      <td><code>hexBinary</code></td> +      <td><code>hex_binary</code></td> +    </tr> + +    <tr> +      <th colspan="3">date/time types</th> +    </tr> +    <tr> +      <td><code>date</code></td> +      <td><code>date</code></td> +      <td><a href="#2.5.8">Section 2.5.8, "Mapping for +          <code>date</code>"</a></td> +    </tr> +    <tr> +      <td><code>dateTime</code></td> +      <td><code>date_time</code></td> +      <td><a href="#2.5.9">Section 2.5.9, "Mapping for +          <code>dateTime</code>"</a></td> +    </tr> +    <tr> +      <td><code>duration</code></td> +      <td><code>duration</code></td> +      <td><a href="#2.5.10">Section 2.5.10, "Mapping for +          <code>duration</code>"</a></td> +    </tr> +    <tr> +      <td><code>gDay</code></td> +      <td><code>gday</code></td> +      <td><a href="#2.5.11">Section 2.5.11, "Mapping for +          <code>gDay</code>"</a></td> +    </tr> +    <tr> +      <td><code>gMonth</code></td> +      <td><code>gmonth</code></td> +      <td><a href="#2.5.12">Section 2.5.12, "Mapping for +          <code>gMonth</code>"</a></td> +    </tr> +    <tr> +      <td><code>gMonthDay</code></td> +      <td><code>gmonth_day</code></td> +      <td><a href="#2.5.13">Section 2.5.13, "Mapping for +          <code>gMonthDay</code>"</a></td> +    </tr> +    <tr> +      <td><code>gYear</code></td> +      <td><code>gyear</code></td> +      <td><a href="#2.5.14">Section 2.5.14, "Mapping for +          <code>gYear</code>"</a></td> +    </tr> +    <tr> +      <td><code>gYearMonth</code></td> +      <td><code>gyear_month</code></td> +      <td><a href="#2.5.15">Section 2.5.15, "Mapping for +          <code>gYearMonth</code>"</a></td> +    </tr> +    <tr> +      <td><code>time</code></td> +      <td><code>time</code></td> +      <td><a href="#2.5.16">Section 2.5.16, "Mapping for +          <code>time</code>"</a></td> +    </tr> + +    <tr> +      <th colspan="3">entity types</th> +    </tr> +    <tr> +      <td><code>ENTITY</code></td> +      <td><code>entity</code></td> +      <td>type derived from <code>name</code></td> +    </tr> +    <tr> +      <td><code>ENTITIES</code></td> +      <td><code>entities</code></td> +      <td>type derived from <code>sequence<entity></code></td> +    </tr> +  </table> + +  <p>All XML Schema built-in types are mapped to C++ classes that are +     derived from the <code>xml_schema::simple_type</code> class except +     where the mapping is to a fundamental C++ type.</p> + +  <p>The <code>sequence</code> class template is defined in an +     implementation-specific namespace. It conforms to the +     sequence interface as defined by the ISO/ANSI Standard for +     C++ (ISO/IEC 14882:1998, Section 23.1.1, "Sequences"). +     Practically, this means that you can treat such a sequence +     as if it was <code>std::vector</code>. One notable extension +     to the standard interface that is available only for +     sequences of non-fundamental C++ types is the addition of +     the overloaded <code>push_back</code> and <code>insert</code> +     member functions which instead of the constant reference +     to the element type accept automatic pointer (<code>std::unique_ptr</code> +     or <code>std::auto_ptr</code>, depending on the C++ standard +     selected) to the element type. These functions assume ownership +     of the pointed to object and reset the passed automatic pointer. +  </p> + +  <h3><a name="2.5.1">2.5.1 Inheritance from Built-in Data Types</a></h3> + +  <p>In cases where the mapping calls for an inheritance from a built-in +     type which is mapped to a fundamental C++ type, a proxy type is +     used instead of the fundamental C++ type (C++ does not allow +     inheritance from fundamental types). For instance:</p> + +  <pre class="xml"> +<simpleType name="my_int"> +  <restriction base="int"/> +</simpleType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class my_int: public fundamental_base<int> +{ +  ... +}; +  </pre> + +  <p>The <code>fundamental_base</code> class template provides a close +     emulation (though not exact) of a fundamental C++ type. +     It is defined in an implementation-specific namespace and has the +     following interface:</p> + +  <pre class="c++"> +template <typename X> +class fundamental_base: public simple_type +{ +public: +  fundamental_base (); +  fundamental_base (X) +  fundamental_base (const fundamental_base&) + +public: +  fundamental_base& +  operator= (const X&); + +public: +  operator const X & () const; +  operator X& (); + +  template <typename Y> +  operator Y () const; + +  template <typename Y> +  operator Y (); +}; +  </pre> + +  <h3><a name="2.5.2">2.5.2 Mapping for <code>anyType</code></a></h3> + +  <p>The XML Schema <code>anyType</code> built-in data type is mapped to the +     <code>xml_schema::type</code> C++ class:</p> + +  <pre class="c++"> +class type +{ +public: +  virtual +  ~type (); + +  type (); +  type (const type&); + +  type& +  operator= (const type&); + +  virtual type* +  _clone () const; + +  // anyType DOM content. +  // +public: +  typedef element_optional dom_content_optional; + +  const dom_content_optional& +  dom_content () const; + +  dom_content_optional& +  dom_content (); + +  void +  dom_content (const xercesc::DOMElement&); + +  void +  dom_content (xercesc::DOMElement*); + +  void +  dom_content (const dom_content_optional&); + +  const xercesc::DOMDocument& +  dom_content_document () const; + +  xercesc::DOMDocument& +  dom_content_document (); + +  bool +  null_content () const; + +  // DOM association. +  // +public: +  const xercesc::DOMNode* +  _node () const; + +  xercesc::DOMNode* +  _node (); +}; +  </pre> + +  <p>When <code>xml_schema::type</code> is used to create an instance +     (as opposed to being a base of a derived type), it represents +     the XML Schema <code>anyType</code> type. <code>anyType</code> +     allows any attributes and any content in any order. In the +     C++/Tree mapping this content can be represented as a DOM +     fragment, similar to XML Schema wildcards (<a href="#2.12">Section +     2.12, "Mapping for <code>any</code> and +     <code>anyAttribute</code>"</a>).</p> + +  <p>To enable automatic extraction of <code>anyType</code> content +     during parsing, the <code>--generate-any-type</code> option must be +     specified. Because the DOM API is used to access such content, the +     Xerces-C++ runtime should be initialized by the application prior to +     parsing and should remain initialized for the lifetime of objects +     with the DOM content. For more information on the Xerces-C++ runtime +     initialization see <a href="#3.1">Section 3.1, "Initializing the +     Xerces-C++ Runtime"</a>.</p> + +  <p>The DOM content is stored as the optional DOM element container +     and the DOM content accessors and modifiers presented above are +     identical to those generated for an optional element wildcard. +     Refer to <a href="#2.12.2">Section 2.12.2, "Mapping for <code>any</code> +     with the Optional Cardinality Class"</a> for details on their +     semantics.</p> + +  <p>The <code>dom_content_document()</code> function returns the +     DOM document used to store the raw XML content corresponding +     to the <code>anyType</code> instance. It is equivalent to the +     <code>dom_document()</code> function generated for types +     with wildcards.</p> + +  <p>The <code>null_content()</code> accessor is an optimization function +     that allows us to check for the lack of content without actually +     creating its empty representation, that is, empty DOM document for +     <code>anyType</code> or empty string for <code>anySimpleType</code> +     (see the following section for details on <code>anySimpleType</code>).</p> + +  <p>For more information on DOM association refer to +     <a href="#5.1">Section 5.1, "DOM Association"</a>.</p> + +  <h3><a name="2.5.3">2.5.3 Mapping for <code>anySimpleType</code></a></h3> + +  <p>The XML Schema <code>anySimpleType</code> built-in data type is mapped +     to the <code>xml_schema::simple_type</code> C++ class:</p> + +  <pre class="c++"> +class simple_type: public type +{ +public: +  simple_type (); +  simple_type (const C*); +  simple_type (const std::basic_string<C>&); + +  simple_type (const simple_type&); + +  simple_type& +  operator= (const simple_type&); + +  virtual simple_type* +  _clone () const; + +  // anySimpleType text content. +  // +public: +  const std::basic_string<C>& +  text_content () const; + +  std::basic_string<C>& +  text_content (); + +  void +  text_content (const std::basic_string<C>&); +}; +  </pre> + +  <p>When <code>xml_schema::simple_type</code> is used to create an instance +     (as opposed to being a base of a derived type), it represents +     the XML Schema <code>anySimpleType</code> type. <code>anySimpleType</code> +     allows any simple content. In the C++/Tree mapping this content can +     be represented as a string and accessed or modified with the +     <code>text_content()</code> functions shown above.</p> + +  <h3><a name="2.5.4">2.5.4 Mapping for <code>QName</code></a></h3> + +  <p>The XML Schema <code>QName</code> built-in data type is mapped to the +     <code>xml_schema::qname</code> C++ class:</p> + +  <pre class="c++"> +class qname: public simple_type +{ +public: +  qname (const ncname&); +  qname (const uri&, const ncname&); +  qname (const qname&); + +public: +  qname& +  operator= (const qname&); + +public: +  virtual qname* +  _clone () const; + +public: +  bool +  qualified () const; + +  const uri& +  namespace_ () const; + +  const ncname& +  name () const; +}; +  </pre> + +  <p>The <code>qualified</code> accessor function can be used to determine +     if the name is qualified.</p> + +  <h3><a name="2.5.5">2.5.5 Mapping for <code>IDREF</code></a></h3> + +  <p>The XML Schema <code>IDREF</code> built-in data type is mapped to the +     <code>xml_schema::idref</code> C++ class. This class implements the +     smart pointer C++ idiom:</p> + +  <pre class="c++"> +class idref: public ncname +{ +public: +  idref (const C* s); +  idref (const C* s, std::size_t n); +  idref (std::size_t n, C c); +  idref (const std::basic_string<C>&); +  idref (const std::basic_string<C>&, +         std::size_t pos, +         std::size_t n = npos); + +public: +  idref (const idref&); + +public: +  virtual idref* +  _clone () const; + +public: +  idref& +  operator= (C c); + +  idref& +  operator= (const C* s); + +  idref& +  operator= (const std::basic_string<C>&) + +  idref& +  operator= (const idref&); + +public: +  const type* +  operator-> () const; + +  type* +  operator-> (); + +  const type& +  operator* () const; + +  type& +  operator* (); + +  const type* +  get () const; + +  type* +  get (); + +  // Conversion to bool. +  // +public: +  typedef void (idref::*bool_convertible)(); +  operator bool_convertible () const; +}; +  </pre> + +  <p>The object, <code>idref</code> instance refers to, is the immediate +     container of the matching <code>id</code> instance. For example, +     with the following instance document and schema: +  </p> + + +  <pre class="xml"> +<!-- test.xml --> +<root> +  <object id="obj-1" text="hello"/> +  <reference>obj-1</reference> +</root> + +<!-- test.xsd --> +<schema> +  <complexType name="object_type"> +    <attribute name="id" type="ID"/> +    <attribute name="text" type="string"/> +  </complexType> + +  <complexType name="root_type"> +    <sequence> +      <element name="object" type="object_type"/> +      <element name="reference" type="IDREF"/> +    </sequence> +  </complexType> + +  <element name="root" type="root_type"/> +</schema> +  </pre> + +  <p>The <code>ref</code> instance in the code below will refer to +     an object of type <code>object_type</code>:</p> + +  <pre class="c++"> +root_type& root = ...; +xml_schema::idref& ref (root.reference ()); +object_type& obj (dynamic_cast<object_type&> (*ref)); +cout << obj.text () << endl; +  </pre> + +  <p>The smart pointer interface of the <code>idref</code> class always +     returns a pointer or reference to <code>xml_schema::type</code>. +     This means that you will need to manually cast such pointer or +     reference to its real (dynamic) type before you can use it (unless +     all you need is the base interface provided by +     <code>xml_schema::type</code>). As a special extension to the XML +     Schema language, the mapping supports static typing of <code>idref</code> +     references by employing the <code>refType</code> extension attribute. +     The following example illustrates this mechanism: +  </p> + +  <pre class="xml"> +<!-- test.xsd --> +<schema +  xmlns:xse="https://www.codesynthesis.com/xmlns/xml-schema-extension"> + +  ... + +      <element name="reference" type="IDREF" xse:refType="object_type"/> + +  ... + +</schema> +  </pre> + +  <p>With this modification we do not need to do manual casting anymore: +  </p> + +  <pre class="c++"> +root_type& root = ...; +root_type::reference_type& ref (root.reference ()); +object_type& obj (*ref); +cout << ref->text () << endl; +  </pre> + + +  <h3><a name="2.5.6">2.5.6 Mapping for <code>base64Binary</code> and +      <code>hexBinary</code></a></h3> + +  <p>The XML Schema <code>base64Binary</code> and <code>hexBinary</code> +     built-in data types are mapped to the +     <code>xml_schema::base64_binary</code> and +     <code>xml_schema::hex_binary</code> C++ classes, respectively. The +     <code>base64_binary</code> and <code>hex_binary</code> classes +     support a simple buffer abstraction by inheriting from the +     <code>xml_schema::buffer</code> class: +  </p> + +  <pre class="c++"> +class bounds: public virtual exception +{ +public: +  virtual const char* +  what () const throw (); +}; + +class buffer +{ +public: +  typedef std::size_t size_t; + +public: +  buffer (size_t size = 0); +  buffer (size_t size, size_t capacity); +  buffer (const void* data, size_t size); +  buffer (const void* data, size_t size, size_t capacity); +  buffer (void* data, +          size_t size, +          size_t capacity, +          bool assume_ownership); + +public: +  buffer (const buffer&); + +  buffer& +  operator= (const buffer&); + +  void +  swap (buffer&); + +public: +  size_t +  capacity () const; + +  bool +  capacity (size_t); + +public: +  size_t +  size () const; + +  bool +  size (size_t); + +public: +  const char* +  data () const; + +  char* +  data (); + +  const char* +  begin () const; + +  char* +  begin (); + +  const char* +  end () const; + +  char* +  end (); +}; +  </pre> + +  <p>The last overloaded constructor reuses an existing data buffer instead +     of making a copy. If the <code>assume_ownership</code> argument is +     <code>true</code>, the instance assumes ownership of the +     memory block pointed to by the <code>data</code> argument and will +     eventually release it by calling <code>operator delete</code>. The +     <code>capacity</code> and <code>size</code> modifier functions return +     <code>true</code> if the underlying buffer has moved. +  </p> + +  <p>The <code>bounds</code> exception is thrown if the constructor +     arguments violate the <code>(size <= capacity)</code> +     constraint.</p> + +  <p>The <code>base64_binary</code> and <code>hex_binary</code> classes +     support the <code>buffer</code> interface and perform automatic +     decoding/encoding from/to the Base64 and Hex formats, respectively: +  </p> + +  <pre class="c++"> +class base64_binary: public simple_type, public buffer +{ +public: +  base64_binary (size_t size = 0); +  base64_binary (size_t size, size_t capacity); +  base64_binary (const void* data, size_t size); +  base64_binary (const void* data, size_t size, size_t capacity); +  base64_binary (void* data, +                 size_t size, +                 size_t capacity, +                 bool assume_ownership); + +public: +  base64_binary (const base64_binary&); + +  base64_binary& +  operator= (const base64_binary&); + +  virtual base64_binary* +  _clone () const; + +public: +  std::basic_string<C> +  encode () const; +}; +  </pre> + +  <pre class="c++"> +class hex_binary: public simple_type, public buffer +{ +public: +  hex_binary (size_t size = 0); +  hex_binary (size_t size, size_t capacity); +  hex_binary (const void* data, size_t size); +  hex_binary (const void* data, size_t size, size_t capacity); +  hex_binary (void* data, +              size_t size, +              size_t capacity, +              bool assume_ownership); + +public: +  hex_binary (const hex_binary&); + +  hex_binary& +  operator= (const hex_binary&); + +  virtual hex_binary* +  _clone () const; + +public: +  std::basic_string<C> +  encode () const; +}; +  </pre> + + +  <h2><a name="2.5.7">2.5.7 Time Zone Representation</a></h2> + +  <p>The <code>date</code>, <code>dateTime</code>, <code>gDay</code>, +     <code>gMonth</code>, <code>gMonthDay</code>, <code>gYear</code>, +     <code>gYearMonth</code>, and <code>time</code> XML Schema built-in +     types all include an optional time zone component. The following +     <code>xml_schema::time_zone</code> base class is used to represent +     this information:</p> + +  <pre class="c++"> +class time_zone +{ +public: +  time_zone (); +  time_zone (short hours, short minutes); + +  bool +  zone_present () const; + +  void +  zone_reset (); + +  short +  zone_hours () const; + +  void +  zone_hours (short); + +  short +  zone_minutes () const; + +  void +  zone_minutes (short); +}; + +bool +operator== (const time_zone&, const time_zone&); + +bool +operator!= (const time_zone&, const time_zone&); +  </pre> + +  <p>The <code>zone_present()</code> accessor function returns <code>true</code> +     if the time zone is specified. The <code>zone_reset()</code> modifier +     function resets the time zone object to the <em>not specified</em> +     state. If the time zone offset is negative then both hours and +     minutes components are represented as negative integers.</p> + + +  <h2><a name="2.5.8">2.5.8 Mapping for <code>date</code></a></h2> + + <p>The XML Schema <code>date</code> built-in data type is mapped to the +    <code>xml_schema::date</code> C++ class which represents a year, a day, +    and a month with an optional time zone. Its interface is presented +    below. For more information on the base <code>xml_schema::time_zone</code> +    class refer to <a href="#2.5.7">Section 2.5.7, "Time Zone +    Representation"</a>.</p> + +  <pre class="c++"> +class date: public simple_type, public time_zone +{ +public: +  date (int year, unsigned short month, unsigned short day); +  date (int year, unsigned short month, unsigned short day, +        short zone_hours, short zone_minutes); + +public: +  date (const date&); + +  date& +  operator= (const date&); + +  virtual date* +  _clone () const; + +public: +  int +  year () const; + +  void +  year (int); + +  unsigned short +  month () const; + +  void +  month (unsigned short); + +  unsigned short +  day () const; + +  void +  day (unsigned short); +}; + +bool +operator== (const date&, const date&); + +bool +operator!= (const date&, const date&); +  </pre> + +  <h2><a name="2.5.9">2.5.9 Mapping for <code>dateTime</code></a></h2> + + <p>The XML Schema <code>dateTime</code> built-in data type is mapped to the +    <code>xml_schema::date_time</code> C++ class which represents a year, a month, +    a day, hours, minutes, and seconds with an optional time zone. Its interface +    is presented below. For more information on the base +    <code>xml_schema::time_zone</code> class refer to <a href="#2.5.7">Section +    2.5.7, "Time Zone Representation"</a>.</p> + +  <pre class="c++"> +class date_time: public simple_type, public time_zone +{ +public: +  date_time (int year, unsigned short month, unsigned short day, +             unsigned short hours, unsigned short minutes, +             double seconds); + +  date_time (int year, unsigned short month, unsigned short day, +             unsigned short hours, unsigned short minutes, +             double seconds, short zone_hours, short zone_minutes); +public: +  date_time (const date_time&); + +  date_time& +  operator= (const date_time&); + +  virtual date_time* +  _clone () const; + +public: +  int +  year () const; + +  void +  year (int); + +  unsigned short +  month () const; + +  void +  month (unsigned short); + +  unsigned short +  day () const; + +  void +  day (unsigned short); + +  unsigned short +  hours () const; + +  void +  hours (unsigned short); + +  unsigned short +  minutes () const; + +  void +  minutes (unsigned short); + +  double +  seconds () const; + +  void +  seconds (double); +}; + +bool +operator== (const date_time&, const date_time&); + +bool +operator!= (const date_time&, const date_time&); +  </pre> + + +  <h2><a name="2.5.10">2.5.10 Mapping for <code>duration</code></a></h2> + +  <p>The XML Schema <code>duration</code> built-in data type is mapped to the +    <code>xml_schema::duration</code> C++ class which represents a potentially +     negative duration in the form of years, months, days, hours, minutes, +     and seconds. Its interface is presented below.</p> + +  <pre class="c++"> +class duration: public simple_type +{ +public: +  duration (bool negative, +            unsigned int years, unsigned int months, unsigned int days, +            unsigned int hours, unsigned int minutes, double seconds); +public: +  duration (const duration&); + +  duration& +  operator= (const duration&); + +  virtual duration* +  _clone () const; + +public: +  bool +  negative () const; + +  void +  negative (bool); + +  unsigned int +  years () const; + +  void +  years (unsigned int); + +  unsigned int +  months () const; + +  void +  months (unsigned int); + +  unsigned int +  days () const; + +  void +  days (unsigned int); + +  unsigned int +  hours () const; + +  void +  hours (unsigned int); + +  unsigned int +  minutes () const; + +  void +  minutes (unsigned int); + +  double +  seconds () const; + +  void +  seconds (double); +}; + +bool +operator== (const duration&, const duration&); + +bool +operator!= (const duration&, const duration&); +  </pre> + + +  <h2><a name="2.5.11">2.5.11 Mapping for <code>gDay</code></a></h2> + +  <p>The XML Schema <code>gDay</code> built-in data type is mapped to the +    <code>xml_schema::gday</code> C++ class which represents a day of the +     month with an optional time zone. Its interface is presented below. +     For more information on the base <code>xml_schema::time_zone</code> +     class refer to <a href="#2.5.7">Section 2.5.7, "Time Zone +     Representation"</a>.</p> + +  <pre class="c++"> +class gday: public simple_type, public time_zone +{ +public: +  explicit +  gday (unsigned short day); +  gday (unsigned short day, short zone_hours, short zone_minutes); + +public: +  gday (const gday&); + +  gday& +  operator= (const gday&); + +  virtual gday* +  _clone () const; + +public: +  unsigned short +  day () const; + +  void +  day (unsigned short); +}; + +bool +operator== (const gday&, const gday&); + +bool +operator!= (const gday&, const gday&); +  </pre> + + +  <h2><a name="2.5.12">2.5.12 Mapping for <code>gMonth</code></a></h2> + +  <p>The XML Schema <code>gMonth</code> built-in data type is mapped to the +    <code>xml_schema::gmonth</code> C++ class which represents a month of the +     year with an optional time zone. Its interface is presented below. +     For more information on the base <code>xml_schema::time_zone</code> +     class refer to <a href="#2.5.7">Section 2.5.7, "Time Zone +     Representation"</a>.</p> + +  <pre class="c++"> +class gmonth: public simple_type, public time_zone +{ +public: +  explicit +  gmonth (unsigned short month); +  gmonth (unsigned short month, +          short zone_hours, short zone_minutes); + +public: +  gmonth (const gmonth&); + +  gmonth& +  operator= (const gmonth&); + +  virtual gmonth* +  _clone () const; + +public: +  unsigned short +  month () const; + +  void +  month (unsigned short); +}; + +bool +operator== (const gmonth&, const gmonth&); + +bool +operator!= (const gmonth&, const gmonth&); +  </pre> + + +  <h2><a name="2.5.13">2.5.13 Mapping for <code>gMonthDay</code></a></h2> + +  <p>The XML Schema <code>gMonthDay</code> built-in data type is mapped to the +    <code>xml_schema::gmonth_day</code> C++ class which represents a day and +     a month of the year with an optional time zone. Its interface is presented +     below. For more information on the base <code>xml_schema::time_zone</code> +     class refer to <a href="#2.5.7">Section 2.5.7, "Time Zone +     Representation"</a>.</p> + +  <pre class="c++"> +class gmonth_day: public simple_type, public time_zone +{ +public: +  gmonth_day (unsigned short month, unsigned short day); +  gmonth_day (unsigned short month, unsigned short day, +              short zone_hours, short zone_minutes); + +public: +  gmonth_day (const gmonth_day&); + +  gmonth_day& +  operator= (const gmonth_day&); + +  virtual gmonth_day* +  _clone () const; + +public: +  unsigned short +  month () const; + +  void +  month (unsigned short); + +  unsigned short +  day () const; + +  void +  day (unsigned short); +}; + +bool +operator== (const gmonth_day&, const gmonth_day&); + +bool +operator!= (const gmonth_day&, const gmonth_day&); +  </pre> + + +  <h2><a name="2.5.14">2.5.14 Mapping for <code>gYear</code></a></h2> + +  <p>The XML Schema <code>gYear</code> built-in data type is mapped to the +    <code>xml_schema::gyear</code> C++ class which represents a year with +     an optional time zone. Its interface is presented below. For more +     information on the base <code>xml_schema::time_zone</code> class refer +     to <a href="#2.5.7">Section 2.5.7, "Time Zone Representation"</a>.</p> + +  <pre class="c++"> +class gyear: public simple_type, public time_zone +{ +public: +  explicit +  gyear (int year); +  gyear (int year, short zone_hours, short zone_minutes); + +public: +  gyear (const gyear&); + +  gyear& +  operator= (const gyear&); + +  virtual gyear* +  _clone () const; + +public: +  int +  year () const; + +  void +  year (int); +}; + +bool +operator== (const gyear&, const gyear&); + +bool +operator!= (const gyear&, const gyear&); +  </pre> + + +  <h2><a name="2.5.15">2.5.15 Mapping for <code>gYearMonth</code></a></h2> + +  <p>The XML Schema <code>gYearMonth</code> built-in data type is mapped to +     the <code>xml_schema::gyear_month</code> C++ class which represents +     a year and a month with an optional time zone. Its interface is presented +     below. For more information on the base <code>xml_schema::time_zone</code> +     class refer to <a href="#2.5.7">Section 2.5.7, "Time Zone +     Representation"</a>.</p> + +  <pre class="c++"> +class gyear_month: public simple_type, public time_zone +{ +public: +  gyear_month (int year, unsigned short month); +  gyear_month (int year, unsigned short month, +               short zone_hours, short zone_minutes); +public: +  gyear_month (const gyear_month&); + +  gyear_month& +  operator= (const gyear_month&); + +  virtual gyear_month* +  _clone () const; + +public: +  int +  year () const; + +  void +  year (int); + +  unsigned short +  month () const; + +  void +  month (unsigned short); +}; + +bool +operator== (const gyear_month&, const gyear_month&); + +bool +operator!= (const gyear_month&, const gyear_month&); +  </pre> + + +  <h2><a name="2.5.16">2.5.16 Mapping for <code>time</code></a></h2> + +  <p>The XML Schema <code>time</code> built-in data type is mapped to +     the <code>xml_schema::time</code> C++ class which represents hours, +     minutes, and seconds with an optional time zone. Its interface is +     presented below. For more information on the base +     <code>xml_schema::time_zone</code> class refer to +     <a href="#2.5.7">Section 2.5.7, "Time Zone Representation"</a>.</p> + +  <pre class="c++"> +class time: public simple_type, public time_zone +{ +public: +  time (unsigned short hours, unsigned short minutes, double seconds); +  time (unsigned short hours, unsigned short minutes, double seconds, +        short zone_hours, short zone_minutes); + +public: +  time (const time&); + +  time& +  operator= (const time&); + +  virtual time* +  _clone () const; + +public: +  unsigned short +  hours () const; + +  void +  hours (unsigned short); + +  unsigned short +  minutes () const; + +  void +  minutes (unsigned short); + +  double +  seconds () const; + +  void +  seconds (double); +}; + +bool +operator== (const time&, const time&); + +bool +operator!= (const time&, const time&); +  </pre> + + +  <!-- Mapping for Simple Types --> + +  <h2><a name="2.6">2.6 Mapping for Simple Types</a></h2> + +  <p>An XML Schema simple type is mapped to a C++ class with the same +     name as the simple type. The class defines a public copy constructor, +     a public copy assignment operator, and a public virtual +     <code>_clone</code> function. The <code>_clone</code> function is +     declared <code>const</code>, does not take any arguments, and returns +     a pointer to a complete copy of the instance allocated in the free +     store. The <code>_clone</code> function shall be used to make copies +     when static type and dynamic type of the instance may differ (see +     <a href="#2.11">Section 2.11, "Mapping for <code>xsi:type</code> +     and Substitution Groups"</a>). For instance:</p> + +  <pre class="xml"> +<simpleType name="object"> +  ... +</simpleType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class object: ... +{ +public: +  object (const object&); + +public: +  object& +  operator= (const object&); + +public: +  virtual object* +  _clone () const; + +  ... + +}; +  </pre> + +  <p>The base class specification and the rest of the class definition +     depend on the type of derivation used to define the simple type. </p> + + +  <h3><a name="2.6.1">2.6.1 Mapping for Derivation by Restriction</a></h3> + +  <p>XML Schema derivation by restriction is mapped to C++ public +     inheritance. The base type of the restriction becomes the base +     type for the resulting C++ class. In addition to the members described +     in <a href="#2.6">Section 2.6, "Mapping for Simple Types"</a>, the +     resulting C++ class defines a public constructor with the base type +     as its single argument. For instance:</p> + +  <pre class="xml"> +<simpleType name="object"> +  <restriction base="base"> +    ... +  </restriction> +</simpleType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class object: public base +{ +public: +  object (const base&); +  object (const object&); + +public: +  object& +  operator= (const object&); + +public: +  virtual object* +  _clone () const; +}; +  </pre> + + +  <h3><a name="2.6.2">2.6.2 Mapping for Enumerations</a></h3> + +<p>XML Schema restriction by enumeration is mapped to a C++ class +   with semantics similar to C++ <code>enum</code>. Each XML Schema +   enumeration element is mapped to a C++ enumerator with the +   name derived from the <code>value</code> attribute and defined +   in the class scope. In addition to the members +   described in <a href="#2.6">Section 2.6, "Mapping for Simple Types"</a>, +   the resulting C++ class defines a public constructor that can be called +   with one of the enumerators as its single argument, a public constructor +   that can be called with enumeration's base value as its single +   argument, a public assignment operator that can be used to assign the +   value of one of the enumerators, and a public implicit conversion +   operator to the underlying C++ enum type.</p> + +<p>Furthermore, for string-based enumeration types, the resulting C++ +   class defines a public constructor with a single argument of type +   <code>const C*</code> and a public constructor with a single +   argument of type <code>const std::basic_string<C>&</code>. +   For instance:</p> + +  <pre class="xml"> +<simpleType name="color"> +  <restriction base="string"> +    <enumeration value="red"/> +    <enumeration value="green"/> +    <enumeration value="blue"/> +  </restriction> +</simpleType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class color: public xml_schema::string +{ +public: +  enum value +  { +    red, +    green, +    blue +  }; + +public: +  color (value); +  color (const C*); +  color (const std::basic_string<C>&); +  color (const xml_schema::string&); +  color (const color&); + +public: +  color& +  operator= (value); + +  color& +  operator= (const color&); + +public: +  virtual color* +  _clone () const; + +public: +  operator value () const; +}; +  </pre> + +  <h3><a name="2.6.3">2.6.3 Mapping for Derivation by List</a></h3> + +  <p>XML Schema derivation by list is mapped to C++ public +     inheritance from <code>xml_schema::simple_type</code> +     (<a href="#2.5.3">Section 2.5.3, "Mapping for +     <code>anySimpleType</code>"</a>) and a suitable sequence type. +     The list item type becomes the element type of the sequence. +     In addition to the members described in <a href="#2.6">Section 2.6, +     "Mapping for Simple Types"</a>, the resulting C++ class defines +     a public default constructor, a public constructor +     with the first argument of type <code>size_type</code> and +     the second argument of list item type that creates +     a list object with the specified number of copies of the specified +     element value, and a public constructor with the two arguments +     of an input iterator type that creates a list object from an +     iterator range. For instance: +  </p> + +  <pre class="xml"> +<simpleType name="int_list"> +  <list itemType="int"/> +</simpleType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class int_list: public simple_type, +                public sequence<int> +{ +public: +  int_list (); +  int_list (size_type n, int x); + +  template <typename I> +  int_list (const I& begin, const I& end); +  int_list (const int_list&); + +public: +  int_list& +  operator= (const int_list&); + +public: +  virtual int_list* +  _clone () const; +}; +  </pre> + +  <p>The <code>sequence</code> class template is defined in an +     implementation-specific namespace. It conforms to the +     sequence interface as defined by the ISO/ANSI Standard for +     C++ (ISO/IEC 14882:1998, Section 23.1.1, "Sequences"). +     Practically, this means that you can treat such a sequence +     as if it was <code>std::vector</code>. One notable extension +     to the standard interface that is available only for +     sequences of non-fundamental C++ types is the addition of +     the overloaded <code>push_back</code> and <code>insert</code> +     member functions which instead of the constant reference +     to the element type accept automatic pointer (<code>std::unique_ptr</code> +     or <code>std::auto_ptr</code>, depending on the C++ standard +     selected) to the element type. These functions assume ownership +     of the pointed to object and reset the passed automatic pointer. +  </p> + +  <h3><a name="2.6.4">2.6.4 Mapping for Derivation by Union</a></h3> + +  <p>XML Schema derivation by union is mapped to C++ public +     inheritance from <code>xml_schema::simple_type</code> +     (<a href="#2.5.3">Section 2.5.3, "Mapping for +     <code>anySimpleType</code>"</a>) and <code>std::basic_string<C></code>. +     In addition to the members described in <a href="#2.6">Section 2.6, +     "Mapping for Simple Types"</a>, the resulting C++ class defines a +     public constructor with a single argument of type <code>const C*</code> +     and a public constructor with a single argument of type +     <code>const std::basic_string<C>&</code>. For instance: +  </p> + +  <pre class="xml"> +<simpleType name="int_string_union"> +  <xsd:union memberTypes="xsd:int xsd:string"/> +</simpleType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class int_string_union: public simple_type, +                        public std::basic_string<C> +{ +public: +  int_string_union (const C*); +  int_string_union (const std::basic_string<C>&); +  int_string_union (const int_string_union&); + +public: +  int_string_union& +  operator= (const int_string_union&); + +public: +  virtual int_string_union* +  _clone () const; +}; +  </pre> + +  <h2><a name="2.7">2.7 Mapping for Complex Types</a></h2> + +  <p>An XML Schema complex type is mapped to a C++ class with the same +     name as the complex type. The class defines a public copy constructor, +     a public copy assignment operator, and a public virtual +     <code>_clone</code> function. The <code>_clone</code> function is +     declared <code>const</code>, does not take any arguments, and returns +     a pointer to a complete copy of the instance allocated in the free +     store. The <code>_clone</code> function shall be used to make copies +     when static type and dynamic type of the instance may differ (see +     <a href="#2.11">Section 2.11, "Mapping for <code>xsi:type</code> +     and Substitution Groups"</a>).</p> + +  <p>Additionally, the resulting C++ class +     defines two public constructors that take an initializer for each +     member of the complex type and all its base types that belongs to +     the One cardinality class (see <a href="#2.8">Section 2.8, "Mapping +     for Local Elements and Attributes"</a>). In the first constructor, +     the arguments are passed as constant references and the newly created +     instance is initialized with copies of the passed objects. In the +     second constructor, arguments that are complex types (that is, +     they themselves contain elements or attributes) are passed as +     either <code>std::unique_ptr</code> (C++11) or <code>std::auto_ptr</code> +     (C++98), depending on the C++ standard selected. In this case the newly +     created instance is directly initialized with and assumes ownership +     of the pointed to objects and the <code>std::[unique|auto]_ptr</code> +     arguments are reset to <code>0</code>. For instance:</p> + +  <pre class="xml"> +<complexType name="complex"> +  <sequence> +    <element name="a" type="int"/> +    <element name="b" type="string"/> +  </sequence> +</complexType> + +<complexType name="object"> +  <sequence> +    <element name="s-one" type="boolean"/> +    <element name="c-one" type="complex"/> +    <element name="optional" type="int" minOccurs="0"/> +    <element name="sequence" type="string" maxOccurs="unbounded"/> +  </sequence> +</complexType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class complex: public xml_schema::type +{ +public: +  object (const int& a, const xml_schema::string& b); +  object (const complex&); + +public: +  object& +  operator= (const complex&); + +public: +  virtual complex* +  _clone () const; + +  ... + +}; + +class object: public xml_schema::type +{ +public: +  object (const bool& s_one, const complex& c_one); +  object (const bool& s_one, std::[unique|auto]_ptr<complex> c_one); +  object (const object&); + +public: +  object& +  operator= (const object&); + +public: +  virtual object* +  _clone () const; + +  ... + +}; +  </pre> + +  <p>Notice that the generated <code>complex</code> class does not +     have the second (<code>std::[unique|auto]_ptr</code>) version of the +     constructor since all its required members are of simple types.</p> + +  <p>If an XML Schema complex type has an ultimate base which is an XML +     Schema simple type then the resulting C++ class also defines a public +     constructor that takes an initializer for the base type as well as +     for each member of the complex type and all its base types that +     belongs to the One cardinality class. For instance:</p> + +  <pre class="xml"> +<complexType name="object"> +  <simpleContent> +    <extension base="date"> +      <attribute name="lang" type="language" use="required"/> +    </extension> +  </simpleContent> +</complexType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class object: public xml_schema::string +{ +public: +  object (const xml_schema::language& lang); + +  object (const xml_schema::date& base, +          const xml_schema::language& lang); + +  ... + +}; +  </pre> + +  <p>Furthermore, for string-based XML Schema complex types, the resulting C++ +     class also defines two  public constructors with the first arguments +     of type <code>const C*</code> and <code>std::basic_string<C>&</code>, +     respectively, followed by arguments for each member of the complex +     type and all its base types that belongs to the One cardinality +     class. For enumeration-based complex types the resulting C++ +     class also defines a public constructor with the first arguments +     of the underlying enum type followed by arguments for each member +     of the complex type and all its base types that belongs to the One +     cardinality class. For instance:</p> + +  <pre class="xml"> +<simpleType name="color"> +  <restriction base="string"> +    <enumeration value="red"/> +    <enumeration value="green"/> +    <enumeration value="blue"/> +  </restriction> +</simpleType> + +<complexType name="object"> +  <simpleContent> +    <extension base="color"> +      <attribute name="lang" type="language" use="required"/> +    </extension> +  </simpleContent> +</complexType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class color: public xml_schema::string +{ +public: +  enum value +  { +    red, +    green, +    blue +  }; + +public: +  color (value); +  color (const C*); +  color (const std::basic_string<C>&); + +  ... + +}; + +class object: color +{ +public: +  object (const color& base, +          const xml_schema::language& lang); + +  object (const color::value& base, +          const xml_schema::language& lang); + +  object (const C* base, +          const xml_schema::language& lang); + +  object (const std::basic_string<C>& base, +          const xml_schema::language& lang); + +  ... + +}; +  </pre> + +  <p>Additional constructors can be requested with the +     <code>--generate-default-ctor</code> and +     <code>--generate-from-base-ctor</code> options. See the +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD +     Compiler Command Line Manual</a> for details.</p> + +  <p>If an XML Schema complex type is not explicitly derived from any type, +     the resulting C++ class is derived from <code>xml_schema::type</code>. +     In cases where an XML Schema complex type is defined using derivation +     by extension or restriction, the resulting C++ base class specification +     depends on the type of derivation and is described in the subsequent +     sections. +  </p> + +  <p>The mapping for elements and attributes that are defined in a complex +     type is described in <a href="#2.8">Section 2.8, "Mapping for Local +     Elements and Attributes"</a>. +  </p> + +  <h3><a name="2.7.1">2.7.1 Mapping for Derivation by Extension</a></h3> + +  <p>XML Schema derivation by extension is mapped to C++ public +     inheritance. The base type of the extension becomes the base +     type for the resulting C++ class. +  </p> + +  <h3><a name="2.7.2">2.7.2 Mapping for Derivation by Restriction</a></h3> + +  <p>XML Schema derivation by restriction is mapped to C++ public +     inheritance. The base type of the restriction becomes the base +     type for the resulting C++ class. XML Schema elements and +     attributes defined within restriction do not result in any +     definitions in the resulting C++ class. Instead, corresponding +     (unrestricted) definitions are inherited from the base class. +     In the future versions of this mapping, such elements and +     attributes may result in redefinitions of accessors and +     modifiers to reflect their restricted semantics. +  </p> + +  <!-- 2.8 Mapping for Local Elements and Attributes --> + +  <h2><a name="2.8">2.8 Mapping for Local Elements and Attributes</a></h2> + +   <p>XML Schema element and attribute definitions are called local +      if they appear within a complex type definition, an element group +      definition, or an attribute group definitions. +   </p> + +   <p>Local XML Schema element and attribute definitions have the same +      C++ mapping. Therefore, in this section, local elements and +      attributes are collectively called members. +   </p> + +   <p>While there are many different member cardinality combinations +      (determined by the <code>use</code> attribute for attributes and +       the <code>minOccurs</code> and <code>maxOccurs</code> attributes +       for elements), the mapping divides all possible cardinality +       combinations into three cardinality classes: +   </p> + +   <dl> +     <dt><i>one</i></dt> +     <dd>attributes: <code>use == "required"</code></dd> +     <dd>attributes: <code>use == "optional"</code> and has default or fixed value</dd> +     <dd>elements: <code>minOccurs == "1"</code> and <code>maxOccurs == "1"</code></dd> + +     <dt><i>optional</i></dt> +     <dd>attributes: <code>use == "optional"</code> and doesn't have default or fixed value</dd> +     <dd>elements: <code>minOccurs == "0"</code> and <code>maxOccurs == "1"</code></dd> + +     <dt><i>sequence</i></dt> +     <dd>elements: <code>maxOccurs > "1"</code></dd> +   </dl> + +   <p>An optional attribute with a default or fixed value acquires this value +      if the attribute hasn't been specified in an instance document (see +      <a href="#A">Appendix A, "Default and Fixed Values"</a>). This +      mapping places such optional attributes to the One cardinality +      class.</p> + +   <p>A member is mapped to a set of public type definitions +      (<code>typedef</code>s) and a set of public accessor and modifier +      functions. Type definitions have names derived from the member's +      name. The accessor and modifier functions have the same name as the +      member. For example: +   </p> + +  <pre class="xml"> +<complexType name="object"> +  <sequence> +    <element name="member" type="string"/> +  </sequence> +</complexType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class object: public xml_schema::type +{ +public: +  typedef xml_schema::string member_type; + +  const member_type& +  member () const; + +  ... + +}; +  </pre> + +   <p>In addition, if a member has a default or fixed value, a static +      accessor function is generated that returns this value. For +      example:</p> + +<pre class="xml"> +<complexType name="object"> +  <attribute name="data" type="string" default="test"/> +</complexType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class object: public xml_schema::type +{ +public: +  typedef xml_schema::string data_type; + +  const data_type& +  data () const; + +  static const data_type& +  data_default_value (); + +  ... + +}; +  </pre> + +   <p>Names and semantics of type definitions for the member as well +      as signatures of the accessor and modifier functions depend on +      the member's cardinality class and are described in the following +      sub-sections. +   </p> + + +  <h3><a name="2.8.1">2.8.1 Mapping for Members with the One Cardinality Class</a></h3> + +   <p>For the One cardinality class, the type definitions consist of +      an alias for the member's type with the name created by appending +      the <code>_type</code> suffix to the member's name. +   </p> + +   <p>The accessor functions come in constant and non-constant versions. +      The constant accessor function returns a constant reference to the +      member and can be used for read-only access. The non-constant +      version returns an unrestricted reference to the member and can +      be used for read-write access. +   </p> + +   <p>The first modifier function expects an argument of type reference to +      constant of the member's type. It makes a deep copy of its argument. +      Except for member's types that are mapped to fundamental C++ types, +      the second modifier function is provided that expects an argument +      of type automatic pointer (<code>std::unique_ptr</code> or +      <code>std::auto_ptr</code>, depending on the C++ standard selected) +      to the member's type. It assumes ownership of the pointed to object +      and resets the passed automatic pointer. For instance:</p> + +  <pre class="xml"> +<complexType name="object"> +  <sequence> +    <element name="member" type="string"/> +  </sequence> +</complexType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class object: public xml_schema::type +{ +public: +  // Type definitions. +  // +  typedef xml_schema::string member_type; + +  // Accessors. +  // +  const member_type& +  member () const; + +  member_type& +  member (); + +  // Modifiers. +  // +  void +  member (const member_type&); + +  void +  member (std::[unique|auto]_ptr<member_type>); +  ... + +}; +  </pre> + +   <p>In addition, if requested by specifying the <code>--generate-detach</code> +      option and only for members of non-fundamental C++ types, the mapping +      provides a detach function that returns an automatic pointer to the +      member's type, for example:</p> + +  <pre class="c++"> +class object: public xml_schema::type +{ +public: +  ... + +  std::[unique|auto]_ptr<member_type> +  detach_member (); +  ... + +}; +  </pre> + +   <p>This function detaches the value from the tree leaving the member +      value uninitialized. Accessing such an uninitialized value prior to +      re-initializing it results in undefined behavior.</p> + +  <p>The following code shows how one could use this mapping:</p> + +  <pre class="c++"> +void +f (object& o) +{ +  using xml_schema::string; + +  string s (o.member ());                // get +  object::member_type& sr (o.member ()); // get + +  o.member ("hello");           // set, deep copy +  o.member () = "hello";        // set, deep copy + +  // C++11 version. +  // +  std::unique_ptr<string> p (new string ("hello")); +  o.member (std::move (p));     // set, assumes ownership +  p = o.detach_member ();       // detach, member is uninitialized +  o.member (std::move (p));     // re-attach + +  // C++98 version. +  // +  std::auto_ptr<string> p (new string ("hello")); +  o.member (p);                 // set, assumes ownership +  p = o.detach_member ();       // detach, member is uninitialized +  o.member (p);                 // re-attach +} +  </pre> + + +<h3><a name="2.8.2">2.8.2 Mapping for Members with the Optional Cardinality Class</a></h3> + +   <p>For the Optional cardinality class, the type definitions consist of +      an alias for the member's type with the name created by appending +      the <code>_type</code> suffix to the member's name and an alias for +      the container type with the name created by appending the +      <code>_optional</code> suffix to the member's name. +   </p> + +   <p>Unlike accessor functions for the One cardinality class, accessor +      functions for the Optional cardinality class return references to +      corresponding containers rather than directly to members. The +      accessor functions come in constant and non-constant versions. +      The constant accessor function returns a constant reference to +      the container and can be used for read-only access. The non-constant +      version returns an unrestricted reference to the container +      and can be used for read-write access. +   </p> + +   <p>The modifier functions are overloaded for the member's +      type and the container type. The first modifier function +      expects an argument of type reference to constant of the +      member's type. It makes a deep copy of its argument. +      Except for member's types that are mapped to fundamental C++ types, +      the second modifier function is provided that expects an argument +      of type automatic pointer (<code>std::unique_ptr</code> or +      <code>std::auto_ptr</code>, depending on the C++ standard selected) +      to the member's type. It assumes ownership of the pointed to object +      and resets the passed automatic pointer. The last modifier function +      expects an argument of type reference to constant of the container +      type. It makes a deep copy of its argument. For instance: +   </p> + +  <pre class="xml"> +<complexType name="object"> +  <sequence> +    <element name="member" type="string" minOccurs="0"/> +  </sequence> +</complexType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class object: public xml_schema::type +{ +public: +  // Type definitions. +  // +  typedef xml_schema::string member_type; +  typedef optional<member_type> member_optional; + +  // Accessors. +  // +  const member_optional& +  member () const; + +  member_optional& +  member (); + +  // Modifiers. +  // +  void +  member (const member_type&); + +  void +  member (std::[unique|auto]_ptr<member_type>); + +  void +  member (const member_optional&); + +  ... + +}; +  </pre> + + +  <p>The <code>optional</code> class template is defined in an +     implementation-specific namespace and has the following +     interface. The <code>[unique|auto]_ptr</code>-based constructor +     and modifier function are only available if the template +     argument is not a fundamental C++ type. +  </p> + +  <pre class="c++"> +template <typename X> +class optional +{ +public: +  optional (); + +  // Makes a deep copy. +  // +  explicit +  optional (const X&); + +  // Assumes ownership. +  // +  explicit +  optional (std::[unique|auto]_ptr<X>); + +  optional (const optional&); + +public: +  optional& +  operator= (const X&); + +  optional& +  operator= (const optional&); + +  // Pointer-like interface. +  // +public: +  const X* +  operator-> () const; + +  X* +  operator-> (); + +  const X& +  operator* () const; + +  X& +  operator* (); + +  typedef void (optional::*bool_convertible) (); +  operator bool_convertible () const; + +  // Get/set interface. +  // +public: +  bool +  present () const; + +  const X& +  get () const; + +  X& +  get (); + +  // Makes a deep copy. +  // +  void +  set (const X&); + +  // Assumes ownership. +  // +  void +  set (std::[unique|auto]_ptr<X>); + +  // Detach and return the contained value. +  // +  std::[unique|auto]_ptr<X> +  detach (); + +  void +  reset (); +}; + +template <typename X> +bool +operator== (const optional<X>&, const optional<X>&); + +template <typename X> +bool +operator!= (const optional<X>&, const optional<X>&); + +template <typename X> +bool +operator< (const optional<X>&, const optional<X>&); + +template <typename X> +bool +operator> (const optional<X>&, const optional<X>&); + +template <typename X> +bool +operator<= (const optional<X>&, const optional<X>&); + +template <typename X> +bool +operator>= (const optional<X>&, const optional<X>&); +  </pre> + + +  <p>The following code shows how one could use this mapping:</p> + +  <pre class="c++"> +void +f (object& o) +{ +  using xml_schema::string; + +  if (o.member ().present ())       // test +  { +    string& s (o.member ().get ()); // get +    o.member ("hello");             // set, deep copy +    o.member ().set ("hello");      // set, deep copy +    o.member ().reset ();           // reset +  } + +  // Same as above but using pointer notation: +  // +  if (o.member ())                  // test +  { +    string& s (*o.member ());       // get +    o.member ("hello");             // set, deep copy +    *o.member () = "hello";         // set, deep copy +    o.member ().reset ();           // reset +  } + +  // C++11 version. +  // +  std::unique_ptr<string> p (new string ("hello")); +  o.member (std::move (p));         // set, assumes ownership + +  p.reset (new string ("hello")); +  o.member ().set (std::move (p));  // set, assumes ownership + +  p = o.member ().detach ();        // detach, member is reset +  o.member ().set (std::move (p));  // re-attach + +  // C++98 version. +  // +  std::auto_ptr<string> p (new string ("hello")); +  o.member (p);                     // set, assumes ownership + +  p = new string ("hello"); +  o.member ().set (p);              // set, assumes ownership + +  p = o.member ().detach ();        // detach, member is reset +  o.member ().set (p);              // re-attach +} +  </pre> + + +  <h3><a name="2.8.3">2.8.3 Mapping for Members with the Sequence Cardinality Class</a></h3> + +   <p>For the Sequence cardinality class, the type definitions consist of an +      alias for the member's type with the name created by appending +      the <code>_type</code> suffix to the member's name, an alias of +      the container type with the name created by appending the +      <code>_sequence</code> suffix to the member's name, an alias of +      the iterator type with the name created by appending the +      <code>_iterator</code> suffix to the member's name, and an alias +      of the constant iterator type with the name created by appending the +      <code>_const_iterator</code> suffix to the member's name. +   </p> + +   <p>The accessor functions come in constant and non-constant versions. +      The constant accessor function returns a constant reference to the +      container and can be used for read-only access. The non-constant +      version returns an unrestricted reference to the container and can +      be used for read-write access. +   </p> + +   <p>The modifier function expects an argument of type reference to +      constant of the container type. The modifier function +      makes a deep copy of its argument. For instance: +   </p> + + +  <pre class="xml"> +<complexType name="object"> +  <sequence> +    <element name="member" type="string" minOccurs="unbounded"/> +  </sequence> +</complexType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class object: public xml_schema::type +{ +public: +  // Type definitions. +  // +  typedef xml_schema::string member_type; +  typedef sequence<member_type> member_sequence; +  typedef member_sequence::iterator member_iterator; +  typedef member_sequence::const_iterator member_const_iterator; + +  // Accessors. +  // +  const member_sequence& +  member () const; + +  member_sequence& +  member (); + +  // Modifier. +  // +  void +  member (const member_sequence&); + +  ... + +}; +  </pre> + +  <p>The <code>sequence</code> class template is defined in an +     implementation-specific namespace. It conforms to the +     sequence interface as defined by the ISO/ANSI Standard for +     C++ (ISO/IEC 14882:1998, Section 23.1.1, "Sequences"). +     Practically, this means that you can treat such a sequence +     as if it was <code>std::vector</code>. Two notable extensions +     to the standard interface that are available only for +     sequences of non-fundamental C++ types are the addition of +     the overloaded <code>push_back</code> and <code>insert</code> +     as well as the <code>detach_back</code> and <code>detach</code> +     member functions. The additional <code>push_back</code> and +     <code>insert</code> functions accept an automatic pointer +     (<code>std::unique_ptr</code> or <code>std::auto_ptr</code>, +     depending on the C++ standard selected) to the +     element type instead of the constant reference. They assume +     ownership of the pointed to object and reset the passed +     automatic pointer. The <code>detach_back</code> and +     <code>detach</code> functions detach the element +     value from the sequence container and, by default, remove +     the element from the sequence. These additional functions +     have the following signatures:</p> + +  <pre class="c++"> +template <typename X> +class sequence +{ +public: +  ... + +  void +  push_back (std::[unique|auto]_ptr<X>) + +  iterator +  insert (iterator position, std::[unique|auto]_ptr<X>) + +  std::[unique|auto]_ptr<X> +  detach_back (bool pop = true); + +  iterator +  detach (iterator position, +          std::[unique|auto]_ptr<X>& result, +          bool erase = true) + +  ... +} +  </pre> + +  <p>The following code shows how one could use this mapping:</p> + +  <pre class="c++"> +void +f (object& o) +{ +  using xml_schema::string; + +  object::member_sequence& s (o.member ()); + +  // Iteration. +  // +  for (object::member_iterator i (s.begin ()); i != s.end (); ++i) +  { +    string& value (*i); +  } + +  // Modification. +  // +  s.push_back ("hello");  // deep copy + +  // C++11 version. +  // +  std::unique_ptr<string> p (new string ("hello")); +  s.push_back (std::move (p)); // assumes ownership +  p = s.detach_back ();        // detach and pop +  s.push_back (std::move (p)); // re-append + +  // C++98 version. +  // +  std::auto_ptr<string> p (new string ("hello")); +  s.push_back (p);        // assumes ownership +  p = s.detach_back ();   // detach and pop +  s.push_back (p);        // re-append + +  // Setting a new container. +  // +  object::member_sequence n; +  n.push_back ("one"); +  n.push_back ("two"); +  o.member (n);           // deep copy +} +  </pre> + +  <h3><a name="2.8.4">2.8.4 Element Order</a></h3> + +  <p>C++/Tree is a "flattening" mapping in a sense that many levels of +     nested compositors (<code>choice</code> and <code>sequence</code>), +     all potentially with their own cardinalities, are in the end mapped +     to a flat set of elements with one of the three cardinality classes +     discussed in the previous sections. While this results in a simple +     and easy to use API for most types, in certain cases, the order of +     elements in the actual XML documents is not preserved once parsed +     into the object model. And sometimes such order has +     application-specific significance. As an example, consider a schema +     that defines a batch of bank transactions:</p> + +  <pre class="xml"> +<complexType name="withdraw"> +  <sequence> +    <element name="account" type="unsignedInt"/> +    <element name="amount" type="unsignedInt"/> +  </sequence> +</complexType> + +<complexType name="deposit"> +  <sequence> +    <element name="account" type="unsignedInt"/> +    <element name="amount" type="unsignedInt"/> +  </sequence> +</complexType> + +<complexType name="batch"> +  <choice minOccurs="0" maxOccurs="unbounded"> +    <element name="withdraw" type="withdraw"/> +    <element name="deposit" type="deposit"/> +  </choice> +</complexType> +  </pre> + +  <p>The batch can contain any number of transactions in any order +     but the order of transactions in each actual batch is significant. +     For instance, consider what could happen if we reorder the +     transactions and apply all the withdrawals before deposits.</p> + +  <p>For the <code>batch</code> schema type defined above the default +     C++/Tree mapping will produce a C++ class that contains a pair of +     sequence containers, one for each of the two elements. While this +     will capture the content (transactions), the order of this content +     as it appears in XML will be lost. Also, if we try to serialize the +     batch we just loaded back to XML, all the withdrawal transactions +     will appear before deposits.</p> + +  <p>To overcome this limitation of a flattening mapping, C++/Tree +     allows us to mark certain XML Schema types, for which content +     order is important, as ordered.</p> + +  <p>There are several command line options that control which +     schema types are treated as ordered. To make an individual +     type ordered, we use the <code>--ordered-type</code> option, +     for example:</p> + +  <pre class="term"> +--ordered-type batch +  </pre> + +  <p>To automatically treat all the types that are derived from an ordered +     type also ordered, we use the <code>--ordered-type-derived</code> +     option. This is primarily useful if you would like to iterate +     over the complete hierarchy's content using the content order +     sequence (discussed below).</p> + +  <p>Ordered types are also useful for handling mixed content. To +     automatically mark all the types with mixed content as ordered +     we use the <code>--ordered-type-mixed</code> option. For more +     information on handling mixed content see <a href="#2.13">Section +     2.13, "Mapping for Mixed Content Models"</a>.</p> + +  <p>Finally, we can mark all the types in the schema we are +     compiling with the <code>--ordered-type-all</code> option. +     You should only resort to this option if all the types in +     your schema truly suffer from the loss of content +     order since, as we will discuss shortly, ordered types +     require extra effort to access and, especially, modify. +     See the +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD +     Compiler Command Line Manual</a> for more information on +     these options.</p> + +  <p>Once a type is marked ordered, C++/Tree alters its mapping +     in several ways. Firstly, for each local element, element +     wildcard (<a href="#2.12.4">Section 2.12.4, "Element Wildcard +     Order"</a>), and mixed content text (<a href="#2.13">Section +     2.13, "Mapping for Mixed Content Models"</a>) in this type, a +     content id constant is generated. Secondly, an addition sequence +     is added to the class that captures the content order. Here +     is how the mapping of our <code>batch</code> class changes +     once we make it ordered:</p> + +  <pre class="c++"> +class batch: public xml_schema::type +{ +public: +  // withdraw +  // +  typedef withdraw withdraw_type; +  typedef sequence<withdraw_type> withdraw_sequence; +  typedef withdraw_sequence::iterator withdraw_iterator; +  typedef withdraw_sequence::const_iterator withdraw_const_iterator; + +  static const std::size_t withdraw_id = 1; + +  const withdraw_sequence& +  withdraw () const; + +  withdraw_sequence& +  withdraw (); + +  void +  withdraw (const withdraw_sequence&); + +  // deposit +  // +  typedef deposit deposit_type; +  typedef sequence<deposit_type> deposit_sequence; +  typedef deposit_sequence::iterator deposit_iterator; +  typedef deposit_sequence::const_iterator deposit_const_iterator; + +  static const std::size_t deposit_id = 2; + +  const deposit_sequence& +  deposit () const; + +  deposit_sequence& +  deposit (); + +  void +  deposit (const deposit_sequence&); + +  // content_order +  // +  typedef xml_schema::content_order content_order_type; +  typedef std::vector<content_order_type> content_order_sequence; +  typedef content_order_sequence::iterator content_order_iterator; +  typedef content_order_sequence::const_iterator content_order_const_iterator; + +  const content_order_sequence& +  content_order () const; + +  content_order_sequence& +  content_order (); + +  void +  content_order (const content_order_sequence&); + +  ... +}; +  </pre> + +  <p>Notice the <code>withdraw_id</code> and <code>deposit_id</code> +     content ids as well as the extra <code>content_order</code> +     sequence that does not correspond to any element in the +     schema definition. The other changes to the mapping for ordered +     types has to do with XML parsing and serialization code. During +     parsing the content order is captured in the <code>content_order</code> +     sequence while during serialization this sequence is used to +     determine the order in which content is serialized. The +     <code>content_order</code> sequence is also copied during +     copy construction and assigned during copy assignment. It is also +     taken into account during comparison.</p> + +  <p>The entry type of the <code>content_order</code> sequence is the +     <code>xml_schema::content_order</code> type that has the following +     interface:</p> + +  <pre class="c++"> +namespace xml_schema +{ +  struct content_order +  { +    content_order (std::size_t id, std::size_t index = 0); + +    std::size_t id; +    std::size_t index; +  }; + +  bool +  operator== (const content_order&, const content_order&); + +  bool +  operator!= (const content_order&, const content_order&); + +  bool +  operator< (const content_order&, const content_order&); +} +  </pre> + +  <p>The <code>content_order</code> sequence describes the order of +     content (elements, including wildcards, as well as mixed content +     text). Each entry in this sequence consists of the content id +     (for example, <code>withdraw_id</code> or <code>deposit_id</code> +     in our case) as well as, for elements of the sequence cardinality +     class, an index into the corresponding sequence container (the +     index is unused for the one and optional cardinality classes). +     For example, in our case, if the content id is <code>withdraw_id</code>, +     then the index will point into the <code>withdraw</code> element +     sequence.</p> + +  <p>With all this information we can now examine how to iterate over +     transaction in the batch in content order:</p> + +  <pre class="c++"> +batch& b = ... + +for (batch::content_order_const_iterator i (b.content_order ().begin ()); +     i != b.content_order ().end (); +     ++i) +{ +  switch (i->id) +  { +  case batch::withdraw_id: +    { +      const withdraw& t (b.withdraw ()[i->index]); +      cerr << t.account () << " withdraw " << t.amount () << endl; +      break; +    } +  case batch::deposit_id: +    { +      const deposit& t (b.deposit ()[i->index]); +      cerr << t.account () << " deposit " << t.amount () << endl; +      break; +    } +  default: +    { +      assert (false); // Unknown content id. +    } +  } +} +  </pre> + +  <p>If we serialized our batch back to XML, we would also see that the +     order of transactions in the output is exactly the same as in the +     input rather than all the withdrawals first followed by all the +     deposits.</p> + +  <p>The most complex aspect of working with ordered types is +     modifications. Now we not only need to change the content, +     but also remember to update the order information corresponding +     to this change. As a first example, we add a deposit transaction +     to the batch:</p> + +  <pre class="c++"> +using xml_schema::content_order; + +batch::deposit_sequence& d (b.deposit ()); +batch::withdraw_sequence& w (b.withdraw ()); +batch::content_order_sequence& co (b.content_order ()); + +d.push_back (deposit (123456789, 100000)); +co.push_back (content_order (batch::deposit_id, d.size () - 1)); +  </pre> + +  <p>In the above example we first added the content (deposit +     transaction) and then updated the content order information +     by adding an entry with <code>deposit_id</code> content +     id and the index of the just added deposit transaction.</p> + +  <p>Removing the last transaction can be easy if we know which +     transaction (deposit or withdrawal) is last:</p> + +  <pre class="c++"> +d.pop_back (); +co.pop_back (); +  </pre> + +  <p>If, however, we do not know which transaction is last, then +     things get a bit more complicated:</p> + +  <pre class="c++"> +switch (co.back ().id) +{ +case batch::withdraw_id: +  { +    d.pop_back (); +    break; +  } +case batch::deposit_id: +  { +    w.pop_back (); +    break; +  } +} + +co.pop_back (); +  </pre> + +  <p>The following example shows how to add a transaction at the +     beginning of the batch:</p> + +  <pre class="c++"> +w.push_back (withdraw (123456789, 100000)); +co.insert (co.begin (), +           content_order (batch::withdraw_id, w.size () - 1)); +  </pre> + +  <p>Note also that when we merely modify the content of one +     of the elements in place, we do not need to update its +     order since it doesn't change. For example, here is how +     we can change the amount in the first withdrawal:</p> + +  <pre class="c++"> +w[0].amount (10000); +  </pre> + +  <p>For the complete working code shown in this section refer to the +     <code>order/element</code> example in the +     <code>cxx/tree/</code> directory in the +     <a href="https://cppget.org/xsd-examples">xsd-examples</a> +     package.</p> + +  <p>If both the base and derived types are ordered, then the +     content order sequence is only added to the base and the content +     ids are unique within the whole hierarchy. In this case +     the content order sequence for the derived type contains +     ordering information for both base and derived content.</p> + +  <p>In some applications we may need to perform more complex +     content processing. For example, in our case, we may need +     to remove all the withdrawal transactions. The default +     container, <code>std::vector</code>, is not particularly +     suitable for such operations. What may be required by +     some applications is a multi-index container that not +     only allows us to iterate in content order similar to +     <code>std::vector</code> but also search by the content +     id as well as the content id and index pair.</p> + +  <p>While C++/Tree does not provide this functionality by +     default, it allows us to specify a custom container +     type for content order with the <code>--order-container</code> +     command line option. The only requirement from the +     generated code side for such a container is to provide +     the <code>vector</code>-like <code>push_back()</code>, +     <code>size()</code>, and const iteration interfaces.</p> + +  <p>As an example, here is how we can use the Boost Multi-Index +     container for content order. First we create the +     <code>content-order-container.hxx</code> header with the +     following definition:</p> + +  <pre class="c++"> +#ifndef CONTENT_ORDER_CONTAINER +#define CONTENT_ORDER_CONTAINER + +#include <cstddef> // std::size_t + +#include <boost/multi_index_container.hpp> +#include <boost/multi_index/member.hpp> +#include <boost/multi_index/identity.hpp> +#include <boost/multi_index/ordered_index.hpp> +#include <boost/multi_index/random_access_index.hpp> + +struct by_id {}; +struct by_id_index {}; + +template <typename T> +using content_order_container = +  boost::multi_index::multi_index_container< +    T, +    boost::multi_index::indexed_by< +      boost::multi_index::random_access<>, +      boost::multi_index::ordered_unique< +        boost::multi_index::tag<by_id_index>, +        boost::multi_index::identity<T> +      >, +      boost::multi_index::ordered_non_unique< +        boost::multi_index::tag<by_id>, +        boost::multi_index::member<T, std::size_t, &T::id> +      > +    > +  >; + +#endif +  </pre> + +  <p>Next we add the following two XSD compiler options to include +     this header into every generated header file and to use the +     custom container type (see the XSD compiler command line manual +     for more information on shell quoting for the first option):</p> + +  <pre class="term"> +--hxx-prologue '#include "content-order-container.hxx"' +--order-container content_order_container +  </pre> + +  <p>With these changes we can now use the multi-index functionality, +     for example, to search for a specific content id:</p> + +  <pre class="c++"> +typedef batch::content_order_sequence::index<by_id>::type id_set; +typedef id_set::iterator id_iterator; + +const id_set& ids (b.content_order ().get<by_id> ()); + +std::pair<id_iterator, id_iterator> r ( +  ids.equal_range (std::size_t (batch::deposit_id)); + +for (id_iterator i (r.first); i != r.second; ++i) +{ +  const deposit& t (b.deposit ()[i->index]); +  cerr << t.account () << " deposit " << t.amount () << endl; +} +  </pre> + +  <h2><a name="2.9">2.9 Mapping for Global Elements</a></h2> + +  <p>An XML Schema element definition is called global if it appears +     directly under the <code>schema</code> element. +     A global element is a valid root of an instance document. By +     default, a global element is mapped to a set of overloaded +     parsing and, optionally, serialization functions with the +     same name as the element. It is also possible to generate types +     for root elements instead of parsing and serialization functions. +     This is primarily useful to distinguish object models with the +     same root type but with different root elements. See +     <a href="#2.9.1">Section 2.9.1, "Element Types"</a> for details. +     It is also possible to request the generation of an element map +     which allows uniform parsing and serialization of multiple root +     elements. See <a href="#2.9.2">Section 2.9.2, "Element Map"</a> +     for details. +  </p> + +  <p>The parsing functions read XML instance documents and return +     corresponding object models as an automatic pointer +     (<code>std::unique_ptr</code> or <code>std::auto_ptr</code>, +     depending on the C++ standard selected). Their signatures +     have the following pattern (<code>type</code> denotes +     element's type and <code>name</code> denotes element's +     name): +  </p> + +  <pre class="c++"> +std::[unique|auto]_ptr<type> +name (....); +  </pre> + +  <p>The process of parsing, including the exact signatures of the parsing +     functions, is the subject of <a href="#3">Chapter 3, "Parsing"</a>. +  </p> + +  <p>The serialization functions write object models back to XML instance +     documents. Their signatures have the following pattern: +  </p> + +  <pre class="c++"> +void +name (<stream type>&, const type&, ....); +  </pre> + +  <p>The process of serialization, including the exact signatures of the +     serialization functions, is the subject of <a href="#4">Chapter 4, +     "Serialization"</a>. +  </p> + + +  <h3><a name="2.9.1">2.9.1 Element Types</a></h3> + +  <p>The generation of element types is requested with the +     <code>--generate-element-type</code> option. With this option +     each global element is mapped to a C++ class with the +     same name as the element. Such a class is derived from +     <code>xml_schema::element_type</code> and contains the same set +     of type definitions, constructors, and member function as would a +     type containing a single element with the One cardinality class +     named <code>"value"</code>. In addition, the element type also +     contains a set of member functions for accessing the element +     name and namespace as well as its value in a uniform manner. +     For example:</p> + +  <pre class="xml"> +<complexType name="type"> +  <sequence> +    ... +  </sequence> +</complexType> + +<element name="root" type="type"/> +  </pre> + +<p>is mapped to:</p> + +  <pre class="c++"> +class type +{ +  ... +}; + +class root: public xml_schema::element_type +{ +public: +  // Element value. +  // +  typedef type value_type; + +  const value_type& +  value () const; + +  value_type& +  value (); + +  void +  value (const value_type&); + +  void +  value (std::[unique|auto]_ptr<value_type>); + +  // Constructors. +  // +  root (const value_type&); + +  root (std::[unique|auto]_ptr<value_type>); + +  root (const xercesc::DOMElement&, xml_schema::flags = 0); + +  root (const root&, xml_schema::flags = 0); + +  virtual root* +  _clone (xml_schema::flags = 0) const; + +  // Element name and namespace. +  // +  static const std::string& +  name (); + +  static const std::string& +  namespace_ (); + +  virtual const std::string& +  _name () const; + +  virtual const std::string& +  _namespace () const; + +  // Element value as xml_schema::type. +  // +  virtual const xml_schema::type* +  _value () const; + +  virtual xml_schema::type* +  _value (); +}; + +void +operator<< (xercesc::DOMElement&, const root&); +  </pre> + +  <p>The <code>xml_schema::element_type</code> class is a common +     base type for all element types and is defined as follows:</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class element_type +  { +  public: +    virtual +    ~element_type (); + +    virtual element_type* +    _clone (flags f = 0) const = 0; + +    virtual const std::basic_string<C>& +    _name () const = 0; + +    virtual const std::basic_string<C>& +    _namespace () const = 0; + +    virtual xml_schema::type* +    _value () = 0; + +    virtual const xml_schema::type* +    _value () const = 0; +  }; +} +  </pre> + +  <p>The <code>_value()</code> member function returns a pointer to +     the element value or 0 if the element is of a fundamental C++ +     type and therefore is not derived from <code>xml_schema::type</code>. +  </p> + +  <p>Unlike parsing and serialization functions, element types +     are only capable of parsing and serializing from/to a +     <code>DOMElement</code> object. This means that the application +     will need to perform its own XML-to-DOM parsing and DOM-to-XML +     serialization. The following section describes a mechanism +     provided by the mapping to uniformly parse and serialize +     multiple root elements.</p> + + +  <h3><a name="2.9.2">2.9.2 Element Map</a></h3> + +  <p>When element types are generated for root elements it is also +     possible to request the generation of an element map with the +     <code>--generate-element-map</code> option. The element map +     allows uniform parsing and serialization of multiple root +     elements via the common <code>xml_schema::element_type</code> +     base type. The <code>xml_schema::element_map</code> class is +     defined as follows:</p> + +  <pre class="c++"> +namespace xml_schema +{ +  class element_map +  { +  public: +    static std::[unique|auto]_ptr<xml_schema::element_type> +    parse (const xercesc::DOMElement&, flags = 0); + +    static void +    serialize (xercesc::DOMElement&, const element_type&); +  }; +} +  </pre> + +  <p>The <code>parse()</code> function creates the corresponding +     element type object based on the element name and namespace +     and returns it as an automatic pointer (<code>std::unique_ptr</code> +     or <code>std::auto_ptr</code>, depending on the C++ standard +     selected) to <code>xml_schema::element_type</code>. +     The <code>serialize()</code> function serializes the passed element +     object to <code>DOMElement</code>. Note that in case of +     <code>serialize()</code>, the <code>DOMElement</code> object +     should have the correct name and namespace. If no element type is +     available for an element, both functions throw the +     <code>xml_schema::no_element_info</code> exception:</p> + +  <pre class="c++"> +struct no_element_info: virtual exception +{ +  no_element_info (const std::basic_string<C>& element_name, +                   const std::basic_string<C>& element_namespace); + +  const std::basic_string<C>& +  element_name () const; + +  const std::basic_string<C>& +  element_namespace () const; + +  virtual const char* +  what () const throw (); +}; +  </pre> + +  <p>The application can discover the actual type of the element +     object returned by <code>parse()</code> either using +     <code>dynamic_cast</code> or by comparing element names and +     namespaces. The following code fragments illustrate how the +     element map can be used:</p> + +  <pre class="c++"> +// Parsing. +// +DOMElement& e = ... // Parse XML to DOM. + +unique_ptr<xml_schema::element_type> r ( +  xml_schema::element_map::parse (e)); + +if (root1 r1 = dynamic_cast<root1*> (r.get ())) +{ +  ... +} +else if (r->_name == root2::name () && +         r->_namespace () == root2::namespace_ ()) +{ +  root2& r2 (static_cast<root2&> (*r)); + +  ... +} +  </pre> + +  <pre class="c++"> +// Serialization. +// +xml_schema::element_type& r = ... + +string name (r._name ()); +string ns (r._namespace ()); + +DOMDocument& doc = ... // Create a new DOMDocument with name and ns. +DOMElement& e (*doc->getDocumentElement ()); + +xml_schema::element_map::serialize (e, r); + +// Serialize DOMDocument to XML. +  </pre> + +  <!-- --> + +  <h2><a name="2.10">2.10 Mapping for Global Attributes</a></h2> + +  <p>An XML Schema attribute definition is called global if it appears +     directly under the <code>schema</code> element. A global +     attribute does not have any mapping. +  </p> + +  <!-- +     When it is referenced from +     a local attribute definition (using the <code>ref</code> attribute) +     it is treated as a local attribute (see Section 2.8, "Mapping for +     Local Elements and Attributes"). +  --> + +  <h2><a name="2.11">2.11 Mapping for <code>xsi:type</code> and Substitution +      Groups</a></h2> + +  <p>The mapping provides optional support for the XML Schema polymorphism +     features (<code>xsi:type</code> and substitution groups) which can +     be requested with the <code>--generate-polymorphic</code> option. +     When used, the dynamic type of a member may be different from +     its static type. Consider the following schema definition and +     instance document: +  </p> + +  <pre class="xml"> +<!-- test.xsd --> +<schema> +  <complexType name="base"> +    <attribute name="text" type="string"/> +  </complexType> + +  <complexType name="derived"> +    <complexContent> +      <extension base="base"> +        <attribute name="extra-text" type="string"/> +      </extension> +    </complexContent> +  </complexType> + +  <complexType name="root_type"> +    <sequence> +      <element name="item" type="base" maxOccurs="unbounded"/> +    </sequence> +  </complexType> + +  <element name="root" type="root_type"/> +</schema> + +<!-- test.xml --> +<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> +  <item text="hello"/> +  <item text="hello" extra-text="world" xsi:type="derived"/> +</root> +  </pre> + +  <p>In the resulting object model, the container for +     the <code>root::item</code> member will have two elements: +     the first element's type will be <code>base</code> while +     the second element's (dynamic) type will be +     <code>derived</code>. This can be discovered using the +     <code>dynamic_cast</code> operator as shown in the following +     example: +  </p> + +  <pre class="c++"> +void +f (root& r) +{ +  for (root::item_const_iterator i (r.item ().begin ()); +       i != r.item ().end () +       ++i) +  { +    if (derived* d = dynamic_cast<derived*> (&(*i))) +    { +      // derived +    } +    else +    { +      // base +    } +  } +} +  </pre> + +  <p>The <code>_clone</code> virtual function should be used instead of +     copy constructors to make copies of members that might use +     polymorphism: +  </p> + +  <pre class="c++"> +void +f (root& r) +{ +  for (root::item_const_iterator i (r.item ().begin ()); +       i != r.item ().end () +       ++i) +  { +    std::unique_ptr<base> c (i->_clone ()); +  } +} +  </pre> + +  <p>The mapping can often automatically determine which types are +     polymorphic based on the substitution group declarations. However, +     if your XML vocabulary is not using substitution groups or if +     substitution groups are defined in a separate schema, then you will +     need to use the <code>--polymorphic-type</code> option to specify +     which types are polymorphic. When using this option you only need +     to specify the root of a polymorphic type hierarchy and the mapping +     will assume that all the derived types are also polymorphic. +     Also note that you need to specify this option when compiling every +     schema file that references the polymorphic type. Consider the following +     two schemas as an example:</p> + +  <pre class="xml"> +<!-- base.xsd --> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + +  <xs:complexType name="base"> +    <xs:sequence> +      <xs:element name="b" type="xs:int"/> +    </xs:sequence> +  </xs:complexType> + +  <!-- substitution group root --> +  <xs:element name="base" type="base"/> + +</xs:schema> +  </pre> + +  <pre class="xml"> +<!-- derived.xsd --> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + +  <include schemaLocation="base.xsd"/> + +  <xs:complexType name="derived"> +    <xs:complexContent> +      <xs:extension base="base"> +        <xs:sequence> +          <xs:element name="d" type="xs:string"/> +        </xs:sequence> +      </xs:extension> +    </xs:complexContent> +  </xs:complexType> + +  <xs:element name="derived" type="derived" substitutionGroup="base"/> + +</xs:schema> +  </pre> + +  <p>In this example we need to specify "<code>--polymorphic-type base</code>" +     when compiling both schemas because the substitution group is declared +     in a schema other than the one defining type <code>base</code>.</p> + +  <p>You can also indicate that all types should be treated as polymorphic +     with the <code>--polymorphic-type-all</code>. However, this may result +     in slower generated code with a greater footprint.</p> + + +  <!-- Mapping for any and anyAttribute --> + + +  <h2><a name="2.12">2.12 Mapping for <code>any</code> and <code>anyAttribute</code></a></h2> + +  <p>For the XML Schema <code>any</code> and <code>anyAttribute</code> +     wildcards an optional mapping can be requested with the +     <code>--generate-wildcard</code> option. The mapping represents +     the content matched by wildcards as DOM fragments. Because the +     DOM API is used to access such content, the Xerces-C++ runtime +     should be initialized by the application prior to parsing and +     should remain initialized for the lifetime of objects with +     the wildcard content. For more information on the Xerces-C++ +     runtime initialization see <a href="#3.1">Section 3.1, +     "Initializing the Xerces-C++ Runtime"</a>. +  </p> + +  <p>The mapping for <code>any</code> is similar to the mapping for +     local elements (see <a href="#2.8">Section 2.8, "Mapping for Local +     Elements and Attributes"</a>) except that the type used in the +     wildcard mapping is <code>xercesc::DOMElement</code>. As with local +     elements, the mapping divides all possible cardinality combinations +     into three cardinality classes: <i>one</i>, <i>optional</i>, and +     <i>sequence</i>. +  </p> + +  <p>The mapping for <code>anyAttribute</code> represents the attributes +     matched by this wildcard as a set of <code>xercesc::DOMAttr</code> +     objects with a key being the attribute's name and namespace.</p> + +  <p>Similar to local elements and attributes, the <code>any</code> and +     <code>anyAttribute</code> wildcards are mapped to a set of public type +     definitions (typedefs) and a set of public accessor and modifier +     functions. Type definitions have names derived from <code>"any"</code> +     for the <code>any</code> wildcard and <code>"any_attribute"</code> +     for the <code>anyAttribute</code> wildcard. The accessor and modifier +     functions are named <code>"any"</code> for the <code>any</code> wildcard +     and <code>"any_attribute"</code> for the <code>anyAttribute</code> +     wildcard. Subsequent wildcards in the same type have escaped names +     such as <code>"any1"</code> or <code>"any_attribute1"</code>. +  </p> + +  <p>Because Xerces-C++ DOM nodes always belong to a <code>DOMDocument</code>, +     each type with a wildcard has an associated <code>DOMDocument</code> +     object. The reference to this object can be obtained using the accessor +     function called <code>dom_document</code>. The access to the document +     object from the application code may be necessary to create or modify +     the wildcard content. For example: +  </p> + +  <pre class="xml"> +<complexType name="object"> +  <sequence> +    <any namespace="##other"/> +  </sequence> +  <anyAttribute namespace="##other"/> +</complexType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class object: public xml_schema::type +{ +public: +  // any +  // +  const xercesc::DOMElement& +  any () const; + +  void +  any (const xercesc::DOMElement&); + +  ... + +  // any_attribute +  // +  typedef attribute_set any_attribute_set; +  typedef any_attribute_set::iterator any_attribute_iterator; +  typedef any_attribute_set::const_iterator any_attribute_const_iterator; + +  const any_attribute_set& +  any_attribute () const; + +  any_attribute_set& +  any_attribute (); + +  ... + +  // DOMDocument object for wildcard content. +  // +  const xercesc::DOMDocument& +  dom_document () const; + +  xercesc::DOMDocument& +  dom_document (); + +  ... +}; +  </pre> + + +  <p>Names and semantics of type definitions for the wildcards as well +     as signatures of the accessor and modifier functions depend on the +     wildcard type as well as the cardinality class for the <code>any</code> +     wildcard. They are described in the following sub-sections. +  </p> + + +  <h3><a name="2.12.1">2.12.1 Mapping for <code>any</code> with the One Cardinality Class</a></h3> + +  <p>For <code>any</code> with the One cardinality class, +     there are no type definitions. The accessor functions come in +     constant and non-constant versions. The constant accessor function +     returns a constant reference to <code>xercesc::DOMElement</code> and +     can be used for read-only access. The non-constant version returns +     an unrestricted reference to <code>xercesc::DOMElement</code> and can +     be used for read-write access. +  </p> + +  <p>The first modifier function expects an argument of type reference +     to constant <code>xercesc::DOMElement</code> and makes a deep copy +     of its argument. The second modifier function expects an argument of +     type pointer to <code>xercesc::DOMElement</code>. This modifier +     function assumes ownership of its argument and expects the element +     object to be created using the DOM document associated with this +     instance. For example: +  </p> + +  <pre class="xml"> +<complexType name="object"> +  <sequence> +    <any namespace="##other"/> +  </sequence> +</complexType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class object: public xml_schema::type +{ +public: +  // Accessors. +  // +  const xercesc::DOMElement& +  any () const; + +  xercesc::DOMElement& +  any (); + +  // Modifiers. +  // +  void +  any (const xercesc::DOMElement&); + +  void +  any (xercesc::DOMElement*); + +  ... + +}; +  </pre> + + +  <p>The following code shows how one could use this mapping:</p> + +  <pre class="c++"> +void +f (object& o, const xercesc::DOMElement& e) +{ +  using namespace xercesc; + +  DOMElement& e1 (o.any ());             // get +  o.any (e)                              // set, deep copy +  DOMDocument& doc (o.dom_document ()); +  o.any (doc.createElement (...));       // set, assumes ownership +} +  </pre> + +  <h3><a name="2.12.2">2.12.2 Mapping for <code>any</code> with the Optional Cardinality Class</a></h3> + +  <p>For <code>any</code> with the Optional cardinality class, the type +     definitions consist of an alias for the container type with name +     <code>any_optional</code> (or <code>any1_optional</code>, etc., for +     subsequent wildcards in the type definition). +  </p> + +  <p>Unlike accessor functions for the One cardinality class, accessor +     functions for the Optional cardinality class return references to +     corresponding containers rather than directly to <code>DOMElement</code>. +     The accessor functions come in constant and non-constant versions. +     The constant accessor function returns a constant reference to +     the container and can be used for read-only access. The non-constant +     version returns an unrestricted reference to the container +     and can be used for read-write access. +  </p> + +  <p>The modifier functions are overloaded for <code>xercesc::DOMElement</code> +     and the container type. The first modifier function expects an argument of +     type reference to constant <code>xercesc::DOMElement</code> and +     makes a deep copy of its argument. The second modifier function +     expects an argument of type pointer to <code>xercesc::DOMElement</code>. +     This modifier function assumes ownership of its argument and expects +     the element object to be created using the DOM document associated +     with this instance. The third modifier function expects an argument +     of type reference to constant of the container type and makes a +     deep copy of its argument. For instance: +  </p> + +  <pre class="xml"> +<complexType name="object"> +  <sequence> +    <any namespace="##other" minOccurs="0"/> +  </sequence> +</complexType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class object: public xml_schema::type +{ +public: +  // Type definitions. +  // +  typedef element_optional any_optional; + +  // Accessors. +  // +  const any_optional& +  any () const; + +  any_optional& +  any (); + +  // Modifiers. +  // +  void +  any (const xercesc::DOMElement&); + +  void +  any (xercesc::DOMElement*); + +  void +  any (const any_optional&); + +  ... + +}; +  </pre> + + +  <p>The <code>element_optional</code> container is a +     specialization of the <code>optional</code> class template described +     in <a href="#2.8.2">Section 2.8.2, "Mapping for Members with the Optional +     Cardinality Class"</a>. Its interface is presented below: +  </p> + +  <pre class="c++"> +class element_optional +{ +public: +  explicit +  element_optional (xercesc::DOMDocument&); + +  // Makes a deep copy. +  // +  element_optional (const xercesc::DOMElement&, xercesc::DOMDocument&); + +  // Assumes ownership. +  // +  element_optional (xercesc::DOMElement*, xercesc::DOMDocument&); + +  element_optional (const element_optional&, xercesc::DOMDocument&); + +public: +  element_optional& +  operator= (const xercesc::DOMElement&); + +  element_optional& +  operator= (const element_optional&); + +  // Pointer-like interface. +  // +public: +  const xercesc::DOMElement* +  operator-> () const; + +  xercesc::DOMElement* +  operator-> (); + +  const xercesc::DOMElement& +  operator* () const; + +  xercesc::DOMElement& +  operator* (); + +  typedef void (element_optional::*bool_convertible) (); +  operator bool_convertible () const; + +  // Get/set interface. +  // +public: +  bool +  present () const; + +  const xercesc::DOMElement& +  get () const; + +  xercesc::DOMElement& +  get (); + +  // Makes a deep copy. +  // +  void +  set (const xercesc::DOMElement&); + +  // Assumes ownership. +  // +  void +  set (xercesc::DOMElement*); + +  void +  reset (); +}; + +bool +operator== (const element_optional&, const element_optional&); + +bool +operator!= (const element_optional&, const element_optional&); +  </pre> + + +  <p>The following code shows how one could use this mapping:</p> + +  <pre class="c++"> +void +f (object& o, const xercesc::DOMElement& e) +{ +  using namespace xercesc; + +  DOMDocument& doc (o.dom_document ()); + +  if (o.any ().present ())                  // test +  { +    DOMElement& e1 (o.any ().get ());       // get +    o.any ().set (e);                       // set, deep copy +    o.any ().set (doc.createElement (...)); // set, assumes ownership +    o.any ().reset ();                      // reset +  } + +  // Same as above but using pointer notation: +  // +  if (o.member ())                          // test +  { +    DOMElement& e1 (*o.any ());             // get +    o.any (e);                              // set, deep copy +    o.any (doc.createElement (...));        // set, assumes ownership +    o.any ().reset ();                      // reset +  } +} +  </pre> + + + +  <h3><a name="2.12.3">2.12.3 Mapping for <code>any</code> with the Sequence Cardinality Class</a></h3> + +  <p>For <code>any</code> with the Sequence cardinality class, the type +     definitions consist of an alias of the container type with name +     <code>any_sequence</code> (or <code>any1_sequence</code>, etc., for +     subsequent wildcards in the type definition), an alias of the iterator +     type with name <code>any_iterator</code> (or <code>any1_iterator</code>, +     etc., for subsequent wildcards in the type definition), and an alias +     of the constant iterator type with name <code>any_const_iterator</code> +     (or <code>any1_const_iterator</code>, etc., for subsequent wildcards +     in the type definition). +  </p> + +  <p>The accessor functions come in constant and non-constant versions. +     The constant accessor function returns a constant reference to the +     container and can be used for read-only access. The non-constant +     version returns an unrestricted reference to the container and can +     be used for read-write access. +  </p> + +  <p>The modifier function expects an argument of type reference to +     constant of the container type. The modifier function makes +     a deep copy of its argument. For instance: +  </p> + + +  <pre class="xml"> +<complexType name="object"> +  <sequence> +    <any namespace="##other" minOccurs="unbounded"/> +  </sequence> +</complexType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class object: public xml_schema::type +{ +public: +  // Type definitions. +  // +  typedef element_sequence any_sequence; +  typedef any_sequence::iterator any_iterator; +  typedef any_sequence::const_iterator any_const_iterator; + +  // Accessors. +  // +  const any_sequence& +  any () const; + +  any_sequence& +  any (); + +  // Modifier. +  // +  void +  any (const any_sequence&); + +  ... + +}; +  </pre> + +  <p>The <code>element_sequence</code> container is a +     specialization of the <code>sequence</code> class template described +     in <a href="#2.8.3">Section 2.8.3, "Mapping for Members with the +     Sequence Cardinality Class"</a>. Its interface is similar to +     the sequence interface as defined by the ISO/ANSI Standard for +     C++ (ISO/IEC 14882:1998, Section 23.1.1, "Sequences") and is +     presented below: +  </p> + +  <pre class="c++"> +class element_sequence +{ +public: +  typedef xercesc::DOMElement        value_type; +  typedef xercesc::DOMElement*       pointer; +  typedef const xercesc::DOMElement* const_pointer; +  typedef xercesc::DOMElement&       reference; +  typedef const xercesc::DOMElement& const_reference; + +  typedef <implementation-defined>   iterator; +  typedef <implementation-defined>   const_iterator; +  typedef <implementation-defined>   reverse_iterator; +  typedef <implementation-defined>   const_reverse_iterator; + +  typedef <implementation-defined>   size_type; +  typedef <implementation-defined>   difference_type; +  typedef <implementation-defined>   allocator_type; + +public: +  explicit +  element_sequence (xercesc::DOMDocument&); + +  // DOMElement cannot be default-constructed. +  // +  // explicit +  // element_sequence (size_type n); + +  element_sequence (size_type n, +                    const xercesc::DOMElement&, +                    xercesc::DOMDocument&); + +  template <typename I> +  element_sequence (const I& begin, +                    const I& end, +                    xercesc::DOMDocument&); + +  element_sequence (const element_sequence&, xercesc::DOMDocument&); + +  element_sequence& +  operator= (const element_sequence&); + +public: +  void +  assign (size_type n, const xercesc::DOMElement&); + +  template <typename I> +  void +  assign (const I& begin, const I& end); + +public: +  // This version of resize can only be used to shrink the +  // sequence because DOMElement cannot be default-constructed. +  // +  void +  resize (size_type); + +  void +  resize (size_type, const xercesc::DOMElement&); + +public: +  size_type +  size () const; + +  size_type +  max_size () const; + +  size_type +  capacity () const; + +  bool +  empty () const; + +  void +  reserve (size_type); + +  void +  clear (); + +public: +  const_iterator +  begin () const; + +  const_iterator +  end () const; + +  iterator +  begin (); + +  iterator +  end (); + +  const_reverse_iterator +  rbegin () const; + +  const_reverse_iterator +  rend () const + +    reverse_iterator +  rbegin (); + +  reverse_iterator +  rend (); + +public: +  xercesc::DOMElement& +  operator[] (size_type); + +  const xercesc::DOMElement& +  operator[] (size_type) const; + +  xercesc::DOMElement& +  at (size_type); + +  const xercesc::DOMElement& +  at (size_type) const; + +  xercesc::DOMElement& +  front (); + +  const xercesc::DOMElement& +  front () const; + +  xercesc::DOMElement& +  back (); + +  const xercesc::DOMElement& +  back () const; + +public: +  // Makes a deep copy. +  // +  void +  push_back (const xercesc::DOMElement&); + +  // Assumes ownership. +  // +  void +  push_back (xercesc::DOMElement*); + +  void +  pop_back (); + +  // Makes a deep copy. +  // +  iterator +  insert (iterator position, const xercesc::DOMElement&); + +  // Assumes ownership. +  // +  iterator +  insert (iterator position, xercesc::DOMElement*); + +  void +  insert (iterator position, size_type n, const xercesc::DOMElement&); + +  template <typename I> +  void +  insert (iterator position, const I& begin, const I& end); + +  iterator +  erase (iterator position); + +  iterator +  erase (iterator begin, iterator end); + +public: +  // Note that the DOMDocument object of the two sequences being +  // swapped should be the same. +  // +  void +  swap (sequence& x); +}; + +inline bool +operator== (const element_sequence&, const element_sequence&); + +inline bool +operator!= (const element_sequence&, const element_sequence&); +  </pre> + + +  <p>The following code shows how one could use this mapping:</p> + +  <pre class="c++"> +void +f (object& o, const xercesc::DOMElement& e) +{ +  using namespace xercesc; + +  object::any_sequence& s (o.any ()); + +  // Iteration. +  // +  for (object::any_iterator i (s.begin ()); i != s.end (); ++i) +  { +    DOMElement& e (*i); +  } + +  // Modification. +  // +  s.push_back (e);                       // deep copy +  DOMDocument& doc (o.dom_document ()); +  s.push_back (doc.createElement (...)); // assumes ownership +} +  </pre> + +  <h3><a name="2.12.4">2.12.4 Element Wildcard Order</a></h3> + +  <p>Similar to elements, element wildcards in ordered types +     (<a href="#2.8.4">Section 2.8.4, "Element Order"</a>) are assigned +     content ids and are included in the content order sequence. +     Continuing with the bank transactions example started in Section +     2.8.4, we can extend the batch by allowing custom transactions:</p> + +  <pre class="xml"> +<complexType name="batch"> +  <choice minOccurs="0" maxOccurs="unbounded"> +    <element name="withdraw" type="withdraw"/> +    <element name="deposit" type="deposit"/> +    <any namespace="##other" processContents="lax"/> +  </choice> +</complexType> +  </pre> + +  <p>This will lead to the following changes in the generated +     <code>batch</code> C++ class:</p> + +  <pre class="c++"> +class batch: public xml_schema::type +{ +public: +  ... + +  // any +  // +  typedef element_sequence any_sequence; +  typedef any_sequence::iterator any_iterator; +  typedef any_sequence::const_iterator any_const_iterator; + +  static const std::size_t any_id = 3UL; + +  const any_sequence& +  any () const; + +  any_sequence& +  any (); + +  void +  any (const any_sequence&); + +  ... +}; +  </pre> + +  <p>With this change we also need to update the iteration code to handle +     the new content id:</p> + +  <pre class="c++"> +for (batch::content_order_const_iterator i (b.content_order ().begin ()); +     i != b.content_order ().end (); +     ++i) +{ +  switch (i->id) +  { +    ... + +  case batch::any_id: +    { +      const DOMElement& e (b.any ()[i->index]); +      ... +      break; +    } + +    ... +  } +} +  </pre> + +  <p>For the complete working code that shows the use of wildcards in +     ordered types refer to the <code>order/element</code> example in +     the <code>cxx/tree/</code> directory in the +     <a href="https://cppget.org/xsd-examples">xsd-examples</a> +     package.</p> + +  <h3><a name="2.12.5">2.12.5 Mapping for <code>anyAttribute</code></a></h3> + +  <p>For <code>anyAttribute</code> the type definitions consist of an alias +     of the container type with name <code>any_attribute_set</code> +     (or <code>any1_attribute_set</code>, etc., for subsequent wildcards +     in the type definition), an alias of the iterator type with name +     <code>any_attribute_iterator</code> (or <code>any1_attribute_iterator</code>, +     etc., for subsequent wildcards in the type definition), and an alias +     of the constant iterator type with name <code>any_attribute_const_iterator</code> +     (or <code>any1_attribute_const_iterator</code>, etc., for subsequent +     wildcards in the type definition). +  </p> + +  <p>The accessor functions come in constant and non-constant versions. +     The constant accessor function returns a constant reference to the +     container and can be used for read-only access. The non-constant +     version returns an unrestricted reference to the container and can +     be used for read-write access. +  </p> + +  <p>The modifier function expects an argument of type reference to +     constant of the container type. The modifier function makes +     a deep copy of its argument. For instance: +  </p> + + +  <pre class="xml"> +<complexType name="object"> +  <sequence> +    ... +  </sequence> +  <anyAttribute namespace="##other"/> +</complexType> +  </pre> + +  <p>is mapped to:</p> + +  <pre class="c++"> +class object: public xml_schema::type +{ +public: +  // Type definitions. +  // +  typedef attribute_set any_attribute_set; +  typedef any_attribute_set::iterator any_attribute_iterator; +  typedef any_attribute_set::const_iterator any_attribute_const_iterator; + +  // Accessors. +  // +  const any_attribute_set& +  any_attribute () const; + +  any_attribute_set& +  any_attribute (); + +  // Modifier. +  // +  void +  any_attribute (const any_attribute_set&); + +  ... + +}; +  </pre> + +  <p>The <code>attribute_set</code> class is an associative container +     similar to the <code>std::set</code> class template as defined by +     the ISO/ANSI Standard for C++ (ISO/IEC 14882:1998, Section 23.3.3, +     "Class template set") with the key being the attribute's name +     and namespace. Unlike <code>std::set</code>, <code>attribute_set</code> +     allows searching using names and namespaces instead of +     <code>xercesc::DOMAttr</code> objects. It is defined in an +     implementation-specific namespace and its interface is presented +     below: +  </p> + +  <pre class="c++"> +class attribute_set +{ +public: +  typedef xercesc::DOMAttr         key_type; +  typedef xercesc::DOMAttr         value_type; +  typedef xercesc::DOMAttr*        pointer; +  typedef const xercesc::DOMAttr*  const_pointer; +  typedef xercesc::DOMAttr&        reference; +  typedef const xercesc::DOMAttr&  const_reference; + +  typedef <implementation-defined> iterator; +  typedef <implementation-defined> const_iterator; +  typedef <implementation-defined> reverse_iterator; +  typedef <implementation-defined> const_reverse_iterator; + +  typedef <implementation-defined> size_type; +  typedef <implementation-defined> difference_type; +  typedef <implementation-defined> allocator_type; + +public: +  attribute_set (xercesc::DOMDocument&); + +  template <typename I> +  attribute_set (const I& begin, const I& end, xercesc::DOMDocument&); + +  attribute_set (const attribute_set&, xercesc::DOMDocument&); + +  attribute_set& +  operator= (const attribute_set&); + +public: +  const_iterator +  begin () const; + +  const_iterator +  end () const; + +  iterator +  begin (); + +  iterator +  end (); + +  const_reverse_iterator +  rbegin () const; + +  const_reverse_iterator +  rend () const; + +  reverse_iterator +  rbegin (); + +  reverse_iterator +  rend (); + +public: +  size_type +  size () const; + +  size_type +  max_size () const; + +  bool +  empty () const; + +  void +  clear (); + +public: +  // Makes a deep copy. +  // +  std::pair<iterator, bool> +  insert (const xercesc::DOMAttr&); + +  // Assumes ownership. +  // +  std::pair<iterator, bool> +  insert (xercesc::DOMAttr*); + +  // Makes a deep copy. +  // +  iterator +  insert (iterator position, const xercesc::DOMAttr&); + +  // Assumes ownership. +  // +  iterator +  insert (iterator position, xercesc::DOMAttr*); + +  template <typename I> +  void +  insert (const I& begin, const I& end); + +public: +  void +  erase (iterator position); + +  size_type +  erase (const std::basic_string<C>& name); + +  size_type +  erase (const std::basic_string<C>& namespace_, +         const std::basic_string<C>& name); + +  size_type +  erase (const XMLCh* name); + +  size_type +  erase (const XMLCh* namespace_, const XMLCh* name); + +  void +  erase (iterator begin, iterator end); + +public: +  size_type +  count (const std::basic_string<C>& name) const; + +  size_type +  count (const std::basic_string<C>& namespace_, +         const std::basic_string<C>& name) const; + +  size_type +  count (const XMLCh* name) const; + +  size_type +  count (const XMLCh* namespace_, const XMLCh* name) const; + +  iterator +  find (const std::basic_string<C>& name); + +  iterator +  find (const std::basic_string<C>& namespace_, +        const std::basic_string<C>& name); + +  iterator +  find (const XMLCh* name); + +  iterator +  find (const XMLCh* namespace_, const XMLCh* name); + +  const_iterator +  find (const std::basic_string<C>& name) const; + +  const_iterator +  find (const std::basic_string<C>& namespace_, +        const std::basic_string<C>& name) const; + +  const_iterator +  find (const XMLCh* name) const; + +  const_iterator +  find (const XMLCh* namespace_, const XMLCh* name) const; + +public: +  // Note that the DOMDocument object of the two sets being +  // swapped should be the same. +  // +  void +  swap (attribute_set&); +}; + +bool +operator== (const attribute_set&, const attribute_set&); + +bool +operator!= (const attribute_set&, const attribute_set&); +  </pre> + +  <p>The following code shows how one could use this mapping:</p> + +  <pre class="c++"> +void +f (object& o, const xercesc::DOMAttr& a) +{ +  using namespace xercesc; + +  object::any_attribute_set& s (o.any_attribute ()); + +  // Iteration. +  // +  for (object::any_attribute_iterator i (s.begin ()); i != s.end (); ++i) +  { +    DOMAttr& a (*i); +  } + +  // Modification. +  // +  s.insert (a);                         // deep copy +  DOMDocument& doc (o.dom_document ()); +  s.insert (doc.createAttribute (...)); // assumes ownership + +  // Searching. +  // +  object::any_attribute_iterator i (s.find ("name")); +  i = s.find ("http://www.w3.org/XML/1998/namespace", "lang"); +} +  </pre> + +  <!-- Mapping for Mixed Content Models --> + +  <h2><a name="2.13">2.13 Mapping for Mixed Content Models</a></h2> + +  <p>For XML Schema types with mixed content models C++/Tree provides +     mapping support only if the type is marked as ordered +     (<a href="#2.8.4">Section 2.8.4, "Element Order"</a>). Use the +     <code>--ordered-type-mixed</code> XSD compiler option to +     automatically mark all types with mixed content as ordered.</p> + +  <p>For an ordered type with mixed content, C++/Tree adds an extra +     text content sequence that is used to store the text fragments. +     This text content sequence is also assigned the content id and +     its entries are included in the content order sequence, just +     like elements. As a result, it is possible to capture the order +     between elements and text fragments.</p> + +  <p>As an example, consider the following schema that describes text +     with embedded links:</p> + +  <pre class="xml"> +<complexType name="anchor"> +  <simpleContent> +    <extension base="string"> +      <attribute name="href" type="anyURI" use="required"/> +    </extension> +  </simpleContent> +</complexType> + +<complexType name="text" mixed="true"> +  <sequence> +    <element name="a" type="anchor" minOccurs="0" maxOccurs="unbounded"/> +  </sequence> +</complexType> +  </pre> + +  <p>The generated <code>text</code> C++ class will provide the following +     API (assuming it is marked as ordered):</p> + +  <pre class="c++"> +class text: public xml_schema::type +{ +public: +  // a +  // +  typedef anchor a_type; +  typedef sequence<a_type> a_sequence; +  typedef a_sequence::iterator a_iterator; +  typedef a_sequence::const_iterator a_const_iterator; + +  static const std::size_t a_id = 1UL; + +  const a_sequence& +  a () const; + +  a_sequence& +  a (); + +  void +  a (const a_sequence&); + +  // text_content +  // +  typedef xml_schema::string text_content_type; +  typedef sequence<text_content_type> text_content_sequence; +  typedef text_content_sequence::iterator text_content_iterator; +  typedef text_content_sequence::const_iterator text_content_const_iterator; + +  static const std::size_t text_content_id = 2UL; + +  const text_content_sequence& +  text_content () const; + +  text_content_sequence& +  text_content (); + +  void +  text_content (const text_content_sequence&); + +  // content_order +  // +  typedef xml_schema::content_order content_order_type; +  typedef std::vector<content_order_type> content_order_sequence; +  typedef content_order_sequence::iterator content_order_iterator; +  typedef content_order_sequence::const_iterator content_order_const_iterator; + +  const content_order_sequence& +  content_order () const; + +  content_order_sequence& +  content_order (); + +  void +  content_order (const content_order_sequence&); + +  ... +}; +  </pre> + +  <p>Given this interface we can iterate over both link elements +     and text in content order. The following code fragment converts +     our format to plain text with references.</p> + +  <pre class="c++"> +const text& t = ... + +for (text::content_order_const_iterator i (t.content_order ().begin ()); +     i != t.content_order ().end (); +     ++i) +{ +  switch (i->id) +  { +  case text::a_id: +    { +      const anchor& a (t.a ()[i->index]); +      cerr << a << "[" << a.href () << "]"; +      break; +    } +  case text::text_content_id: +    { +      const xml_schema::string& s (t.text_content ()[i->index]); +      cerr << s; +      break; +    } +  default: +    { +      assert (false); // Unknown content id. +    } +  } +} +  </pre> + +  <p>For the complete working code that shows the use of mixed content +     in ordered types refer to the <code>order/mixed</code> example in +     the <code>cxx/tree/</code> directory in the +     <a href="https://cppget.org/xsd-examples">xsd-examples</a> +     package.</p> + +  <!-- Parsing --> + + +  <h1><a name="3">3 Parsing</a></h1> + +  <p>This chapter covers various aspects of parsing XML instance +     documents in order to obtain corresponding tree-like object +     model. +  </p> + +  <p>Each global XML Schema element in the form:</p> + +  <pre class="xml"> +<element name="name" type="type"/> +  </pre> + +  <p>is mapped to 14 overloaded C++ functions in the form:</p> + +  <pre class="c++"> +// Read from a URI or a local file. +// + +std::[unique|auto]_ptr<type> +name (const std::basic_string<C>& uri, +      xml_schema::flags = 0, +      const xml_schema::properties& = xml_schema::properties ()); + +std::[unique|auto]_ptr<type> +name (const std::basic_string<C>& uri, +      xml_schema::error_handler&, +      xml_schema::flags = 0, +      const xml_schema::properties& = xml_schema::properties ()); + +std::[unique|auto]_ptr<type> +name (const std::basic_string<C>& uri, +      xercesc::DOMErrorHandler&, +      xml_schema::flags = 0, +      const xml_schema::properties& = xml_schema::properties ()); + + +// Read from std::istream. +// + +std::[unique|auto]_ptr<type> +name (std::istream&, +      xml_schema::flags = 0, +      const xml_schema::properties& = xml_schema::properties ()); + +std::[unique|auto]_ptr<type> +name (std::istream&, +      xml_schema::error_handler&, +      xml_schema::flags = 0, +      const xml_schema::properties& = xml_schema::properties ()); + +std::[unique|auto]_ptr<type> +name (std::istream&, +      xercesc::DOMErrorHandler&, +      xml_schema::flags = 0, +      const xml_schema::properties& = xml_schema::properties ()); + + +std::[unique|auto]_ptr<type> +name (std::istream&, +      const std::basic_string<C>& id, +      xml_schema::flags = 0, +      const xml_schema::properties& = xml_schema::properties ()); + +std::[unique|auto]_ptr<type> +name (std::istream&, +      const std::basic_string<C>& id, +      xml_schema::error_handler&, +      xml_schema::flags = 0, +      const xml_schema::properties& = xml_schema::properties ()); + +std::[unique|auto]_ptr<type> +name (std::istream&, +      const std::basic_string<C>& id, +      xercesc::DOMErrorHandler&, +      xml_schema::flags = 0, +      const xml_schema::properties& = xml_schema::properties ()); + + +// Read from InputSource. +// + +std::[unique|auto]_ptr<type> +name (xercesc::InputSource&, +      xml_schema::flags = 0, +      const xml_schema::properties& = xml_schema::properties ()); + +std::[unique|auto]_ptr<type> +name (xercesc::InputSource&, +      xml_schema::error_handler&, +      xml_schema::flags = 0, +      const xml_schema::properties& = xml_schema::properties ()); + +std::[unique|auto]_ptr<type> +name (xercesc::InputSource&, +      xercesc::DOMErrorHandler&, +      xml_schema::flags = 0, +      const xml_schema::properties& = xml_schema::properties ()); + + +// Read from DOM. +// + +std::[unique|auto]_ptr<type> +name (const xercesc::DOMDocument&, +      xml_schema::flags = 0, +      const xml_schema::properties& = xml_schema::properties ()); + +std::[unique|auto]_ptr<type> +name (xml_schema::dom::[unique|auto]_ptr<xercesc::DOMDocument>, +      xml_schema::flags = 0, +      const xml_schema::properties& = xml_schema::properties ()); +  </pre> + +  <p>You can choose between reading an XML instance from a local file, +     URI, <code>std::istream</code>, <code>xercesc::InputSource</code>, +     or a pre-parsed DOM instance in the form of +     <code>xercesc::DOMDocument</code>. All the parsing functions +     return a dynamically allocated object model as either +     <code>std::unique_ptr</code> or <code>std::auto_ptr</code>, +     depending on the C++ standard selected. Each of these parsing +     functions is discussed in more detail in the following sections. +  </p> + +  <h2><a name="3.1">3.1 Initializing the Xerces-C++ Runtime</a></h2> + +  <p>Some parsing functions expect you to initialize the Xerces-C++ +     runtime while others initialize and terminate it as part of their +     work. The general rule is as follows: if a function has any arguments +     or return a value that is an instance of a Xerces-C++ type, then +     this function expects you to initialize the Xerces-C++ runtime. +     Otherwise, the function initializes and terminates the runtime for +     you. Note that it is legal to have nested calls to the Xerces-C++ +     initialize and terminate functions as long as the calls are balanced. +  </p> + +  <p>You can instruct parsing functions that initialize and terminate +     the runtime not to do so by passing the +     <code>xml_schema::flags::dont_initialize</code> flag (see +     <a href="#3.2">Section 3.2, "Flags and Properties"</a>). +  </p> + + +  <h2><a name="3.2">3.2 Flags and Properties</a></h2> + +  <p>Parsing flags and properties are the last two arguments of every +     parsing function. They allow you to fine-tune the process of +     instance validation and parsing. Both arguments are optional. +  </p> + + +  <p>The following flags are recognized by the parsing functions:</p> + +  <dl> +    <dt><code>xml_schema::flags::keep_dom</code></dt> +    <dd>Keep association between DOM nodes and the resulting +        object model nodes. For more information about DOM association +        refer to <a href="#5.1">Section 5.1, "DOM Association"</a>.</dd> + +    <dt><code>xml_schema::flags::own_dom</code></dt> +    <dd>Assume ownership of the DOM document passed. This flag only +        makes sense together with the <code>keep_dom</code> flag in +        the call to the parsing function with the +        <code>xml_schema::dom::[unique|auto]_ptr<DOMDocument></code> +        argument.</dd> + +    <dt><code>xml_schema::flags::dont_validate</code></dt> +    <dd>Do not validate instance documents against schemas.</dd> + +    <dt><code>xml_schema::flags::dont_initialize</code></dt> +    <dd>Do not initialize the Xerces-C++ runtime.</dd> +  </dl> + +  <p>You can pass several flags by combining them using the bit-wise OR +     operator. For example:</p> + +  <pre class="c++"> +using xml_schema::flags; + +std::unique_ptr<type> r ( +  name ("test.xml", flags::keep_dom | flags::dont_validate)); +  </pre> + +  <p>By default, validation of instance documents is turned on even +     though parsers generated by XSD do not assume instance +     documents are valid. They include a number of checks that prevent +     construction of inconsistent object models. This, +     however, does not mean that an instance document that was +     successfully parsed by the XSD-generated parsers is +     valid per the corresponding schema. If an instance document is not +     "valid enough" for the generated parsers to construct consistent +     object model, one of the exceptions defined in +     <code>xml_schema</code> namespace is thrown (see +     <a href="#3.3">Section 3.3, "Error Handling"</a>). +  </p> + +  <p>For more information on the Xerces-C++ runtime initialization +     refer to <a href="#3.1">Section 3.1, "Initializing the Xerces-C++ +     Runtime"</a>. +  </p> + +  <p>The <code>xml_schema::properties</code> class allows you to +     programmatically specify schema locations to be used instead +     of those specified with the <code>xsi::schemaLocation</code> +     and <code>xsi::noNamespaceSchemaLocation</code> attributes +     in instance documents. The interface of the <code>properties</code> +     class is presented below: +  </p> + +  <pre class="c++"> +class properties +{ +public: +  void +  schema_location (const std::basic_string<C>& namespace_, +                   const std::basic_string<C>& location); +  void +  no_namespace_schema_location (const std::basic_string<C>& location); +}; +  </pre> + +  <p>Note that all locations are relative to an instance document unless +     they are URIs. For example, if you want to use a local file as your +     schema, then you will need to pass +     <code>file:///absolute/path/to/your/schema</code> as the location +     argument. +  </p> + +  <h2><a name="3.3">3.3 Error Handling</a></h2> + +  <p>As discussed in <a href="#2.2">Section 2.2, "Error Handling"</a>, +     the mapping uses the C++ exception handling mechanism as its primary +     way of reporting error conditions. However, to handle recoverable +     parsing and validation errors and warnings, a callback interface maybe +     preferred by the application.</p> + +  <p>To better understand error handling and reporting strategies employed +     by the parsing functions, it is useful to know that the +     transformation of an XML instance document to a statically-typed +     tree happens in two stages. The first stage, performed by Xerces-C++, +     consists of parsing an XML document into a DOM instance. For short, +     we will call this stage the XML-DOM stage. Validation, if not disabled, +     happens during this stage. The second stage, +     performed by the generated parsers, consist of parsing the DOM +     instance into the statically-typed tree. We will call this stage +     the DOM-Tree stage. Additional checks are performed during this +     stage in order to prevent construction of inconsistent tree which +     could otherwise happen when validation is disabled, for example.</p> + +  <p>All parsing functions except the one that operates on a DOM instance +     come in overloaded triples. The first function in such a triple +     reports error conditions exclusively by throwing exceptions. It +     accumulates all the parsing and validation errors of the XML-DOM +     stage and throws them in a single instance of the +     <code>xml_schema::parsing</code> exception (described below). +     The second and the third functions in the triple use callback +     interfaces to report parsing and validation errors and warnings. +     The two callback interfaces are <code>xml_schema::error_handler</code> +     and <code>xercesc::DOMErrorHandler</code>. For more information +     on the <code>xercesc::DOMErrorHandler</code> interface refer to +     the Xerces-C++ documentation. The <code>xml_schema::error_handler</code> +     interface is presented below: +  </p> + +  <pre class="c++"> +class error_handler +{ +public: +  struct severity +  { +    enum value +    { +      warning, +      error, +      fatal +    }; +  }; + +  virtual bool +  handle (const std::basic_string<C>& id, +          unsigned long line, +          unsigned long column, +          severity, +          const std::basic_string<C>& message) = 0; + +  virtual +  ~error_handler (); +}; +  </pre> + +  <p>The <code>id</code> argument of the <code>error_handler::handle</code> +     function identifies the resource being parsed (e.g., a file name or +     URI). +  </p> + +  <p>By returning <code>true</code> from the <code>handle</code> function +     you instruct the parser to recover and continue parsing. Returning +     <code>false</code> results in termination of the parsing process. +     An error with the <code>fatal</code> severity level results in +     termination of the parsing process no matter what is returned from +     the <code>handle</code> function. It is safe to throw an exception +     from the <code>handle</code> function. +  </p> + +  <p>The DOM-Tree stage reports error conditions exclusively by throwing +     exceptions. Individual exceptions thrown by the parsing functions +     are described in the following sub-sections. +  </p> + + +  <h3><a name="3.3.1">3.3.1 <code>xml_schema::parsing</code></a></h3> + +  <pre class="c++"> +struct severity +{ +  enum value +  { +    warning, +    error +  }; + +  severity (value); +  operator value () const; +}; + +struct error +{ +  error (severity, +         const std::basic_string<C>& id, +         unsigned long line, +         unsigned long column, +         const std::basic_string<C>& message); + +  severity +  severity () const; + +  const std::basic_string<C>& +  id () const; + +  unsigned long +  line () const; + +  unsigned long +  column () const; + +  const std::basic_string<C>& +  message () const; +}; + +std::basic_ostream<C>& +operator<< (std::basic_ostream<C>&, const error&); + +struct diagnostics: std::vector<error> +{ +}; + +std::basic_ostream<C>& +operator<< (std::basic_ostream<C>&, const diagnostics&); + +struct parsing: virtual exception +{ +  parsing (); +  parsing (const diagnostics&); + +  const diagnostics& +  diagnostics () const; + +  virtual const char* +  what () const throw (); +}; +  </pre> + +  <p>The <code>xml_schema::parsing</code> exception is thrown if there +     were parsing or validation errors reported during the XML-DOM stage. +     If no callback interface was provided to the parsing function, the +     exception contains a list of errors and warnings accessible using +     the <code>diagnostics</code> function. The usual conditions when +     this exception is thrown include malformed XML instances and, if +     validation is turned on, invalid instance documents. +  </p> + +  <h3><a name="3.3.2">3.3.2 <code>xml_schema::expected_element</code></a></h3> + +  <pre class="c++"> +struct expected_element: virtual exception +{ +  expected_element (const std::basic_string<C>& name, +                    const std::basic_string<C>& namespace_); + + +  const std::basic_string<C>& +  name () const; + +  const std::basic_string<C>& +  namespace_ () const; + + +  virtual const char* +  what () const throw (); +}; +  </pre> + +  <p>The <code>xml_schema::expected_element</code> exception is thrown +     when an expected element is not encountered by the DOM-Tree stage. +     The name and namespace of the expected element can be obtained using +     the <code>name</code> and <code>namespace_</code> functions respectively. +  </p> + + +  <h3><a name="3.3.3">3.3.3 <code>xml_schema::unexpected_element</code></a></h3> + +  <pre class="c++"> +struct unexpected_element: virtual exception +{ +  unexpected_element (const std::basic_string<C>& encountered_name, +                      const std::basic_string<C>& encountered_namespace, +                      const std::basic_string<C>& expected_name, +                      const std::basic_string<C>& expected_namespace) + + +  const std::basic_string<C>& +  encountered_name () const; + +  const std::basic_string<C>& +  encountered_namespace () const; + + +  const std::basic_string<C>& +  expected_name () const; + +  const std::basic_string<C>& +  expected_namespace () const; + + +  virtual const char* +  what () const throw (); +}; +  </pre> + +  <p>The <code>xml_schema::unexpected_element</code> exception is thrown +     when an unexpected element is encountered by the DOM-Tree stage. +     The name and namespace of the encountered element can be obtained +     using the <code>encountered_name</code> and +     <code>encountered_namespace</code> functions respectively. If an +     element was expected instead of the encountered one, its name +     and namespace can be obtained using the <code>expected_name</code> and +     <code>expected_namespace</code> functions respectively. Otherwise +     these functions return empty strings. +  </p> + +  <h3><a name="3.3.4">3.3.4 <code>xml_schema::expected_attribute</code></a></h3> + +  <pre class="c++"> +struct expected_attribute: virtual exception +{ +  expected_attribute (const std::basic_string<C>& name, +                      const std::basic_string<C>& namespace_); + + +  const std::basic_string<C>& +  name () const; + +  const std::basic_string<C>& +  namespace_ () const; + + +  virtual const char* +  what () const throw (); +}; +  </pre> + +  <p>The <code>xml_schema::expected_attribute</code> exception is thrown +     when an expected attribute is not encountered by the DOM-Tree stage. +     The name and namespace of the expected attribute can be obtained using +     the <code>name</code> and <code>namespace_</code> functions respectively. +  </p> + + +  <h3><a name="3.3.5">3.3.5 <code>xml_schema::unexpected_enumerator</code></a></h3> + +  <pre class="c++"> +struct unexpected_enumerator: virtual exception +{ +  unexpected_enumerator (const std::basic_string<C>& enumerator); + +  const std::basic_string<C>& +  enumerator () const; + +  virtual const char* +  what () const throw (); +}; +  </pre> + +  <p>The <code>xml_schema::unexpected_enumerator</code> exception is thrown +     when an unexpected enumerator is encountered by the DOM-Tree stage. +     The enumerator can be obtained using the <code>enumerator</code> +     functions. +  </p> + +  <h3><a name="3.3.6">3.3.6 <code>xml_schema::expected_text_content</code></a></h3> + +  <pre class="c++"> +struct expected_text_content: virtual exception +{ +  virtual const char* +  what () const throw (); +}; +  </pre> + +  <p>The <code>xml_schema::expected_text_content</code> exception is thrown +     when a content other than text is encountered and the text content was +     expected by the DOM-Tree stage. +  </p> + +  <h3><a name="3.3.7">3.3.7 <code>xml_schema::no_type_info</code></a></h3> + +  <pre class="c++"> +struct no_type_info: virtual exception +{ +  no_type_info (const std::basic_string<C>& type_name, +                const std::basic_string<C>& type_namespace); + +  const std::basic_string<C>& +  type_name () const; + +  const std::basic_string<C>& +  type_namespace () const; + +  virtual const char* +  what () const throw (); +}; +  </pre> + +  <p>The <code>xml_schema::no_type_info</code> exception is thrown +     when there is no type information associated with a type specified +     by the <code>xsi:type</code> attribute. This exception is thrown +     by the DOM-Tree stage. The name and namespace of the type in question +     can be obtained using the <code>type_name</code> and +     <code>type_namespace</code> functions respectively. Usually, catching +     this exception means that you haven't linked the code generated +     from the schema defining the type in question with your application +     or this schema has been compiled without the +     <code>--generate-polymorphic</code> option. +  </p> + + +  <h3><a name="3.3.8">3.3.8 <code>xml_schema::not_derived</code></a></h3> + +  <pre class="c++"> +struct not_derived: virtual exception +{ +  not_derived (const std::basic_string<C>& base_type_name, +               const std::basic_string<C>& base_type_namespace, +               const std::basic_string<C>& derived_type_name, +               const std::basic_string<C>& derived_type_namespace); + +  const std::basic_string<C>& +  base_type_name () const; + +  const std::basic_string<C>& +  base_type_namespace () const; + + +  const std::basic_string<C>& +  derived_type_name () const; + +  const std::basic_string<C>& +  derived_type_namespace () const; + +  virtual const char* +  what () const throw (); +}; +  </pre> + +  <p>The <code>xml_schema::not_derived</code> exception is thrown +     when a type specified by the <code>xsi:type</code> attribute is +     not derived from the expected base type. This exception is thrown +     by the DOM-Tree stage. The name and namespace of the expected +     base type can be obtained using the <code>base_type_name</code> and +     <code>base_type_namespace</code> functions respectively. The name +     and namespace of the offending type can be obtained using the +     <code>derived_type_name</code> and +     <code>derived_type_namespace</code> functions respectively. +  </p> + +  <h3><a name="3.3.9">3.3.9 <code>xml_schema::no_prefix_mapping</code></a></h3> + +  <pre class="c++"> +struct no_prefix_mapping: virtual exception +{ +  no_prefix_mapping (const std::basic_string<C>& prefix); + +  const std::basic_string<C>& +  prefix () const; + +  virtual const char* +  what () const throw (); +}; +  </pre> + +  <p>The <code>xml_schema::no_prefix_mapping</code> exception is thrown +     during the DOM-Tree stage if a namespace prefix is encountered for +     which a prefix-namespace mapping hasn't been provided. The namespace +     prefix in question can be obtained using the <code>prefix</code> +     function. +  </p> + +  <h2><a name="3.4">3.4 Reading from a Local File or URI</a></h2> + +  <p>Using a local file or URI is the simplest way to parse an XML instance. +     For example:</p> + +  <pre class="c++"> +using std::unique_ptr; + +unique_ptr<type> r1 (name ("test.xml")); +unique_ptr<type> r2 (name ("https://www.codesynthesis.com/test.xml")); +  </pre> + +  <p>Or, in the C++98 mode:</p> + +  <pre class="c++"> +using std::auto_ptr; + +auto_ptr<type> r1 (name ("test.xml")); +auto_ptr<type> r2 (name ("https://www.codesynthesis.com/test.xml")); +  </pre> + +  <h2><a name="3.5">3.5 Reading from <code>std::istream</code></a></h2> + +  <p>When using an <code>std::istream</code> instance, you may also +     pass an optional resource id. This id is used to identify the +     resource (for example in error messages) as well as to resolve +     relative paths. For instance:</p> + +  <pre class="c++"> +using std::unique_ptr; + +{ +  std::ifstream ifs ("test.xml"); +  unique_ptr<type> r (name (ifs, "test.xml")); +} + +{ +  std::string str ("..."); // Some XML fragment. +  std::istringstream iss (str); +  unique_ptr<type> r (name (iss)); +} +  </pre> + +  <h2><a name="3.6">3.6 Reading from <code>xercesc::InputSource</code></a></h2> + +  <p>Reading from a <code>xercesc::InputSource</code> instance +     is similar to the <code>std::istream</code> case except +     the resource id is maintained by the <code>InputSource</code> +     object. For instance:</p> + +  <pre class="c++"> +xercesc::StdInInputSource is; +std::unique_ptr<type> r (name (is)); +  </pre> + +  <h2><a name="3.7">3.7 Reading from DOM</a></h2> + +  <p>Reading from a <code>xercesc::DOMDocument</code> instance allows +     you to setup a custom XML-DOM stage. Things like DOM +     parser reuse, schema pre-parsing, and schema caching can be achieved +     with this approach. For more information on how to obtain DOM +     representation from an XML instance refer to the Xerces-C++ +     documentation. In addition, the +     <a href="http://wiki.codesynthesis.com/Tree/FAQ">C++/Tree Mapping +     FAQ</a> shows how to parse an XML instance to a Xerces-C++ +     DOM document using the XSD runtime utilities. +  </p> + +  <p>The last parsing function is useful when you would like to perform +     your own XML-to-DOM parsing and associate the resulting DOM document +     with the object model nodes. The automatic <code>DOMDocument</code> +     pointer is reset and the resulting object model assumes ownership +     of the DOM document passed. For example:</p> + +  <pre class="c++"> +// C++11 version. +// +xml_schema::dom::unique_ptr<xercesc::DOMDocument> doc = ... + +std::unique_ptr<type> r ( +  name (std::move (doc), +        xml_schema::flags::keep_dom | xml_schema::flags::own_dom)); + +// At this point doc is reset to 0. + +// C++98 version. +// +xml_schema::dom::auto_ptr<xercesc::DOMDocument> doc = ... + +std::auto_ptr<type> r ( +  name (doc, xml_schema::flags::keep_dom | xml_schema::flags::own_dom)); + +// At this point doc is reset to 0. +  </pre> + +  <h1><a name="4">4 Serialization</a></h1> + +  <p>This chapter covers various aspects of serializing a +     tree-like object model to DOM or XML. +     In this regard, serialization is complimentary to the reverse +     process of parsing a DOM or XML instance into an object model +     which is discussed in <a href="#3">Chapter 3, +     "Parsing"</a>. Note that the generation of the serialization code +     is optional and should be explicitly requested with the +     <code>--generate-serialization</code> option. See the +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD +     Compiler Command Line Manual</a> for more information. +  </p> + +  <p>Each global XML Schema element in the form: +  </p> + + +  <pre class="xml"> +<xsd:element name="name" type="type"/> +  </pre> + +  <p>is mapped to 8 overloaded C++ functions in the form:</p> + +  <pre class="c++"> +// Serialize to std::ostream. +// +void +name (std::ostream&, +      const type&, +      const xml_schema::namespace_fomap& = +        xml_schema::namespace_infomap (), +      const std::basic_string<C>& encoding = "UTF-8", +      xml_schema::flags = 0); + +void +name (std::ostream&, +      const type&, +      xml_schema::error_handler&, +      const xml_schema::namespace_infomap& = +        xml_schema::namespace_infomap (), +      const std::basic_string<C>& encoding = "UTF-8", +      xml_schema::flags = 0); + +void +name (std::ostream&, +      const type&, +      xercesc::DOMErrorHandler&, +      const xml_schema::namespace_infomap& = +        xml_schema::namespace_infomap (), +      const std::basic_string<C>& encoding = "UTF-8", +      xml_schema::flags = 0); + + +// Serialize to XMLFormatTarget. +// +void +name (xercesc::XMLFormatTarget&, +      const type&, +      const xml_schema::namespace_infomap& = +        xml_schema::namespace_infomap (), +      const std::basic_string<C>& encoding = "UTF-8", +      xml_schema::flags = 0); + +void +name (xercesc::XMLFormatTarget&, +      const type&, +      xml_schema::error_handler&, +      const xml_schema::namespace_infomap& = +        xml_schema::namespace_infomap (), +      const std::basic_string<C>& encoding = "UTF-8", +      xml_schema::flags = 0); + +void +name (xercesc::XMLFormatTarget&, +      const type&, +      xercesc::DOMErrorHandler&, +      const xml_schema::namespace_infomap& = +        xml_schema::namespace_infomap (), +      const std::basic_string<C>& encoding = "UTF-8", +      xml_schema::flags = 0); + + +// Serialize to DOM. +// +xml_schema::dom::[unique|auto]_ptr<xercesc::DOMDocument> +name (const type&, +      const xml_schema::namespace_infomap& +        xml_schema::namespace_infomap (), +      xml_schema::flags = 0); + +void +name (xercesc::DOMDocument&, +      const type&, +      xml_schema::flags = 0); +  </pre> + +  <p>You can choose between writing XML to <code>std::ostream</code> or +     <code>xercesc::XMLFormatTarget</code> and creating a DOM instance +     in the form of <code>xercesc::DOMDocument</code>. Serialization +     to <code>ostream</code> or <code>XMLFormatTarget</code> requires a +     considerably less work while serialization to DOM provides +     for greater flexibility. Each of these serialization functions +     is discussed in more detail in the following sections. +  </p> + + +  <h2><a name="4.1">4.1 Initializing the Xerces-C++ Runtime</a></h2> + +  <p>Some serialization functions expect you to initialize the Xerces-C++ +     runtime while others initialize and terminate it as part of their +     work. The general rule is as follows: if a function has any arguments +     or return a value that is an instance of a Xerces-C++ type, then +     this function expects you to initialize the Xerces-C++ runtime. +     Otherwise, the function initializes and terminates the runtime for +     you. Note that it is legal to have nested calls to the Xerces-C++ +     initialize and terminate functions as long as the calls are balanced. +  </p> + +  <p>You can instruct serialization functions that initialize and terminate +     the runtime not to do so by passing the +     <code>xml_schema::flags::dont_initialize</code> flag (see +     <a href="#4.3">Section 4.3, "Flags"</a>). +  </p> + +  <h2><a name="4.2">4.2 Namespace Infomap and Character Encoding</a></h2> + +  <p>When a document being serialized uses XML namespaces, custom +     prefix-namespace associations can to be established. If custom +     prefix-namespace mapping is not provided then generic prefixes +     (<code>p1</code>, <code>p2</code>, etc) are automatically assigned +     to namespaces as needed. Also, if +     you would like the resulting instance document to contain the +     <code>schemaLocation</code> or <code>noNamespaceSchemaLocation</code> +     attributes, you will need to provide namespace-schema associations. +     The <code>xml_schema::namespace_infomap</code> class is used +     to capture this information:</p> + +  <pre class="c++"> +struct namespace_info +{ +  namespace_info (); +  namespace_info (const std::basic_string<C>& name, +                  const std::basic_string<C>& schema); + +  std::basic_string<C> name; +  std::basic_string<C> schema; +}; + +// Map of namespace prefix to namespace_info. +// +struct namespace_infomap: public std::map<std::basic_string<C>, +                                          namespace_info> +{ +}; +  </pre> + +  <p>Consider the following associations as an example:</p> + +  <pre class="c++"> +xml_schema::namespace_infomap map; + +map["t"].name = "https://www.codesynthesis.com/test"; +map["t"].schema = "test.xsd"; +  </pre> + +  <p>This map, if passed to one of the serialization functions, +     could result in the following XML fragment:</p> + +  <pre class="xml"> +<?xml version="1.0" ?> +<t:name xmlns:t="https://www.codesynthesis.com/test" +        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +        xsi:schemaLocation="https://www.codesynthesis.com/test test.xsd"> +  </pre> + +  <p>As you can see, the serialization function automatically added namespace +     mapping for the <code>xsi</code> prefix. You can change this by +     providing your own prefix:</p> + +  <pre class="c++"> +xml_schema::namespace_infomap map; + +map["xsn"].name = "http://www.w3.org/2001/XMLSchema-instance"; + +map["t"].name = "https://www.codesynthesis.com/test"; +map["t"].schema = "test.xsd"; +  </pre> + +  <p>This could result in the following XML fragment:</p> + +  <pre class="xml"> +<?xml version="1.0" ?> +<t:name xmlns:t="https://www.codesynthesis.com/test" +        xmlns:xsn="http://www.w3.org/2001/XMLSchema-instance" +        xsn:schemaLocation="https://www.codesynthesis.com/test test.xsd"> +  </pre> + +  <p>To specify the location of a schema without a namespace you can use +     an empty prefix as in the example below: </p> + +  <pre class="c++"> +xml_schema::namespace_infomap map; + +map[""].schema = "test.xsd"; +  </pre> + +  <p>This would result in the following XML fragment:</p> + +  <pre class="xml"> +<?xml version="1.0" ?> +<name xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +      xsi:noNamespaceSchemaLocation="test.xsd"> +  </pre> + +  <p>To make a particular namespace default you can use an empty +     prefix, for example:</p> + +  <pre class="c++"> +xml_schema::namespace_infomap map; + +map[""].name = "https://www.codesynthesis.com/test"; +map[""].schema = "test.xsd"; +  </pre> + +  <p>This could result in the following XML fragment:</p> + +  <pre class="xml"> +<?xml version="1.0" ?> +<name xmlns="https://www.codesynthesis.com/test" +      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +      xsi:schemaLocation="https://www.codesynthesis.com/test test.xsd"> +  </pre> + + +  <p>Another bit of information that you can pass to the serialization +     functions is the character encoding method that you would like to use. +     Common values for this argument are <code>"US-ASCII"</code>, +     <code>"ISO8859-1"</code>, <code>"UTF-8"</code>, +     <code>"UTF-16BE"</code>, <code>"UTF-16LE"</code>, +     <code>"UCS-4BE"</code>, and <code>"UCS-4LE"</code>. The default +     encoding is <code>"UTF-8"</code>. For more information on +     encoding methods see the +     "<a href="http://en.wikipedia.org/wiki/Character_code">Character +     Encoding</a>" article from Wikipedia. +  </p> + +  <h2><a name="4.3">4.3 Flags</a></h2> + +  <p>Serialization flags are the last argument of every serialization +     function. They allow you to fine-tune the process of serialization. +     The flags argument is optional. +  </p> + + +  <p>The following flags are recognized by the serialization +     functions:</p> + +  <dl> +    <dt><code>xml_schema::flags::dont_initialize</code></dt> +    <dd>Do not initialize the Xerces-C++ runtime.</dd> + +    <dt><code>xml_schema::flags::dont_pretty_print</code></dt> +    <dd>Do not add extra spaces or new lines that make the resulting XML +        slightly bigger but easier to read.</dd> + +    <dt><code>xml_schema::flags::no_xml_declaration</code></dt> +    <dd>Do not write XML declaration (<?xml ... ?>).</dd> +  </dl> + +  <p>You can pass several flags by combining them using the bit-wise OR +     operator. For example:</p> + +  <pre class="c++"> +std::unique_ptr<type> r = ... +std::ofstream ofs ("test.xml"); +xml_schema::namespace_infomap map; +name (ofs, +      *r, +      map, +      "UTF-8", +      xml_schema::flags::no_xml_declaration | +      xml_schema::flags::dont_pretty_print); +  </pre> + +  <p>For more information on the Xerces-C++ runtime initialization +     refer to <a href="#4.1">Section 4.1, "Initializing the Xerces-C++ +     Runtime"</a>. +  </p> + +  <h2><a name="4.4">4.4 Error Handling</a></h2> + +  <p>As with the parsing functions (see <a href="#3.3">Section 3.3, +     "Error Handling"</a>), to better understand error handling and +     reporting strategies employed by the serialization functions, it +     is useful to know that the transformation of a statically-typed +     tree to an XML instance document happens in two stages. The first +     stage, performed by the generated code, consist of building a DOM +     instance from the statically-typed tree . For short, we will call +     this stage the Tree-DOM stage. The second stage, performed by +     Xerces-C++, consists of serializing the DOM instance into the XML +     document. We will call this stage the DOM-XML stage. +  </p> + +  <p>All serialization functions except the two that serialize into +     a DOM instance come in overloaded triples. The first function +     in such a triple reports error conditions exclusively by throwing +     exceptions. It accumulates all the serialization errors of the +     DOM-XML stage and throws them in a single instance of the +     <code>xml_schema::serialization</code> exception (described below). +     The second and the third functions in the triple use callback +     interfaces to report serialization errors and warnings. The two +     callback interfaces are <code>xml_schema::error_handler</code> and +     <code>xercesc::DOMErrorHandler</code>. The +     <code>xml_schema::error_handler</code> interface is described in +     <a href="#3.3">Section 3.3, "Error Handling"</a>. For more information +     on the <code>xercesc::DOMErrorHandler</code> interface refer to the +     Xerces-C++ documentation. +  </p> + +  <p>The Tree-DOM stage reports error conditions exclusively by throwing +     exceptions. Individual exceptions thrown by the serialization functions +     are described in the following sub-sections. +  </p> + +  <h3><a name="4.4.1">4.4.1 <code>xml_schema::serialization</code></a></h3> + +  <pre class="c++"> +struct serialization: virtual exception +{ +  serialization (); +  serialization (const diagnostics&); + +  const diagnostics& +  diagnostics () const; + +  virtual const char* +  what () const throw (); +}; +  </pre> + +  <p>The <code>xml_schema::diagnostics</code> class is described in +     <a href="#3.3.1">Section 3.3.1, "<code>xml_schema::parsing</code>"</a>. +     The <code>xml_schema::serialization</code> exception is thrown if +     there were serialization errors reported during the DOM-XML stage. +     If no callback interface was provided to the serialization function, +     the exception contains a list of errors and warnings accessible using +     the <code>diagnostics</code> function. +  </p> + + +  <h3><a name="4.4.2">4.4.2 <code>xml_schema::unexpected_element</code></a></h3> + +  <p>The <code>xml_schema::unexpected_element</code> exception is +     described in <a href="#3.3.3">Section 3.3.3, +     "<code>xml_schema::unexpected_element</code>"</a>. It is thrown +     by the serialization functions during the Tree-DOM stage if the +     root element name of the provided DOM instance does not match with +     the name of the element this serialization function is for. +  </p> + +  <h3><a name="4.4.3">4.4.3 <code>xml_schema::no_type_info</code></a></h3> + +  <p>The <code>xml_schema::no_type_info</code> exception is +     described in <a href="#3.3.7">Section 3.3.7, +     "<code>xml_schema::no_type_info</code>"</a>. It is thrown +     by the serialization functions during the Tree-DOM stage when there +     is no type information associated with a dynamic type of an +     element. Usually, catching this exception means that you haven't +     linked the code generated from the schema defining the type in +     question with your application or this schema has been compiled +     without the <code>--generate-polymorphic</code> option. +  </p> + +  <h2><a name="4.5">4.5 Serializing to <code>std::ostream</code></a></h2> + +  <p>In order to serialize to <code>std::ostream</code> you will need +     an object model, an output stream and, optionally, a namespace +     infomap. For instance:</p> + +  <pre class="c++"> +// Obtain the object model. +// +std::unique_ptr<type> r = ... + +// Prepare namespace mapping and schema location information. +// +xml_schema::namespace_infomap map; + +map["t"].name = "https://www.codesynthesis.com/test"; +map["t"].schema = "test.xsd"; + +// Write it out. +// +name (std::cout, *r, map); +  </pre> + +  <p>Note that the output stream is treated as a binary stream. This +     becomes important when you use a character encoding that is wider +     than 8-bit <code>char</code>, for instance UTF-16 or UCS-4. For +     example, things will most likely break if you try to serialize +     to <code>std::ostringstream</code> with UTF-16 or UCS-4 as an +     encoding. This is due to the special value, +     <code>'\0'</code>, that will most likely occur as part of such +     serialization and it won't have the special meaning assumed by +     <code>std::ostringstream</code>. +  </p> + + +  <h2><a name="4.6">4.6 Serializing to <code>xercesc::XMLFormatTarget</code></a></h2> + +  <p>Serializing to an <code>xercesc::XMLFormatTarget</code> instance +     is similar the <code>std::ostream</code> case. For instance: +  </p> + +  <pre class="c++"> +using std::unique_ptr; + +// Obtain the object model. +// +unique_ptr<type> r = ... + +// Prepare namespace mapping and schema location information. +// +xml_schema::namespace_infomap map; + +map["t"].name = "https://www.codesynthesis.com/test"; +map["t"].schema = "test.xsd"; + +using namespace xercesc; + +XMLPlatformUtils::Initialize (); + +{ +  // Choose a target. +  // +  unique_ptr<XMLFormatTarget> ft; + +  if (argc != 2) +  { +    ft = unique_ptr<XMLFormatTarget> (new StdOutFormatTarget ()); +  } +  else +  { +    ft = unique_ptr<XMLFormatTarget> ( +      new LocalFileFormatTarget (argv[1])); +  } + +  // Write it out. +  // +  name (*ft, *r, map); +} + +XMLPlatformUtils::Terminate (); +  </pre> + +  <p>Note that we had to initialize the Xerces-C++ runtime before we +     could call this serialization function.</p> + +  <h2><a name="4.7">4.7 Serializing to DOM</a></h2> + +  <p>The mapping provides two overloaded functions that implement +     serialization to a DOM instance. The first creates a DOM instance +     for you and the second serializes to an existing DOM instance. +     While serializing to a new DOM instance is similar to serializing +     to <code>std::ostream</code> or <code>xercesc::XMLFormatTarget</code>, +     serializing to an existing DOM instance requires quite a bit of work +     from your side. You will need to set all the custom namespace mapping +     attributes as well as the <code>schemaLocation</code> and/or +     <code>noNamespaceSchemaLocation</code> attributes. The following +     listing should give you an idea about what needs to be done: +  </p> + +  <pre class="c++"> +// Obtain the object model. +// +std::unique_ptr<type> r = ... + +using namespace xercesc; + +XMLPlatformUtils::Initialize (); + +{ +  // Create a DOM instance. Set custom namespace mapping and schema +  // location attributes. +  // +  DOMDocument& doc = ... + +  // Serialize to DOM. +  // +  name (doc, *r); + +  // Serialize the DOM document to XML. +  // +  ... +} + +XMLPlatformUtils::Terminate (); +  </pre> + +  <p>For more information on how to create and serialize a DOM instance +     refer to the Xerces-C++ documentation. In addition, the +     <a href="http://wiki.codesynthesis.com/Tree/FAQ">C++/Tree Mapping +     FAQ</a> shows how to implement these operations using the XSD +     runtime utilities. +  </p> + +  <h1><a name="5">5 Additional Functionality</a></h1> + +  <p>The C++/Tree mapping provides a number of optional features +     that can be useful in certain situations. They are described +     in the following sections.</p> + +  <h2><a name="5.1">5.1 DOM Association</a></h2> + +  <p>Normally, after parsing is complete, the DOM document which +     was used to extract the data is discarded. However, the parsing +     functions can be instructed to preserve the DOM document +     and create an association between the DOM nodes and object model +     nodes. When there is an association between the DOM and +     object model nodes, you can obtain the corresponding DOM element +     or attribute node from an object model node as well as perform +     the reverse transition: obtain the corresponding object model +     from a DOM element or attribute node.</p> + +  <p>Maintaining DOM association is normally useful when the application +     needs access to XML constructs that are not preserved in the +     object model, for example, XML comments. +     Another useful aspect of DOM association is the ability of the +     application to navigate the document tree using the generic DOM +     interface (for example, with the help of an XPath processor) +     and then move back to the statically-typed object model. Note +     also that while you can change the underlying DOM document, +     these changes are not reflected in the object model and will +     be ignored during serialization. If you need to not only access +     but also modify some aspects of XML that are not preserved in +     the object model, then type customization with custom parsing +     constructors and serialization operators should be used instead.</p> + +  <p>To request DOM association you will need to pass the +     <code>xml_schema::flags::keep_dom</code> flag to one of the +     parsing functions (see <a href="#3.2">Section 3.2, +     "Flags and Properties"</a> for more information). In this case the +     DOM document is retained and will be released when the object model +     is deleted. Note that since DOM nodes "out-live" the parsing function +     call, you need to initialize the Xerces-C++ runtime before calling +     one of the parsing functions with the <code>keep_dom</code> flag and +     terminate it after the object model is destroyed (see +     <a href="#3.1">Section 3.1, "Initializing the Xerces-C++ Runtime"</a>).</p> + +   <p>If the <code>keep_dom</code> flag is passed +      as the second argument to the copy constructor and the copy +      being made is of a complete tree, then the DOM association +      is also maintained in the copy by cloning the underlying +      DOM document and reestablishing the associations. For example:</p> + +  <pre class="c++"> +using namespace xercesc; + +XMLPlatformUtils::Initialize (); + +{ +  // Parse XML to object model. +  // +  std::unique_ptr<type> r (root ( +    "root.xml", +     xml_schema::flags::keep_dom | +     xml_schema::flags::dont_initialize)); + +   // Copy without DOM association. +   // +   type copy1 (*r); + +   // Copy with DOM association. +   // +   type copy2 (*r, xml_schema::flags::keep_dom); +} + +XMLPlatformUtils::Terminate (); +  </pre> + + +  <p>To obtain the corresponding DOM node from an object model node +     you will need to call the <code>_node</code> accessor function +     which returns a pointer to <code>DOMNode</code>. You can then query +     this DOM node's type and cast it to either <code>DOMAttr*</code> +     or <code>DOMElement*</code>. To obtain the corresponding object +     model node from a DOM node, the DOM user data API is used. The +     <code>xml_schema::dom::tree_node_key</code> variable contains +     the key for object model nodes. The following schema and code +     fragment show how to navigate from DOM to object model nodes +     and in the opposite direction:</p> + +  <pre class="xml"> +<complexType name="object"> +  <sequence> +    <element name="a" type="string"/> +  </sequence> +</complexType> + +<element name="root" type="object"/> +  </pre> + +  <pre class="c++"> +using namespace xercesc; + +XMLPlatformUtils::Initialize (); + +{ +  // Parse XML to object model. +  // +  std::unique_ptr<type> r (root ( +    "root.xml", +     xml_schema::flags::keep_dom | +     xml_schema::flags::dont_initialize)); + +  DOMNode* n = r->_node (); +  assert (n->getNodeType () == DOMNode::ELEMENT_NODE); +  DOMElement* re = static_cast<DOMElement*> (n); + +  // Get the 'a' element. Note that it is not necessarily the +  // first child node of 'root' since there could be whitespace +  // nodes before it. +  // +  DOMElement* ae; + +  for (n = re->getFirstChild (); n != 0; n = n->getNextSibling ()) +  { +    if (n->getNodeType () == DOMNode::ELEMENT_NODE) +    { +      ae = static_cast<DOMElement*> (n); +      break; +    } +  } + +  // Get from the 'a' DOM element to xml_schema::string object model +  // node. +  // +  xml_schema::type& t ( +    *reinterpret_cast<xml_schema::type*> ( +       ae->getUserData (xml_schema::dom::tree_node_key))); + +  xml_schema::string& a (dynamic_cast<xml_schema::string&> (t)); +} + +XMLPlatformUtils::Terminate (); +  </pre> + +  <p>The 'mixed' example which can be found in the XSD distribution +     shows how to handle the mixed content using DOM association.</p> + +  <h2><a name="5.2">5.2 Binary Serialization</a></h2> + +  <p>Besides reading from and writing to XML, the C++/Tree mapping +     also allows you to save the object model to and load it from a +     number of predefined as well as custom data representation +     formats. The predefined binary formats are CDR (Common Data +     Representation) and XDR (eXternal Data Representation). A +     custom format can easily be supported by providing +     insertion and extraction operators for basic types.</p> + +  <p>Binary serialization saves only the data without any meta +     information or markup. As a result, saving to and loading +     from a binary representation can be an order of magnitude +     faster than parsing and serializing the same data in XML. +     Furthermore, the resulting representation is normally several +     times smaller than the equivalent XML representation. These +     properties make binary serialization ideal for internal data +     exchange and storage. A typical application that uses this +     facility stores the data and communicates within the +     system using a binary format and reads/writes the data +     in XML when communicating with the outside world.</p> + +  <p>In order to request the generation of insertion operators and +     extraction constructors for a specific predefined or custom +     data representation stream, you will need to use the +     <code>--generate-insertion</code> and <code>--generate-extraction</code> +     compiler options. See the +     <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD +     Compiler Command Line Manual</a> for more information.</p> + +  <p>Once the insertion operators and extraction constructors are +     generated, you can use the <code>xml_schema::istream</code> +     and <code>xml_schema::ostream</code> wrapper stream templates +     to save the object model to and load it from a specific format. +     The following code fragment shows how to do this using ACE +     (Adaptive Communication Environment) CDR streams as an example:</p> + +  <pre class="xml"> +<complexType name="object"> +  <sequence> +    <element name="a" type="string"/> +    <element name="b" type="int"/> +  </sequence> +</complexType> + +<element name="root" type="object"/> +  </pre> + +  <pre class="c++"> +// Parse XML to object model. +// +std::unique_ptr<type> r (root ("root.xml")); + +// Save to a CDR stream. +// +ACE_OutputCDR ace_ocdr; +xml_schema::ostream<ACE_OutputCDR> ocdr (ace_ocdr); + +ocdr << *r; + +// Load from a CDR stream. +// +ACE_InputCDR ace_icdr (buf, size); +xml_schema::istream<ACE_InputCDR> icdr (ace_icdr); + +std::unique_ptr<object> copy (new object (icdr)); + +// Serialize to XML. +// +root (std::cout, *copy); +  </pre> + +  <p>The XSD distribution contains a number of examples that +     show how to save the object model to and load it from +     CDR, XDR, and a custom format.</p> + +  <!--  Appendix A --> + + +  <h1><a name="A">Appendix A — Default and Fixed Values</a></h1> + +  <p>The following table summarizes the effect of default and fixed +     values (specified with the <code>default</code> and <code>fixed</code> +     attributes, respectively) on attribute and element values. The +     <code>default</code> and <code>fixed</code> attributes are mutually +     exclusive. It is also worthwhile to note that the fixed value semantics +     is a superset of the default value semantics. +  </p> + +  <!-- border="1" is necessary for html2ps --> +  <table id="default-fixed" border="1"> +    <tr> +      <th></th> +      <th></th> +      <th colspan="2">default</th> +      <th colspan="2">fixed</th> +    </tr> + +    <!-- element --> + +    <tr> +      <th rowspan="4">element</th> +      <th rowspan="2">not present</th> +      <th>optional</th> +      <th>required</th> +      <th>optional</th> +      <th>required</th> +    </tr> +    <tr> +      <td>not present</td> +      <td>invalid instance</td> +      <td>not present</td> +      <td>invalid instance</td> +    </tr> + + +    <tr> +      <th>empty</th> +      <td colspan="2">default value is used</td> +      <td colspan="2">fixed value is used</td> +    </tr> + +    <tr> +      <th>value</th> +      <td colspan="2">value is used</td> +      <td colspan="2">value is used provided it's the same as fixed</td> +    </tr> + +    <!-- attribute --> + +    <!-- element --> + +    <tr> +      <th rowspan="4">attribute</th> +      <th rowspan="2">not present</th> +      <th>optional</th> +      <th>required</th> +      <th>optional</th> +      <th>required</th> +    </tr> +    <tr> +      <td>default value is used</td> +      <td>invalid schema</td> +      <td>fixed value is used</td> +      <td>invalid instance</td> +    </tr> + + +    <tr> +      <th>empty</th> +      <td colspan="2">empty value is used</td> +      <td colspan="2">empty value is used provided it's the same as fixed</td> +    </tr> + +    <tr> +      <th>value</th> +      <td colspan="2">value is used</td> +      <td colspan="2">value is used provided it's the same as fixed</td> +    </tr> + +  </table> + +  </div> +</div> + + +</body> +</html> diff --git a/doc/cxx/tree/manual/manual.html2ps.in b/doc/cxx/tree/manual/manual.html2ps.in new file mode 100644 index 0000000..5629122 --- /dev/null +++ b/doc/cxx/tree/manual/manual.html2ps.in @@ -0,0 +1,66 @@ +@@html2ps { +  option { +    toc: hb; +    colour: 1; +    hyphenate: 1; +    titlepage: 1; +  } + +  datefmt: "%B %Y"; + +  titlepage { +    content: " +<div align=center> +  <h1><big>C++/Tree Mapping User Manual</big></h1> +  <h1> </h1> +  <h1> </h1> +  <h1> </h1> +  <h1> </h1> +  <h1> </h1> +  <h1> </h1> +  <h1> </h1> +</div> +  <p>Revision $[revision]     $D</p> +  <p>Copyright © @copyright@.</p> + +  <p>Permission is granted to copy, distribute and/or modify this +     document under the terms of the +     <a href='https://www.codesynthesis.com/licenses/fdl-1.2.txt'>GNU Free +     Documentation License, version 1.2</a>; with no Invariant Sections, +     no Front-Cover Texts and no Back-Cover Texts. +  </p> + +  <p>This document is available in the following formats: +     <a href='https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/index.xhtml'>XHTML</a>, +     <a href='https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/cxx-tree-manual.pdf'>PDF</a>, and +     <a href='https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/cxx-tree-manual.ps'>PostScript</a>.</p>"; +  } + +  toc { +    indent: 2em; +  } + +  header { +    odd-right: $H; +    even-left: $H; +  } + +  footer { +    odd-left: $D; +    odd-center: $T, v$[revision]; +    odd-right: $N; + +    even-left: $N; +    even-center: $T, v$[revision]; +    even-right: $D; +  } +} + +body { +  font-size: 12pt; +  text-align: justify; +} + +pre { +  font-size: 10pt; +}  | 
