Sophie

Sophie

distrib > Mandriva > 2007.0 > i586 > media > contrib-release > by-pkgid > 9f5c7ae460878d5070e65a29704c26cd > files > 88

gsoap-2.7.8c-1mdv2007.0.i586.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>gSOAP level-2 DOM: The gSOAP level-2 DOM parser</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.3.8 -->
<div class="qindex"><a class="qindexHL" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="annotated.html">Class&nbsp;List</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Class&nbsp;Members</a> | <a class="qindex" href="globals.html">File&nbsp;Members</a></div>
<h1>The gSOAP level-2 DOM parser </h1>
<p>
The gSOAP level-2 DOM parser features "smart" XML namespace handling and can be used to mix gSOAP XML serializers with plain XML parsing. The DOM parser is also an essential component of the wsse plugin to verify digital signatures.<p>
The DOM parser is not a stand-alone application. The DOM parser is integrated with the SOAP engine to populate a node set and to render a node set in XML.<p>
Two files are needed to work with DOM node sets:<p>
<ul>
<li><a class="el" href="dom_8h.html">dom.h</a> to use a DOM node set in a gSOAP header file with service definitions.</li><li><a class="el" href="dom_8cpp.html">dom.cpp</a> (or dom.c) to be linked with your application code.</li></ul>
<h2><a class="anchor" name="dom_1">
Declaring DOM Node Sets in a gSOAP Header File</a></h2>
To use the DOM node set with the data structures defined in a gSOAP header file, import the <a class="el" href="dom_8h.html">dom.h</a> file into your header file:<p>
<div class="fragment"><pre><span class="preprocessor">    #import "<a class="code" href="dom_8h.html">dom.h</a>"</span>
</pre></div><p>
By importing <a class="el" href="dom_8h.html">dom.h</a> a special data type <a class="el" href="dom_8h.html#a0">xsd__anyType</a> is available that represents a hierarchical DOM node set. The DOM node set data structure can be used within structs, classes, STL containers, and as arguments of service operations. For example:<p>
<div class="fragment"><pre><span class="preprocessor">    #import "<a class="code" href="dom_8h.html">dom.h</a>"</span>
<span class="preprocessor">    #import "wsu.h"</span>
    <span class="keyword">class </span>ns__myProduct
    { <span class="keyword">public</span>:
        @<span class="keywordtype">char</span>*            wsu__Id;
        _wsu__Timestamp*  wsu__Timestamp;
        <span class="keywordtype">char</span>*             name;
        <span class="keywordtype">int</span>               SKU;
        <span class="keywordtype">double</span>            price;
        <a class="code" href="structsoap__dom__element.html">xsd__anyType</a>*     any;
                          ns__myProduct();
                          ~ns__myProduct();
    };
</pre></div><p>
It is important to declare the <a class="el" href="dom_8h.html#a0">xsd__anyType</a> at the end of the struct or class, since the DOM parser consumes any XML element (the field name, 'any' in this case, is irrelavant). Thus, the other fields must be defined first to ensure they are populated first before the DOM node set is populated with any non-previously matched XML element.<p>
Note that we also imported wsu.h as an example to show how to add a wsu:Id attribute to a struct or class if we want to digitally sign instances, and how to add a standardized wsu:Timestamp element to record creation and expiration times.<p>
To compile, run soapcpp2 (with -Iimport) and compile your code by linking <a class="el" href="dom_8cpp.html">dom.cpp</a> (or dom.c for C). Note that the DOM data structures are declared in <a class="el" href="stdsoap2_8h.html">stdsoap2.h</a>, while the DOM operations are defined in <a class="el" href="dom_8cpp.html">dom.cpp</a> (or dom.c for C).<p>
Methods to populate and traverse DOM node sets will be explained later. First, let's take a look at parsing and generating XML documents.<h2><a class="anchor" name="dom_2">
Parsing and Generating XML</a></h2>
The following examples assume that the soapcpp2 compiler was used on a header file (just the <a class="el" href="dom_8h.html">dom.h</a> file will do) and the generated soapC.cpp or (soapC.c for C) code was compiled and linked with <a class="el" href="dom_8cpp.html">dom.cpp</a> (or dom.c for C), stdsoap2.cpp (or stdsoap2.c) and the example application code. The generated namespace table should also be used, since the namespace bindings are relevant for consuming and producing XML for DOM node sets. Therefore, each of the example codes in this documentation is assumed to start with the following two includes:<p>
<div class="fragment"><pre><span class="preprocessor">    #include "soapH.h"</span>  <span class="comment">// generated by soapcpp2</span>
<span class="preprocessor">    #include "ns.nsmap"</span> <span class="comment">// a namespace table with the XML namespace used</span>
</pre></div><p>
The C++ std::iostream operators are overloaded to parse XML octet streams into node sets and to emit XML from node sets:<p>
<div class="fragment"><pre>    <a class="code" href="structsoap__dom__element.html">soap_dom_element</a> dom;
    dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a> = soap_new1(SOAP_DOM_TREE | SOAP_C_UTFSTRING);
    cin &gt;&gt; dom; <span class="comment">// parse XML</span>
    <span class="keywordflow">if</span> (dom.soap-&gt;error)
      ... <span class="comment">// parse error</span>
    cout &lt;&lt; dom; <span class="comment">// display XML</span>
    <span class="keywordflow">if</span> (dom.soap-&gt;error)
      ... <span class="comment">// output error</span>
    soap_destroy(dom.soap);
    soap_end(dom.soap);
    soap_done(dom.soap);
    free(dom.soap);
</pre></div><p>
In the example above we copied an XML document from stdin to stdout.<p>
In C we use the DOM "serializers" to accomplish this as follows:<p>
<div class="fragment"><pre>    <a class="code" href="structsoap__dom__element.html">soap_dom_element</a> dom;
    dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a> = soap_new1(SOAP_DOM_TREE | SOAP_C_UTFSTRING);
    dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a>-&gt;recvfd = stdin;
    <span class="keywordflow">if</span> (soap_begin_recv(dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a>)
     || NULL != <a class="code" href="dom_8cpp.html#a6">soap_in_xsd__anyType</a>(dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a>, NULL, &amp;dom, NULL)
     || soap_end_recv(dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a>))
      ... <span class="comment">// parse error</span>
    dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a>-&gt;sendfd = stdout;
    <span class="keywordflow">if</span> (soap_begin_send(dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a>)
     || <a class="code" href="dom_8cpp.html#a4">soap_out_xsd__anyType</a>(dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a>, NULL, 0, &amp;dom, NULL)
     || soap_end_send(dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a>))
      ... <span class="comment">// output error</span>
    soap_end(dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a>);
    soap_done(dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a>);
    free(dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a>);
</pre></div><p>
The SOAP_DOM_NODE flag is used to instruct the parser to populate a DOM node set with deserialized C and C++ data structures using the data type's deserializers that were generated with soapcpp2 from a header file with the data type declarations. Suppose for example that the following header file was used (in fact, this declaration appears in wsu.h):<p>
<div class="fragment"><pre>    <span class="keyword">typedef</span> <span class="keyword">struct </span>_wsu__Timestamp
    {   @<span class="keywordtype">char</span>*  wsu__Id;
        <span class="keywordtype">char</span>*   Created;
        <span class="keywordtype">char</span>*   Expires;
    } _wsu__Timestamp;
</pre></div><p>
Note that the leading underscore of the type name indicates an XML element definition (rather than a complexType definition), so the name of the data type is relevant when comparing XML element tags to C/C++ data types by the deserializers.<p>
When an XML document is parsed with one or more &lt;wsu:Timestamp&gt; elements, the DOM will be automatically populated with the _wsu__Timestamp objects. Suppose the XML document root is a &lt;wsu:Timestamp&gt;, then the root node of the DOM is a _wsu__Timestamp object:<p>
<div class="fragment"><pre>    <a class="code" href="structsoap__dom__element.html">soap_dom_element</a> dom;
    dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a> = soap_new1(SOAP_DOM_NODE);
    cin &gt;&gt; dom; <span class="comment">// parse XML</span>
    <span class="keywordflow">if</span> (dom.soap-&gt;error)
      ... <span class="comment">// parse error</span>
    <span class="keywordflow">if</span> (dom.type == SOAP_TYPE__wsu__Timestamp)
    { _wsu__Timestamp *t = (_wsu__Timestamp*)dom.<a class="code" href="structsoap__dom__element.html#o9">node</a>;
      cout &lt;&lt; <span class="stringliteral">"Start "</span> &lt;&lt; (t-&gt;Created ? t-&gt;Created : <span class="stringliteral">""</span>)
           &lt;&lt; <span class="stringliteral">" till "</span> &lt;&lt; (t-&gt;Expires ? t-&gt;Expires : <span class="stringliteral">""</span>) &lt;&lt; endl;
    }
</pre></div><p>
Note that the soapcpp2 compiler generates a unique type identification constant SOAP_TYPE_X for each data type X, which is used to determine the node's type in the example above.<p>
When objects occur deeper within the DOM node set then the DOM tree should be traversed. This subject will be discussed next.<h2><a class="anchor" name="dom_3">
Traversing a DOM Node Set</a></h2>
The DOM node set is traversed with a C++ iterator or with the C functions <a class="el" href="stdsoap2_8h.html#a1">soap_dom_next_element</a> and <a class="el" href="stdsoap2_8h.html#a2">soap_dom_next_attribute</a>. For example, to walk the node set visiting nodes in the same order as they appeared in the document, use:<p>
<div class="fragment"><pre>    <a class="code" href="structsoap__dom__element.html">soap_dom_element</a> dom;
    dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a> = soap_new1(SOAP_DOM_TREE | SOAP_C_UTFSTRING);
    ...
    <span class="keywordflow">for</span> (<a class="code" href="classsoap__dom__element__iterator.html">soap_dom_element::iterator</a> iter = dom.<a class="code" href="structsoap__dom__element.html#a7">begin</a>(); iter != dom.<a class="code" href="structsoap__dom__element.html#a8">end</a>(); ++iter)
      <span class="keywordflow">for</span> (<a class="code" href="classsoap__dom__attribute__iterator.html">soap_dom_attribute::iterator</a> attr = (*iter).atts.begin(); attr != (*iter).atts.end(); ++attr)
        ...
</pre></div><p>
In C code, use:<p>
<div class="fragment"><pre>    <a class="code" href="structsoap__dom__element.html">soap_dom_element</a> dom, *iter;
    <a class="code" href="structsoap__dom__attribute.html">soap_dom_attribute</a> *attr;
    dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a> = soap_new1(SOAP_DOM_TREE | SOAP_C_UTFSTRING);
    ...
    <span class="keywordflow">for</span> (iter = &amp;dom; iter; iter = <a class="code" href="dom_8cpp.html#a15">soap_dom_next_element</a>(iter))
      <span class="keywordflow">for</span> (attr = iter-&gt;<a class="code" href="structsoap__dom__element.html#o3">atts</a>; attr; attr = <a class="code" href="dom_8cpp.html#a16">soap_dom_next_attribute</a>(attr))
         ...
</pre></div><p>
The <a class="el" href="structsoap__dom__element.html">soap_dom_element</a> and <a class="el" href="structsoap__dom__attribute.html">soap_dom_attribute</a> structs form essentially linked lists, so it would not be too difficult to write your own tree walkers:<p>
<ul>
<li><a class="el" href="structsoap__dom__element.html#o1">soap_dom_element::prnt</a> points to the parent <a class="el" href="structsoap__dom__element.html">soap_dom_element</a> node.</li><li><a class="el" href="structsoap__dom__element.html#o2">soap_dom_element::elts</a> points to the linked list of child element nodes.</li><li><a class="el" href="structsoap__dom__element.html#o3">soap_dom_element::atts</a> points to the linked list of attribute nodes.</li></ul>
<p>
The linked lists of sibling elements nodes and attribute nodes are respectively:<p>
<ul>
<li><a class="el" href="structsoap__dom__element.html#o0">soap_dom_element::next</a> points to the next sibling element node.</li><li><a class="el" href="structsoap__dom__attribute.html#o0">soap_dom_attribute::next</a> points to the next attribute in the attribute list of an element node.</li></ul>
<p>
Note that for a root node, the <a class="el" href="structsoap__dom__element.html#o1">soap_dom_element::prnt</a> and <a class="el" href="structsoap__dom__element.html#o0">soap_dom_element::next</a> are both NULL.<p>
Tag names of elements and attributes are stored in <a class="el" href="structsoap__dom__element.html#o5">soap_dom_element::name</a> and <a class="el" href="structsoap__dom__attribute.html#o2">soap_dom_attribute::name</a> strings, respectively. The names are UTF-8 encoded.<p>
XML namespace bindings are explicitly propagated throughout the DOM node set for those elements and attributes that are namespace qualified (either with a namespace prefix or when they occur in a xmlns default namespace scope). The namespaces are stored in the <a class="el" href="structsoap__dom__element.html#o4">soap_dom_element::nstr</a> and <a class="el" href="structsoap__dom__attribute.html#o1">soap_dom_attribute::nstr</a> strings. The following example shows how to traverse a DOM node set and print the elements with their namespace URIs when present:<p>
<div class="fragment"><pre>    <a class="code" href="structsoap__dom__element.html">soap_dom_element</a> dom;
    dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a> = soap_new1(SOAP_DOM_TREE | SOAP_C_UTFSTRING);
    cin &gt;&gt; dom;
    <span class="keywordflow">for</span> (<a class="code" href="classsoap__dom__element__iterator.html">soap_dom_element::iterator</a> iter = dom.<a class="code" href="structsoap__dom__element.html#a7">begin</a>(); iter != dom.end(); ++iter)
    { cout &lt;&lt; <span class="stringliteral">"Element "</span> &lt;&lt; (*iter).<a class="code" href="classsoap__dom__element__iterator.html#o2">name</a>;
      <span class="keywordflow">if</span> ((*iter).nstr)
        cout &lt;&lt; <span class="stringliteral">" has namespace "</span> &lt;&lt; (*iter).nstr;
      cout &lt;&lt; endl;
    }
    soap_destroy(dom.soap);
    soap_end(dom.soap);
    soap_done(dom.soap);
    free(dom.soap);
</pre></div><p>
Text content of a node is stored in the <a class="el" href="structsoap__dom__element.html#o6">soap_dom_element::data</a> string in UTF-8 format. This string is populated if the SOAP_C_UTFSTRING flag was set. Otherwise the data content will be stored in the <a class="el" href="structsoap__dom__element.html#o7">soap_dom_element::wide</a> wide-character string.<p>
The following example prints those element nodes that have text content (in UTF-8 format):<p>
<div class="fragment"><pre>    <a class="code" href="structsoap__dom__element.html">soap_dom_element</a> dom;
    ...
    <span class="keywordflow">for</span> (<a class="code" href="classsoap__dom__element__iterator.html">soap_dom_element::iterator</a> iter = dom.<a class="code" href="structsoap__dom__element.html#a7">begin</a>(); iter != dom.<a class="code" href="structsoap__dom__element.html#a8">end</a>(); ++iter)
    { cout &lt;&lt; <span class="stringliteral">"Element "</span> &lt;&lt; (*iter).<a class="code" href="classsoap__dom__element__iterator.html#o2">name</a>;
      <span class="keywordflow">if</span> ((*iter).data)
        cout &lt;&lt; <span class="stringliteral">" = "</span> &lt;&lt; (*iter).data;
      cout &lt;&lt; endl;
    }
    ...
</pre></div><p>
When a DOM node set contains deserialized objects (enabled with the SOAP_DOM_NODE flag), the <a class="el" href="structsoap__dom__element.html#o8">soap_dom_element::type</a> and <a class="el" href="structsoap__dom__element.html#o9">soap_dom_element::node</a> values are set:<p>
<div class="fragment"><pre>    <a class="code" href="structsoap__dom__element.html">soap_dom_element</a> dom;
    ...
    <span class="keywordflow">for</span> (<a class="code" href="classsoap__dom__element__iterator.html">soap_dom_element::iterator</a> iter = dom.<a class="code" href="structsoap__dom__element.html#a7">begin</a>(); iter != dom.<a class="code" href="structsoap__dom__element.html#a8">end</a>(); ++iter)
    { cout &lt;&lt; <span class="stringliteral">"Element "</span> &lt;&lt; (*iter).<a class="code" href="classsoap__dom__element__iterator.html#o2">name</a>;
      <span class="keywordflow">if</span> ((*iter).type)
        cout &lt;&lt; <span class="stringliteral">"Element "</span> &lt;&lt; (*iter).name &lt;&lt; <span class="stringliteral">" contains a deserialized object"</span> &lt;&lt; endl;
      cout &lt;&lt; endl;
    }
    ...
</pre></div><p>
The <a class="el" href="structsoap__dom__element.html#o8">soap_dom_element::type</a> is 0 or a SOAP_TYPE_X constant, where X is the name of the deserialized type. The <a class="el" href="structsoap__dom__element.html#o9">soap_dom_element::node</a> points to the deserialized object. If this is a char* string, it points directly to the character sequence.<p>
Note: the SOAP_DOM_TREE flag restricts the parser to DOM content only, so deserializers is not used. When the SOAP_DOM_TREE flag is not used, an appropriate deserializer MAY be used by gSOAP when an element contains an id attribute and gSOAP can determine the type from the id attribute reference and/or the xsi:type attribute of an element.<h2><a class="anchor" name="dom_4">
Searching</a></h2>
Common operations on DOM node sets in level-2 DOM parsers are searching and filtering.<p>
For C++ code, the built-in <a class="el" href="structsoap__dom__element.html#w0">soap_dom_element::iterator</a> can be used to search for matching element nodes. C programmers are out of luck as they should write looping code to search for nodes explicitly.<p>
The <a class="el" href="structsoap__dom__element.html#a9">soap_dom_element::find</a> method returns a search iterator. The method takes an optional namespace URI and element name to match elements in the DOM node set. For example, to iterate over all "product" elements:<p>
<div class="fragment"><pre>    <a class="code" href="structsoap__dom__element.html">soap_dom_element</a> dom;
    ...
    <span class="keywordflow">for</span> (<a class="code" href="classsoap__dom__element__iterator.html">soap_dom_element::iterator</a> iter = dom.<a class="code" href="structsoap__dom__element.html#a9">find</a>(NULL, <span class="stringliteral">"product"</span>); iter != dom.<a class="code" href="structsoap__dom__element.html#a8">end</a>(); ++iter)
      cout &lt;&lt; <span class="stringliteral">"Element "</span> &lt;&lt; (*iter).<a class="code" href="classsoap__dom__element__iterator.html#o2">name</a> &lt;&lt; endl;
    ...
</pre></div><p>
To iterate over all elements in a particular namespace:<p>
<div class="fragment"><pre>    <a class="code" href="structsoap__dom__element.html">soap_dom_element</a> dom;
    ...
    <span class="keywordflow">for</span> (<a class="code" href="classsoap__dom__element__iterator.html">soap_dom_element::iterator</a> iter = dom.<a class="code" href="structsoap__dom__element.html#a9">find</a>(<span class="stringliteral">"http://www.w3.org/2001/XMLSchema"</span>, NULL); iter != dom.<a class="code" href="structsoap__dom__element.html#a8">end</a>(); ++iter)
      cout &lt;&lt; <span class="stringliteral">"Element "</span> &lt;&lt; (*iter).<a class="code" href="classsoap__dom__element__iterator.html#o2">name</a> &lt;&lt; endl;
    ...
</pre></div><p>
Since namespaces may have different version, a '*' wildcard can be used with the namespace string. Likewise, tag names may be namespace qualified with prefixes that are not relevant to the search:<p>
<div class="fragment"><pre>    <a class="code" href="structsoap__dom__element.html">soap_dom_element</a> dom;
    ...
    <span class="keywordflow">for</span> (<a class="code" href="classsoap__dom__element__iterator.html">soap_dom_element::iterator</a> iter = dom.<a class="code" href="structsoap__dom__element.html#a9">find</a>(<span class="stringliteral">"http://www.w3.org/*XMLSchema"</span>, <span class="stringliteral">"*:schema"</span>); iter != dom.<a class="code" href="structsoap__dom__element.html#a8">end</a>(); ++iter)
      cout &lt;&lt; <span class="stringliteral">"Element "</span> &lt;&lt; (*iter).<a class="code" href="classsoap__dom__element__iterator.html#o2">name</a> &lt;&lt; endl;
    ...
</pre></div><p>
This searches for qualified elements in one of the XSD namespaces.<h2><a class="anchor" name="dom_5">
Constructing DOM Node Sets</a></h2>
The <a class="el" href="structsoap__dom__element.html#a0">soap_dom_element::set</a> and <a class="el" href="structsoap__dom__element.html#a3">soap_dom_element::add</a> methods are used to decorate a DOM node set with child element nodes and attribute nodes. Application data with serializers can be incorporated in the node set as well.<p>
The following examples are shown in C++. C programmers can use the <a class="el" href="structsoap__dom__element.html">soap_dom_element</a>:elts list and soap_dom_elements::atts list to add child nodes and attribute nodes, respectively.<p>
<div class="fragment"><pre>    <a class="code" href="structsoap__dom__element.html">soap_dom_element</a> dom;
    dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a> = soap_new1(SOAP_C_UTFSTRING | SOAP_XML_INDENT);
    <span class="keyword">const</span> <span class="keywordtype">char</span> *myURI = <span class="stringliteral">"http://www.mydomain.com/myproducts"</span>;
    ns__myProduct product();
    product.soap_default(dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a>); <span class="comment">// method generated by soapcpp2</span>
    product.name = <span class="stringliteral">"Ernie"</span>;
    product.SKU = 123;
    product.price = 9.95;
    dom.<a class="code" href="structsoap__dom__element.html#a0">set</a>(myURI, <span class="stringliteral">"list"</span>);
    dom.<a class="code" href="structsoap__dom__element.html#a3">add</a>(<a class="code" href="structsoap__dom__attribute.html">soap_dom_attribute</a>(dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a>, myURI, <span class="stringliteral">"version"</span>, <span class="stringliteral">"0.9"</span>));
    dom.<a class="code" href="structsoap__dom__element.html#a3">add</a>(<a class="code" href="structsoap__dom__element.html">soap_dom_element</a>(dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a>, myURI, <span class="stringliteral">"documentation"</span>, <span class="stringliteral">"List of products"</span>));
    dom.<a class="code" href="structsoap__dom__element.html#a3">add</a>(<a class="code" href="structsoap__dom__element.html">soap_dom_element</a>(dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a>, myURI, <span class="stringliteral">"product"</span>, SOAP_TYPE_ns__myProduct, &amp;product);
    cout &lt;&lt; dom;
    ...
</pre></div><p>
Assuming that myURI is associated with namespace prefix "ns" in the namespace table, the rendition is<p>
<div class="fragment"><pre>&lt;?xml version=<span class="stringliteral">"1.0"</span> encoding=<span class="stringliteral">"UTF-8"</span>?&gt;
&lt;ns:list
  xmlns:SOAP-ENV=<span class="stringliteral">"http://schemas.xmlsoap.org/soap/envelope/"</span>
  xmlns:SOAP-ENC=<span class="stringliteral">"http://schemas.xmlsoap.org/soap/encoding/"</span>
  xmlns:xsi=<span class="stringliteral">"http://www.w3.org/2001/XMLSchema-instance"</span>
  xmlns:xsd=<span class="stringliteral">"http://www.w3.org/2001/XMLSchema"</span>
  xmlns:ns=<span class="stringliteral">"http://domain/schemas/product.xsd"</span>
  version=<span class="stringliteral">"0.9"</span> &gt;
        &lt;ns:documentation&gt;List of products&lt;/ns:documentation&gt;
        &lt;ns:product&gt;
                &lt;name&gt;Ernie&lt;/name&gt;
                &lt;SKU&gt;123&lt;/SKU&gt;
                &lt;price&gt;9.95&lt;/price&gt;
        &lt;/ns:product&gt;
&lt;/ns:list&gt;
</pre></div><p>
Note that the namespace table content is "dumped" into the XML rendition.<p>
The global namespace mapping table "namespaces[]" contains the namespace bindings that should be meaningful to the application. The soap context can be set to a new table as follows:<p>
<div class="fragment"><pre>    Namespace myNamespaces[] = { { <span class="stringliteral">"ns"</span>, <span class="stringliteral">"..."</span> }, ... , { NULL } };
    <a class="code" href="structsoap__dom__element.html">soap_dom_element</a> dom;
    dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a> = soap_new1(SOAP_C_UTFSTRING | SOAP_XML_INDENT);
    dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a>-&gt;namespaces = myNamespaces;
</pre></div><p>
To produce cleaner XML, use the SOAP_XML_CANONICAL flag to initiate the soap context:<p>
<div class="fragment"><pre>&lt;ns:list xmlns:ns=<span class="stringliteral">"http://domain/schemas/product.xsd"</span> version=<span class="stringliteral">"0.9"</span> &gt;
        &lt;ns:documentation&gt;List of products&lt;/ns:documentation&gt;
        &lt;ns:product&gt;
                &lt;name&gt;Ernie&lt;/name&gt;
                &lt;SKU&gt;123&lt;/SKU&gt;
                &lt;price&gt;9.95&lt;/price&gt;
        &lt;/ns:product&gt;
&lt;/ns:list&gt;
</pre></div><p>
Note that the xmlns bindings are rendered automatically. When parsing an XML document, xmlns bindings are not added to the attribute node set. The <a class="el" href="structsoap__dom__element.html#o4">soap_dom_element::nstr</a> and <a class="el" href="structsoap__dom__attribute.html#o1">soap_dom_attribute::nstr</a> namespace strings are set to retain namespace URIs. The XML rendering algorithm uses the namespace strings to add xmlns bindings that are not already in the namespace table.<p>
When it is desirable to render XML exactly as represented in the DOM node set, e.g. when xmlns bindings are explicitly included in the attribute node set, use the SOAP_DOM_ASIS flag:<p>
<div class="fragment"><pre>    <a class="code" href="structsoap__dom__element.html">soap_dom_element</a> dom;
    dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a> = soap_new1(SOAP_C_UTFSTRING | SOAP_DOM_ASIS);
</pre></div><h2><a class="anchor" name="dom_6">
Example</a></h2>
The gSOAP header file below imports DOM and declares xsd:float to enable serializing floats embedded within DOM node sets and deserializing floats to populate DOM node sets:<p>
<div class="fragment"><pre><span class="preprocessor">    #import "<a class="code" href="dom_8h.html">dom.h</a>"</span>
    <span class="keyword">typedef</span> <span class="keywordtype">float</span> xsd__float;
</pre></div><p>
Consider invoking the XMethods delayed stock quote service to obtain a stock quote. The float deserializer is used to store the floating-point value of a stock given that the &lt;result&gt; element has an xsi:type="xsd:float" attribute.<p>
<div class="fragment"><pre>    <span class="keyword">struct </span>soap *soap = soap_new1(SOAP_C_UTFSTRING | SOAP_DOM_NODE);
    <a class="code" href="structsoap__dom__element.html">soap_dom_element</a> envelope(soap, <span class="stringliteral">"http://schemas.xmlsoap.org/soap/envelope/"</span>, <span class="stringliteral">"Envelope"</span>);
    <a class="code" href="structsoap__dom__element.html">soap_dom_element</a> body(soap, <span class="stringliteral">"http://schemas.xmlsoap.org/soap/envelope/"</span>, <span class="stringliteral">"Body"</span>);
    <a class="code" href="structsoap__dom__attribute.html">soap_dom_attribute</a> encodingStyle(soap, <span class="stringliteral">"http://schemas.xmlsoap.org/soap/envelope/"</span>, <span class="stringliteral">"encodingStyle"</span>, <span class="stringliteral">"http://schemas.xmlsoap.org/soap/encoding/"</span>);
    <a class="code" href="structsoap__dom__element.html">soap_dom_element</a> request(soap, <span class="stringliteral">"urn:xmethods-delayed-quotes"</span>, <span class="stringliteral">"getQuote"</span>);
    <a class="code" href="structsoap__dom__element.html">soap_dom_element</a> symbol(soap, NULL, <span class="stringliteral">"symbol"</span>, <span class="stringliteral">"IBM"</span>);
    <a class="code" href="structsoap__dom__element.html">soap_dom_element</a> response(soap);
    envelope.add(body);
    body.add(encodingStyle);
    body.add(request);
    request.add(symbol);
    cout &lt;&lt; <span class="stringliteral">"Request message:"</span> &lt;&lt; endl &lt;&lt; envelope &lt;&lt; endl;
    <span class="keywordflow">if</span> (soap_connect(soap, <span class="stringliteral">"http://services.xmethods.net/soap"</span>, <span class="stringliteral">""</span>)
     || <a class="code" href="dom_8cpp.html#a4">soap_out_xsd__anyType</a>(soap, NULL, 0, &amp;envelope, NULL)
     || soap_end_send(soap)
     || soap_begin_recv(soap)
     || NULL != <a class="code" href="dom_8cpp.html#a6">soap_in_xsd__anyType</a>(soap, NULL, &amp;response, NULL)
     || soap_end_recv(soap)
     || soap_closesock(soap))
    { soap_print_fault(soap, stderr);
      soap_print_fault_location(soap, stderr);
    }
    <span class="keywordflow">else</span>
    { cout &lt;&lt; <span class="stringliteral">"Response message:"</span> &lt;&lt; endl &lt;&lt; response &lt;&lt; endl;
      <span class="keywordflow">for</span> (<a class="code" href="classsoap__dom__element__iterator.html">soap_dom_element::iterator</a> walker = response.find(SOAP_TYPE_xsd__float); walker != response.end(); ++walker)
        cout &lt;&lt; <span class="stringliteral">"Quote = "</span> &lt;&lt; *(xsd__float*)(*walker).node &lt;&lt; endl;
    }
    soap_destroy(soap);
    soap_end(soap);
    soap_done(soap);
    free(soap);
</pre></div><h2><a class="anchor" name="dom_7">
Summary</a></h2>
The DOM parser needs a soap context to allocate nodes:<p>
<div class="fragment"><pre>    <a class="code" href="structsoap__dom__element.html">soap_dom_element</a> dom;
    dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a> = soap_new1(... flags ...);
    ...
    soap_destroy(dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a>);
    soap_end(dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a>);
    soap_done(dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a>);
    soap_free(dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a>);
</pre></div><p>
The nodes are removed with soap_destroy (for C++) and soap_end. The soap_done function should only be used before the soap context is deallocated.<p>
The soap context flags that control the parsing and rendition of XML are:<p>
<ul>
<li>(no flag): only elements with an id attribute are deserialized as C/C++ data types (when a deserializer is available). XML elements with character data are deserialized into the <a class="el" href="structsoap__dom__element.html#o7">soap_dom_element::wide</a> field.</li><li>SOAP_C_UTFSTRING: store character data in UTF-8 format in <a class="el" href="structsoap__dom__element.html#o6">soap_dom_element::data</a>.</li><li>SOAP_C_MBSTRING: store character data in multi-byte format in <a class="el" href="structsoap__dom__element.html#o6">soap_dom_element::data</a>, where the decoding depends on the current localication. The platform must support MB strings (HAVE_MBTOWC).</li><li>SOAP_DOM_TREE: prevents deserialization of C/C++ data structures into the DOM.</li><li>SOAP_DOM_NODE: attempt to deserialize C/C++ data structures when a deserializer is available. A deserializer is selected based on the element name or the xsi:type attribute.</li><li>SOAP_DOM_ASIS: render XML "as is", i.e. do not insert xmlns bindings for URIs stored in nstr. Assumes the DOM is self-contained.</li><li>SOAP_XML_INDENT: render XML with indent.</li><li>SOAP_XML_CANONICAL: render XML in exc-c14n form.</li></ul>
<p>
The DOM traversal operations:<p>
<ul>
<li><a class="el" href="stdsoap2_8h.html#a1">soap_dom_next_element</a> returns the next element in an in-order traversal.</li><li><a class="el" href="stdsoap2_8h.html#a2">soap_dom_next_attribute</a> returns the next attribute of a node.</li></ul>
<p>
The <a class="el" href="structsoap__dom__element.html">soap_dom_element</a> fields:<p>
<ul>
<li><a class="el" href="structsoap__dom__element.html#o0">soap_dom_element::next</a> pointer to next sibling in list.</li><li><a class="el" href="structsoap__dom__element.html#o1">soap_dom_element::prnt</a> pointer to parent node.</li><li><a class="el" href="structsoap__dom__element.html#o2">soap_dom_element::elts</a> pointer to list of child element nodes.</li><li><a class="el" href="structsoap__dom__element.html#o3">soap_dom_element::atts</a> pointer to list of attribute nodes.</li><li><a class="el" href="structsoap__dom__element.html#o4">soap_dom_element::nstr</a> optional namespace string of this node.</li><li><a class="el" href="structsoap__dom__element.html#o5">soap_dom_element::name</a> the name of the element node (with optional prefix).</li><li><a class="el" href="structsoap__dom__element.html#o6">soap_dom_element::data</a> optional character data in UTF-8 format.</li><li><a class="el" href="structsoap__dom__element.html#o7">soap_dom_element::wide</a> optional character data in wide string format.</li><li><a class="el" href="structsoap__dom__element.html#o8">soap_dom_element::type</a> optional SOAP_TYPE_X type of a C/C++ data structure stored with this node.</li><li><a class="el" href="structsoap__dom__element.html#o9">soap_dom_element::node</a> optional pointer to the C/C++ data structure stored with this node.</li><li><a class="el" href="structsoap__dom__element.html#o10">soap_dom_element::head</a> optional leading whitespace to the start tag.</li><li><a class="el" href="structsoap__dom__element.html#o11">soap_dom_element::tail</a> optional leading whitespace to the end tag.</li><li><a class="el" href="structsoap__dom__element.html#o12">soap_dom_element::soap</a> the soap context that manages this node.</li></ul>
<p>
The <a class="el" href="structsoap__dom__element.html">soap_dom_element</a> types:<p>
<ul>
<li><a class="el" href="structsoap__dom__element.html#w0">soap_dom_element::iterator</a></li></ul>
<p>
The <a class="el" href="structsoap__dom__element.html">soap_dom_element</a> methods:<p>
<ul>
<li><a class="el" href="structsoap__dom__element.html#a0">soap_dom_element::set</a>(nstr, name);</li><li><a class="el" href="structsoap__dom__element.html#a0">soap_dom_element::set</a>(data);</li><li><a class="el" href="structsoap__dom__element.html#a0">soap_dom_element::set</a>(node, type);</li><li><a class="el" href="structsoap__dom__element.html#a3">soap_dom_element::add</a>(<a class="el" href="structsoap__dom__element.html">soap_dom_element</a>);</li><li><a class="el" href="structsoap__dom__element.html#a3">soap_dom_element::add</a>(<a class="el" href="structsoap__dom__attribute.html">soap_dom_attribute</a>);</li><li><a class="el" href="structsoap__dom__element.html#a7">soap_dom_element::begin</a>();</li><li><a class="el" href="structsoap__dom__element.html#a8">soap_dom_element::end</a>();</li><li><a class="el" href="structsoap__dom__element.html#a9">soap_dom_element::find</a>(nstr, name);</li><li><a class="el" href="structsoap__dom__element.html#a9">soap_dom_element::find</a>(type);</li><li><a class="el" href="structsoap__dom__element.html#a11">soap_dom_element::unlink</a>();</li></ul>
<p>
The <a class="el" href="structsoap__dom__element.html">soap_dom_element</a> constructors:<p>
<ul>
<li><a class="el" href="structsoap__dom__element.html">soap_dom_element</a>();</li><li><a class="el" href="structsoap__dom__element.html">soap_dom_element</a>(soap);</li><li><a class="el" href="structsoap__dom__element.html">soap_dom_element</a>(soap, nstr, name);</li><li><a class="el" href="structsoap__dom__element.html">soap_dom_element</a>(soap, nstr, name, data);</li><li><a class="el" href="structsoap__dom__element.html">soap_dom_element</a>(soap, nstr, name, node, type);</li></ul>
<p>
The <a class="el" href="structsoap__dom__attribute.html">soap_dom_attribute</a> fields:<p>
<ul>
<li><a class="el" href="structsoap__dom__attribute.html#o0">soap_dom_attribute::next</a> pointer to next attribute node in list.</li><li><a class="el" href="structsoap__dom__attribute.html#o1">soap_dom_attribute::nstr</a> optional namespace string of this node.</li><li><a class="el" href="structsoap__dom__attribute.html#o2">soap_dom_attribute::name</a> the name of the attribute (with optional prefix).</li><li><a class="el" href="structsoap__dom__attribute.html#o3">soap_dom_attribute::data</a> optional character data in UTF-8 format.</li><li><a class="el" href="structsoap__dom__attribute.html#o5">soap_dom_attribute::soap</a> the soap context that manages this node.</li></ul>
<p>
The <a class="el" href="structsoap__dom__attribute.html">soap_dom_attribute</a> types:<p>
<ul>
<li><a class="el" href="structsoap__dom__attribute.html#w0">soap_dom_attribute::iterator</a></li></ul>
<p>
The <a class="el" href="structsoap__dom__attribute.html">soap_dom_attribute</a> methods:<p>
<ul>
<li><a class="el" href="structsoap__dom__attribute.html#a0">soap_dom_attribute::set</a>(nstr, name);</li><li><a class="el" href="structsoap__dom__attribute.html#a0">soap_dom_attribute::set</a>(data);</li><li><a class="el" href="structsoap__dom__attribute.html#a2">soap_dom_attribute::begin</a>();</li><li><a class="el" href="structsoap__dom__attribute.html#a3">soap_dom_attribute::end</a>();</li><li><a class="el" href="structsoap__dom__attribute.html#a4">soap_dom_attribute::find</a>(nstr, name);</li><li><a class="el" href="structsoap__dom__attribute.html#a5">soap_dom_attribute::unlink</a>();</li></ul>
<p>
The <a class="el" href="structsoap__dom__attribute.html">soap_dom_attribute</a> constructors:<p>
<ul>
<li><a class="el" href="structsoap__dom__attribute.html">soap_dom_attribute</a>();</li><li><a class="el" href="structsoap__dom__attribute.html">soap_dom_attribute</a>(soap);</li><li><a class="el" href="structsoap__dom__attribute.html">soap_dom_attribute</a>(soap, nstr, name, data); </li></ul>
<hr size="1"><address style="align: right;"><small>Generated on Sat Aug 20 12:24:36 2005 for gSOAP level-2 DOM by
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border=0 ></a> 1.3.8 </small></address>
</body>
</html>