<!-- ** using the xml parser

     $Id: sect_xml_parser.docbook 801 2005-07-17 12:56:42Z ewald-arnold $
-->

<sect1 id="xml-parser">
<title>Using the &xml; Parser</title>

<para>&ulxmlrpcpp; uses <systemitem class="library">expat</systemitem> as parser
for &xml;. Additionally there are some helper classes. One of them forms a C++ wrapper to the
C-functions in <systemitem class="library">expat</systemitem> and one supports
parsing using a simple state machine. Nested &xml; elements
are modeled by deriving parser classes: "outer" elements derive from "inner"
elements.</para>

<para>Parsing of a start tag is done in the following steps:

<procedure>
  <step>Check if the current object is able to handle the current element</step>
  <step>Otherwise delegate to the parent (which may as well call the former parent)</step>
  <step>Process the current element and remember the state for later use on a stack</step>
</procedure>

</para>

<para>Character data between the &xml; tags is stored for later use.</para>

<para>An ending tag is handled similarly:

<procedure>
  <step>Check if the current object is able to handle the current element</step>
  <step>Otherwise delegate to the parent</step>
  <step>Check for a well formed document (current tag matches element on the stack).
  Process stored character data.</step>
</procedure>

</para>

<para>For examples on the working method see the various *parse.cpp files.</para>

<caution>
  <title>There is one pitfall:</title>
  <para>
   <calloutlist>
     <callout id="xml-push-link" arearefs="xml-push-co">
      <para>The first constructor in a chain of derived parsers must push an
      appropriate element onto the state stack because the parser methods rely
      upon being able to retrieve information about the current state.</para>
    </callout>

    <callout id="xml-clean-link" arearefs="xml-clean-co">
     <para>The destructor on the other hand must clean up
     the stack.</para>
    </callout>

   </calloutlist>


  <programlisting>

  ValueParser::ValueParser()
  {
    states.push(new ValueState(eNone)); <co  id="xml-push-co" linkends="xml-push-link" />
  }

  ValueParser::~ValueParser()
  {
    while (states.size() != 0)<co  id="xml-clean-co" linkends="xml-clean-link" />
    {
      delete getTopValueState()->getValue();
      delete getTopValueState();
      states.pop();
    }
  }

  </programlisting>

  </para>

</caution>

</sect1>
