File: index.html

package info (click to toggle)
libzeep 5.1.8-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 3,596 kB
  • sloc: cpp: 27,393; xml: 7,798; javascript: 180; sh: 37; makefile: 8
file content (270 lines) | stat: -rw-r--r-- 10,619 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title>libzeep documentation</title>
    <meta name="author" content="Maarten L. Hekkelman" />
    <meta name="generator" content="Japi" />
	<link rel="stylesheet" type="text/css" href="zeep.css" />
	<!-- Date:		 zondag 11 april, 2010 -->
</head>
<body>
	<h2>Contents</h2>
	<ul>
		<li><a href="#intro">Introduction</a></li>
		<li><a href="#examples">Examples</a></li>
		<li><a href="#reference">Reference</a></li>
	</ul>



	<a name="intro"/>
	<h2>Introduction</h2>

	<h3>The XML library</h3>

	<p>libzeep is a library that consists of two main parts. The first and arguably most useful for many is the XML processing part. It consists of a SAX parser, a DOM implementation, an XML writing module and an XPath implementation. The parser can act as a validating parser using the Document Type Definition to check the content. Schema support is not yet implemented but will be in a future release.
	</p>

	<p>The second part of libzeep (and the part it all started with, hence the name) is a skeleton to build SOAP server implementations. It uses the XML part as well as various <a href="http://www.boost.org">Boost</a> libraries to achieve its usefulness. It allows the creation of a SOAP server by implementing only the serving routines in C++ and calling a routine for each to export of them. Code is then automatically generated to do all the SOAP message parsing and WSDL's generation occurs on-the-fly at runtime.
	</p>

	<p>libzeep comes with headers and libraries. The headers all have <code>zeep</code> as namespace. All code heavily depends on the boost libraries.
	</p>


	<a name="examples"/>
	<h2>Examples</h2>

	<p>Using libzeep is fairly straightforward. E.g., if we take the following XML file:
	</p>

	<pre>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;employees&gt;
  &lt;employee&gt;
    &lt;name id="1"&gt;Joe Doe&lt;/name&gt;
    &lt;address&gt;Main street&lt;/address&gt;
  &lt;/employee&gt;
  &lt;employee&gt;
    &lt;name id="2"&gt;Jack Daniels&lt;/name&gt;
    &lt;address&gt;Backstreet&lt;/address&gt;
  &lt;/employee&gt;
&lt;/employees&gt;</pre>

	<p>Reading this file is simple:
	</p>

<pre>#include &lt;zeep/xml/document.hpp&gt;

using namespace zeep;
using namespace std;

ifstream data("/tmp/myfile.xml");
xml::document doc;
data >> doc;
</pre>

	<p>The result of this code is a DOM tree with <code>doc</code> as root. An <code>xml::document</code> is derived from <code>xml::element</code> and can only have one <code>xml::element</code> child. Since it is a DOM tree, and since it is implemented in the classic link-list approach, you can use the <code>next()</code>, <code>prev()</code>, <code>parent()</code> and <code>child()</code> methods to navigate the tree.
	</p>

	<p>But to stick to STL coding styles, walking a tree can also be done using the <code>children()</code> method which returns a <code>std::list</code> of pointers to its children. This method is templated since an element can have non-element child nodes like comments and processing instruction but most often you're only interested in the element child nodes.
	</p>

	<p>Using the <code>children</code> method, iterating over all employees can be done like this:</p>

<pre><span class="comment">// iterate over employees</span>
xml::element_set employees = doc.root()->children&lt;xml::element&gt;();
for (xml::element_set::iterator employee = employees.begin(); employee != employees.end(); ++employee)
{
	<span style="comment">// employee points to an element and we want its first child</span>
	xml::element* name = (*employee)->child();
	<span style="comment">// it really should be a name, right?</span>
	assert(name->qname() == "name");
    cout &lt;&lt; "Name: " &lt;&lt; name->content() &lt;&lt; endl;
}
</pre>

	<p>Of course, using Boost's foreach this looks a lot nicer:</p>

<pre><span class="comment">// iterate over employees, boost foreach style</span>
#include &lt;boost/foreach.hpp&gt;
#define foreach BOOST_FOREACH

...

for (xml::element* employee, doc.root()->children&lt;xml::element&gt;())
{
	xml::element* name = (*employee)->child();
	...
}
</pre>

	<p>Still, we can do better. Using XPaths. Just like the <code>children()</code> method of <code>xml::element</code> the xpath evaluation method returns all nodes, if you're only interested in <code>xml::element</code> nodes, you can specify this.</p>

<pre>#include &lt;boost/foreach.hpp&gt;
#define foreach BOOST_FOREACH

...

xpath p("//employee/name");

for (xml::element* name, p.evaluate&lt;xml::element&gt;(doc))
{
    cout &lt;&lt; "Name: " &lt;&lt; name->content() &lt;&lt; endl;
}
</pre>

	<p>The <code>find</code> method of <code>xml::element</code> is a shortcut to <code>xpath::evaluate()</code>, it always returns <code>xml::element</code> nodes.</p>

<pre>for (xml::element* name = doc.find("//employee/name"))
    cout &lt;&lt; "Name: " &lt;&lt; name->content() &lt;&lt; endl;
</pre>

	<p>The XPath implementation in libzeep implements the full XPath 1.0 specification. That means you can also do this:

<pre>// Fetch Jack's record by name:
xml::element* jack = doc.find_first("//employee[name = 'Jack Daniels']");

// or by id:
jack = doc.find_first("//employee[@id='2']");

// or by position in the list, jack is always last...
jack = doc.find_first("//employee[position() = last()]");
</pre>

	<p>You can even use variables:</p>

<pre>// Fetch Jack's record by name:
xml::context context;
context.set("var", "Jack Daniels");
xml::xpath xpath("//employee[name = $var]");

xml::element* jack = xpath.evaluate(*doc.root(), context).front();
</pre>

	<h3>SOAP server</h3>

	<p>This comes from the man page for the 1.0 version of libzeep. I'll have to improve this one day:</p>

<pre>libzeep(3)                        subroutine                        libzeep(3)



NAME
       libzeep - A C++ library to create SOAP servers

SYNOPSIS
       #include &lt;zeep/server.hpp&gt;

       class my_server : public zeep::server
       {
         public:
           my_server(const char* addr, short port);
           void sum(int a, int b, int&amp; c) { c = a + b; }
       };

       my_server::my_server(const char* addr, short port)
         : zeep::server("http//www.acme.org/...", addr, port)
       {
         const char kSumParameterNames[] = { "a", "b", "c" };
         register_action("sum", this, &amp;my_server::sum, kSumParameterNames);
       }

        ...

       my_server server("0.0.0.0", 10333);
       boost::thread t(boost::bind(&amp;my_server::run, &amp;server));
       // and wait for a signal to stop using e.g. sigwait(3)


DESCRIPTION
       Using   libzeep   you  can  create  a  SOAP  server  by  deriving  from
       zeep::server.  In the constructor of your server,  you  call  the  base
       class  constructor  with three arguments: ns, a namespace for your SOAP
       server, address, the address to listen to, usually "0.0.0.0" to  listen
       to all available addresses. And port, the port number to bind to.

       SOAP actions are simply members of the server object and are registered
       using the register_action member  function  of  the  zeep::server  base
       class.  After  initializing the server object, the run member is called
       and the server then starts listening to the address and port specified.

       The resulting web service application will  process  incoming  request.
       There  are  three kinds of requests, the server can return an automati-
       cally generated WSDL, it can process standard SOAP message send in SOAP
       envelopes  and  it  can  handle REST style requests which are mapped to
       corresponding SOAP messages internally.

       The signature of the registered actions are used to  generate  all  the
       code needed to serialize and deserialize SOAP envelopes and to create a
       corresponding WSDL file. The signature can be as simple as the  example
       above but can also be as complex as in this one:

         void myAction(
                const std::vector&lt;MyStructIn&gt;&amp; input,
                MyStructOut&amp; output);

       In  order to make this work, you have to notify the library of the map
       ping  of  your   structure   type   to   a   name   using   the   macro
       SOAP_XML_SET_STRUCT_NAME like this:

                SOAP_XML_SET_STRUCT_NAME(MyStructIn);
                SOAP_XML_SET_STRUCT_NAME(MyStructOut);

       Next  to  this,  you have to provide a way to serialize and deserialize
       your structure. For this,  libzeep  uses  the  same  mechanism  as  the
       Boost::serialize  library, which means you have to add a templated mem
       ber function called serialize to your structure. The result  will  look
       like this:

       struct MyStructIn {
         string myField1;
         int myField2;

         template&lt;class Archive&gt;
         void serialize(Archive&amp; ar, const unsigned int version)
         {
           ar &amp; BOOST_SERIALIZATION_NVP(myField1)
              &amp; BOOST_SERIALIZATION_NVP(myField2);
         }
       };

       Similarly  you  can  use  enum's in an action signature or as structure
       member variables. Again we need to tell the library the type  name  for
       the   enum  and  the  possible  enum  values.  We  do  this  using  the
       SOAP_XML_ADD_ENUM macro, like this:

          enum MyEnum { "one", "two" };
          SOAP_XML_ADD_ENUM(myEnum, one);
          SOAP_XML_ADD_ENUM(myEnum, two);

       As shown above, you can also use std::vector containers in  the  signa-
       ture  of  actions.  Support for other STL containers is not implemented
       yet.

       If the address used by clients of your server  is  different  from  the
       address  of  your  local  machine  (which can happen if you're behind a
       reverse proxy e.g.) you can specify the location using the set_location
       member  function  of  zeep::server.  The specified address will then be
       used in the WSDL file.


BUGS
       Undoubtedly libzeep will contain bugs. One of the more obvious  one  is
       the  missing  support  for  signatures  using STL containers other than
       std::vector.



version 1.0                       12-jan-2009                       libzeep(3)
</pre>


	<a name="reference"/>
	<h2>Reference</h2>

	<p>Well, read the code for now. If I can find the time I will do better.</p>

</body>
</html>