Sophie

Sophie

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

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="qindex" 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> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
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 invokes the SOAP engine to populate a node set and to render a node set in XML.<h2><a class="anchor" name="dom_1">
Using DOM Node Sets in a gSOAP Header File</a></h2>
To use the DOM node set in a data structure defined in a gSOAP header file, import the <a class="el" href="dom_8h.html">dom.h</a> file into the 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. DOM nodes can be used with structs, classes, STL containers, and as arguments of service operations in your gSOAP header file declarations. 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 that we add <a class="el" href="dom_8h.html#a0">xsd__anyType</a> at the end of the struct or class, since it 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 to use the wsu:Id attribute in case we want to digitally sign product instances and a wsu:Created timestamp element to record creation and expiration times.<p>
To compile, run soapcpp2 (with -Iimport) and compile your code by linking dom.cpp (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 dom.cpp (or dom.c).<h2><a class="anchor" name="dom_2">
Populating a DOM Node Set</a></h2>
When a structure with a DOM node set (as shown in the example in the previous section) is deserialized, the node set is automatically populated.<p>
In addition, the C++ iostream operators are overloaded to parse and display XML of a node set:<p>
<div class="fragment"><pre>    <span class="keyword">struct </span>soap *soap = soap_new();
    <a class="code" href="structsoap__dom__element.html">soap_dom_element</a> dom(soap);
    cin &gt;&gt; dom; <span class="comment">// parse XML</span>
    <span class="keywordflow">if</span> (soap.error)
      ... <span class="comment">// parse error</span>
    cout &lt;&lt; dom; <span class="comment">// display XML</span>
</pre></div><p>
In C we use the DOM "serializers" as follows:<p>
<div class="fragment"><pre>    <span class="keyword">struct </span>soap *soap = soap_new();
    <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;
    soap-&gt;recvfd = stdin;
    <span class="keywordflow">if</span> (soap_begin_recv(soap)
     || soap_in_xsd__anyType(soap, NULL, &amp;dom, NULL) != NULL
     || soap_end_recv(soap))
      ... <span class="comment">// parse error</span>
    soap-&gt;sendfd = stdout;
    <span class="keywordflow">if</span> (soap_begin_send(soap)
     || soap_out_xsd__anyType(soap, NULL, 0, &amp;dom, NULL)
     || soap_end_send(soap))
      ... <span class="comment">// send error</span>
</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 generated with soapcpp2. Suppose for example that the following header file was used (in fact, the declaration appears in wsu.h):<p>
<div class="fragment"><pre>    <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;
    };
</pre></div><p>
Note that the leading underscore of the type name indicate XML element definitions (rather than complexTypes), so the name of the data type is relevant when comparing XML element tags to C/C++ data types by the deserializers.<p>
When a &lt;wsu:Timestamp&gt; element appears in XML, the DOM node will be automatically populated with the _wsu__Timestamp object using the SOAP_DOM_NODE flag:<p>
<div class="fragment"><pre>    <span class="keyword">struct </span>soap *soap = soap_new1(SOAP_DOM_NODE);
    <a class="code" href="structsoap__dom__element.html">soap_dom_element</a> dom(soap);
    cin &gt;&gt; dom; <span class="comment">// parse XML</span>
    <span class="keywordflow">if</span> (soap.error)
      ... <span class="comment">// parse error</span>
</pre></div><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 over the node set with an in-order traversal use:<p>
<div class="fragment"><pre>    <span class="keyword">struct </span>soap *soap = soap_new();
    <a class="code" href="structsoap__dom__element.html">soap_dom_element</a> dom(soap);
    ...
    <span class="keywordflow">for</span> (<a class="code" href="classsoap__dom__iterator.html">soap_dom_element::iterator</a> walker = dom.begin(); walker != dom.end(); ++walker)
      ...
</pre></div><p>
In C, use<p>
<div class="fragment"><pre>    <span class="keyword">struct </span>soap *soap = soap_new();
    <a class="code" href="structsoap__dom__element.html">soap_dom_element</a> dom, *walker;
    dom.<a class="code" href="structsoap__dom__element.html#o12">soap</a> = soap;
    ...
    <span class="keywordflow">for</span> (walker = &amp;dom; walker; walker = <a class="code" href="stdsoap2_8h.html#a1">soap_dom_next_element</a>(walker))
      ...
</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 is not too difficult to write your own tree walkers.<h2><a class="anchor" name="dom_4">
Searching and filtering a DOM Node Set</a></h2>
<h2><a class="anchor" name="dom_5">
Using a DOM with Embedded Application Data</a></h2>
<h2><a class="anchor" name="dom_6">
Tips and Tricks</a></h2>
DOM element nodes and attribute nodes can have an optional namespace names. The namespace prefix and name bindings (xmlns in XML) are automatically resolved.<p>
The DOM elements can be used anywhere within a C/C++ data structure and also as the arguments to a service method. For example: struct SOAP_ENV__Header { xsd__anyType *authentication; }; int ns__test(xsd__anyType in, xsd__anyType *out); which defines a custom SOAP Header with an authentication element parsed as a DOM.<p>
DOM node fields: prnt pointer to parent node elts list of child elements (list of DOM nodes) atts list of attributes const char *nstr optional element namespace name (URI) char *name element name with optional ns: prefix char *data optional element data (see comment below) wchar_t *wide optional element data (see comment below) int type optional type SOAP_TYPE_X as defined in soapH.h void *node and optional pointer to C/C++ data type char *head leading whitespace to start tag (render only) char *tail leading whitespace to end tag (render only) soap the context that manages this instance<p>
DOM Parsing: The namespace name (URI) parsing is smart and fills the 'nstr' field with the namespace URIs. The algorithm checks the names in the nsmap table first. After parsing, the 'nstr' namespace strings will point to the nsmap table contents in case the names (URIs) match a table entry. Otherwise, the names are dynamically allocated. This enables quick pointer-based checks on the DOM node's namespace names by comparing the pointer to the namespace table entries 'namespaces[i].ns'.<p>
Character data parsing: The parser fills the 'wide' string fields of the DOM nodes only (the 'wide' fields contain Unicode XML cdata), unless the input-mode flag SOAP_C_UTFSTRING or SOAP_C_MBSTRING is set using soap_init2() or soap_set_imode(). In that case the 'data' fields are set with UTF8 contents or multibyte character strings.<p>
The following input-mode flags (set with soap_set_imode()) control the parsing of C/C++ data types (stored in the 'node' and 'type' fields):<p>
default: only elements with an 'id' attribute are deserialized as C/C++ data types (when a deserializer is available) SOAP_DOM_TREE: never deserialize C/C++ types (produces DOM tree) SOAP_DOM_NODE: always deserialize C/C++ types (when a deserializer is available and the xsi:type attribute is present in the XML node or the XML element tag matches the type name) SOAP_DOM_ASIS: never insert xmlns bindings for URIs stored in nstr, but assume the DOM is self-contained<p>
The following output-mode flag (set with soap_set_omode()) controls the serialization of XML:<p>
SOAP_XML_INDENT: serialize XML with indentation SOAP_XML_CANONICAL: serialize XML in canonical form<p>
The entire deserialized DOM is freed with soap_destroy(DOM.soap); soap_end(DOM.soap);<p>
Examples (XML parsing and generation):<p>
struct soap *soap = soap_new(); xsd__anyType dom(soap); // need a soap struct to parse XML using '&gt;&gt;' cin &gt;&gt; dom; // parse XML if (soap-&gt;error) ... input error ... soap_destroy(soap); // delete DOM soap_end(soap); // delete data soap_done(soap); // finalize free(soap);<p>
struct soap *soap = soap_new(); xsd__anyType dom(soap, ...); // populate the DOM cout &lt;&lt; dom; // print if (soap-&gt;error) ... output error ... soap_destroy(soap); // clean up objects soap_end(soap); // clean up soap_done(soap); // finalize free(soap);<p>
To retain the DOM but remove all other data, use: dom.unlink();<p>
Compile: soapcpp2 <a class="el" href="dom_8h.html">dom.h</a> g++ -c dom.cpp<p>
To use a DOM in your Web service application, add to the gSOAP header file that defines your service: #import "dom.h" Then use the xsd__anyType to refer to the DOM in your data structures.<p>
Link the application with dom.o <hr size="1"><address style="align: right;"><small>Generated on Wed Aug 17 20:55:54 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>