1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
4 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
5 <link rel="SHORTCUT ICON" href="/favicon.ico">
6 <style type="text/css"><!--
7 TD {font-family: Verdana,Arial,Helvetica}
8 BODY {font-family: Verdana,Arial,Helvetica; margin-top: 2em; margin-left: 0em; margin-right: 0em}
9 H1 {font-family: Verdana,Arial,Helvetica}
10 H2 {font-family: Verdana,Arial,Helvetica}
11 H3 {font-family: Verdana,Arial,Helvetica}
12 A:link, A:visited, A:active { text-decoration: underline }
14 <title>A real example</title>
16 <body bgcolor="#8b7765" text="#000000" link="#000000" vlink="#000000">
17 <table border="0" width="100%" cellpadding="5" cellspacing="0" align="center"><tr>
19 <a href="http://www.gnome.org/"><img src="gnome2.png" alt="Gnome2 Logo"></a><a href="http://www.w3.org/Status"><img src="w3c.png" alt="W3C Logo"></a><a href="http://www.redhat.com/"><img src="redhat.gif" alt="Red Hat Logo"></a><div align="left"><a href="http://xmlsoft.org/"><img src="Libxml2-Logo-180x168.gif" alt="Made with Libxml2 Logo"></a></div>
21 <td><table border="0" width="90%" cellpadding="2" cellspacing="0" align="center" bgcolor="#000000"><tr><td><table width="100%" border="0" cellspacing="1" cellpadding="3" bgcolor="#fffacd"><tr><td align="center">
22 <h1>The XML C library for Gnome</h1>
23 <h2>A real example</h2>
24 </td></tr></table></td></tr></table></td>
26 <table border="0" cellpadding="4" cellspacing="0" width="100%" align="center"><tr><td bgcolor="#8b7765"><table border="0" cellspacing="0" cellpadding="2" width="100%"><tr>
27 <td valign="top" width="200" bgcolor="#8b7765"><table border="0" cellspacing="0" cellpadding="1" width="100%" bgcolor="#000000"><tr><td>
28 <table width="100%" border="0" cellspacing="1" cellpadding="3">
29 <tr><td colspan="1" bgcolor="#eecfa1" align="center"><center><b>Main Menu</b></center></td></tr>
30 <tr><td bgcolor="#fffacd">
31 <form action="search.php" enctype="application/x-www-form-urlencoded" method="GET">
32 <input name="query" type="TEXT" size="20" value=""><input name="submit" type="submit" value="Search ...">
35 <li><a href="index.html">Home</a></li>
36 <li><a href="intro.html">Introduction</a></li>
37 <li><a href="FAQ.html">FAQ</a></li>
38 <li><a href="docs.html">Documentation</a></li>
39 <li><a href="bugs.html">Reporting bugs and getting help</a></li>
40 <li><a href="help.html">How to help</a></li>
41 <li><a href="downloads.html">Downloads</a></li>
42 <li><a href="news.html">News</a></li>
43 <li><a href="XMLinfo.html">XML</a></li>
44 <li><a href="XSLT.html">XSLT</a></li>
45 <li><a href="python.html">Python and bindings</a></li>
46 <li><a href="architecture.html">libxml architecture</a></li>
47 <li><a href="tree.html">The tree output</a></li>
48 <li><a href="interface.html">The SAX interface</a></li>
49 <li><a href="xmldtd.html">Validation & DTDs</a></li>
50 <li><a href="xmlmem.html">Memory Management</a></li>
51 <li><a href="encoding.html">Encodings support</a></li>
52 <li><a href="xmlio.html">I/O Interfaces</a></li>
53 <li><a href="catalog.html">Catalog support</a></li>
54 <li><a href="library.html">The parser interfaces</a></li>
55 <li><a href="entities.html">Entities or no entities</a></li>
56 <li><a href="namespaces.html">Namespaces</a></li>
57 <li><a href="upgrade.html">Upgrading 1.x code</a></li>
58 <li><a href="threads.html">Thread safety</a></li>
59 <li><a href="DOM.html">DOM Principles</a></li>
60 <li><a href="example.html">A real example</a></li>
61 <li><a href="contribs.html">Contributions</a></li>
62 <li><a href="xmlreader.html">The Reader Interface</a></li>
63 <li><a href="tutorial/index.html">Tutorial</a></li>
64 <li><a href="guidelines.html">XML Guidelines</a></li>
66 <a href="xml.html">flat page</a>, <a href="site.xsl">stylesheet</a>
71 <table width="100%" border="0" cellspacing="1" cellpadding="3">
72 <tr><td colspan="1" bgcolor="#eecfa1" align="center"><center><b>Related links</b></center></td></tr>
73 <tr><td bgcolor="#fffacd"><ul>
74 <li><a href="http://mail.gnome.org/archives/xml/">Mail archive</a></li>
75 <li><a href="http://xmlsoft.org/XSLT/">XSLT libxslt</a></li>
76 <li><a href="http://phd.cs.unibo.it/gdome2/">DOM gdome2</a></li>
77 <li><a href="http://www.aleksey.com/xmlsec/">XML-DSig xmlsec</a></li>
78 <li><a href="ftp://xmlsoft.org/">FTP</a></li>
79 <li><a href="http://www.zlatkovic.com/projects/libxml/">Windows binaries</a></li>
80 <li><a href="http://garypennington.net/libxml2/">Solaris binaries</a></li>
81 <li><a href="http://www.zveno.com/open_source/libxml2xslt.html">MacOsX binaries</a></li>
82 <li><a href="http://sourceforge.net/projects/libxml2-pas/">Pascal bindings</a></li>
83 <li><a href="http://bugzilla.gnome.org/buglist.cgi?product=libxml&product=libxml2">Bug Tracker</a></li>
86 <table width="100%" border="0" cellspacing="1" cellpadding="3">
87 <tr><td colspan="1" bgcolor="#eecfa1" align="center"><center><b>API Indexes</b></center></td></tr>
88 <tr><td bgcolor="#fffacd"><ul>
89 <li><a href="APIchunk0.html">Alphabetic</a></li>
90 <li><a href="APIconstructors.html">Constructors</a></li>
91 <li><a href="APIfunctions.html">Functions/Types</a></li>
92 <li><a href="APIfiles.html">Modules</a></li>
93 <li><a href="APIsymbols.html">Symbols</a></li>
96 </td></tr></table></td>
97 <td valign="top" bgcolor="#8b7765"><table border="0" cellspacing="0" cellpadding="1" width="100%"><tr><td><table border="0" cellspacing="0" cellpadding="1" width="100%" bgcolor="#000000"><tr><td><table border="0" cellpadding="3" cellspacing="1" width="100%"><tr><td bgcolor="#fffacd">
98 <p>Here is a real size example, where the actual content of the application
99 data is not kept in the DOM tree but uses internal structures. It is based on
100 a proposal to keep a database of jobs related to Gnome, with an XML based
101 storage structure. Here is an <a href="gjobs.xml">XML encoded jobs
103 <pre><?xml version="1.0"?>
104 <gjob:Helping xmlns:gjob="http://www.gnome.org/some-location">
108 <gjob:Project ID="3"/>
109 <gjob:Application>GBackup</gjob:Application>
110 <gjob:Category>Development</gjob:Category>
113 <gjob:Status>Open</gjob:Status>
114 <gjob:Modified>Mon, 07 Jun 1999 20:27:45 -0400 MET DST</gjob:Modified>
115 <gjob:Salary>USD 0.00</gjob:Salary>
118 <gjob:Developers>
119 <gjob:Developer>
120 </gjob:Developer>
121 </gjob:Developers>
124 <gjob:Person>Nathan Clemons</gjob:Person>
125 <gjob:Email>nathan@windsofstorm.net</gjob:Email>
127 </gjob:Company>
128 <gjob:Organisation>
129 </gjob:Organisation>
131 </gjob:Webpage>
132 <gjob:Snailmail>
133 </gjob:Snailmail>
136 </gjob:Contact>
138 <gjob:Requirements>
139 The program should be released as free software, under the GPL.
140 </gjob:Requirements>
146 A GNOME based system that will allow a superuser to configure
147 compressed and uncompressed files and/or file systems to be backed
148 up with a supported media in the system. This should be able to
149 perform via find commands generating a list of files that are passed
150 to tar, dd, cpio, cp, gzip, etc., to be directed to the tape machine
151 or via operations performed on the filesystem itself. Email
152 notification and GUI status display very important.
153 </gjob:Details>
158 </gjob:Helping></pre>
159 <p>While loading the XML file into an internal DOM tree is a matter of
160 calling only a couple of functions, browsing the tree to gather the data and
161 generate the internal structures is harder, and more error prone.</p>
162 <p>The suggested principle is to be tolerant with respect to the input
163 structure. For example, the ordering of the attributes is not significant,
164 the XML specification is clear about it. It's also usually a good idea not to
165 depend on the order of the children of a given node, unless it really makes
166 things harder. Here is some code to parse the information for a person:</p>
170 typedef struct person {
178 } person, *personPtr;
181 * And the code needed to parse it
183 personPtr parsePerson(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur) {
184 personPtr ret = NULL;
186 DEBUG("parsePerson\n");
188 * allocate the struct
190 ret = (personPtr) malloc(sizeof(person));
192 fprintf(stderr,"out of memory\n");
195 memset(ret, 0, sizeof(person));
197 /* We don't care what the top level element name is */
198 cur = cur->xmlChildrenNode;
199 while (cur != NULL) {
200 if ((!strcmp(cur->name, "Person")) && (cur->ns == ns))
201 ret->name = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
202 if ((!strcmp(cur->name, "Email")) && (cur->ns == ns))
203 ret->email = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
209 <p>Here are a couple of things to notice:</p>
211 <li>Usually a recursive parsing style is the more convenient one: XML data
212 is by nature subject to repetitive constructs and usually exhibits highly
213 structured patterns.</li>
214 <li>The two arguments of type <em>xmlDocPtr</em> and <em>xmlNsPtr</em>,
215 i.e. the pointer to the global XML document and the namespace reserved to
216 the application. Document wide information are needed for example to
217 decode entities and it's a good coding practice to define a namespace for
218 your application set of data and test that the element and attributes
219 you're analyzing actually pertains to your application space. This is
220 done by a simple equality test (cur->ns == ns).</li>
221 <li>To retrieve text and attributes value, you can use the function
222 <em>xmlNodeListGetString</em> to gather all the text and entity reference
223 nodes generated by the DOM output and produce an single text string.</li>
225 <p>Here is another piece of code used to parse another level of the
227 <pre>#include <libxml/tree.h>
229 * a Description for a Job
237 personPtr developers[100]; /* using dynamic alloc is left as an exercise */
241 * And the code needed to parse it
243 jobPtr parseJob(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur) {
246 DEBUG("parseJob\n");
248 * allocate the struct
250 ret = (jobPtr) malloc(sizeof(job));
252 fprintf(stderr,"out of memory\n");
255 memset(ret, 0, sizeof(job));
257 /* We don't care what the top level element name is */
258 cur = cur->xmlChildrenNode;
259 while (cur != NULL) {
261 if ((!strcmp(cur->name, "Project")) && (cur->ns == ns)) {
262 ret->projectID = xmlGetProp(cur, "ID");
263 if (ret->projectID == NULL) {
264 fprintf(stderr, "Project has no ID\n");
267 if ((!strcmp(cur->name, "Application")) && (cur->ns == ns))
268 ret->application = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
269 if ((!strcmp(cur->name, "Category")) && (cur->ns == ns))
270 ret->category = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
271 if ((!strcmp(cur->name, "Contact")) && (cur->ns == ns))
272 ret->contact = parsePerson(doc, ns, cur);
278 <p>Once you are used to it, writing this kind of code is quite simple, but
279 boring. Ultimately, it could be possible to write stubbers taking either C
280 data structure definitions, a set of XML examples or an XML DTD and produce
281 the code needed to import and export the content between C data and XML
282 storage. This is left as an exercise to the reader :-)</p>
283 <p>Feel free to use <a href="example/gjobread.c">the code for the full C
284 parsing example</a> as a template, it is also available with Makefile in the
285 Gnome CVS base under gnome-xml/example</p>
286 <p><a href="bugs.html">Daniel Veillard</a></p>
287 </td></tr></table></td></tr></table></td></tr></table></td>
288 </tr></table></td></tr></table>