mirror of
https://github.com/michaelrsweet/mxml.git
synced 2024-11-08 13:39:58 +00:00
537afc37da
Move version definition to configure script. Add XML schema for the mxmldoc output.
300 lines
9.6 KiB
HTML
300 lines
9.6 KiB
HTML
<html>
|
|
<body>
|
|
|
|
<h1 align='right'><a name='BASICS'>2 - Getting Started with
|
|
Mini-XML</a></h1>
|
|
|
|
<p>This chapter describes how to write programs that use
|
|
Mini-XML to access data in an XML file.</p>
|
|
|
|
<h2>The Basics</h2>
|
|
|
|
<p>Mini-XML provides a single header file which you include:</p>
|
|
|
|
<pre>
|
|
#include <mxml.h>
|
|
</pre>
|
|
|
|
<p>The Mini-XML library is included with your program using the
|
|
<kbd>-lmxml</kbd> option:</p>
|
|
|
|
<pre>
|
|
<kbd>gcc -o myprogram myprogram.c -lmxml ENTER</kbd>
|
|
</pre>
|
|
|
|
<p>If you have the <tt>pkg-config(1)</tt> software installed,
|
|
you can use it to determine the proper compiler and linker options
|
|
for your installation:</p>
|
|
|
|
<pre>
|
|
<kbd>pkg-config --cflags mxml ENTER</kbd>
|
|
<kbd>pkg-config --libs mxml ENTER</kbd>
|
|
</pre>
|
|
|
|
<h2>Nodes</h2>
|
|
|
|
<p>Every piece of information in an XML file (elements, text,
|
|
numbers) is stored in memory in "nodes". Nodes are defined by
|
|
the <a
|
|
href='reference.html#mxml_node_t'><tt>mxml_node_t</tt></a>
|
|
structure. The <a
|
|
href='reference.html#mxml_type_t'><tt>type</tt></a> member
|
|
defines the node type (element, integer, opaque, real, or text)
|
|
which determines which value you want to look at in the <a
|
|
href='reference.html#mxml_value_t'><tt>value</tt></a> union.</p>
|
|
|
|
<p>New nodes can be created using the <a
|
|
href='reference.html#mxmlNewElement'><tt>mxmlNewElement()</tt></a>,
|
|
<a
|
|
href='reference.html#mxmlNewInteger'><tt>mxmlNewInteger()</tt></a>,
|
|
<a
|
|
href='reference.html#mxmlNewOpaque'><tt>mxmlNewOpaque()</tt></a>,
|
|
<a href='reference.html#mxmlNewReal'><tt>mxmlNewReal()</tt></a>,
|
|
and <a
|
|
href='reference.html#mxmlNewText'><tt>mxmlNewText()</tt></a>
|
|
functions. Only elements can have child nodes, and the top node
|
|
must be an element, usually "?xml".</p>
|
|
|
|
<p>Each node has pointers for the node above (<tt>parent</tt>),
|
|
below (<tt>child</tt>), to the left (<tt>prev</tt>), and to the
|
|
right (<tt>next</tt>) of the current node. If you have an XML
|
|
file like the following:</p>
|
|
|
|
<pre>
|
|
<?xml version="1.0"?>
|
|
<data>
|
|
<node>val1</node>
|
|
<node>val2</node>
|
|
<node>val3</node>
|
|
<group>
|
|
<node>val4</node>
|
|
<node>val5</node>
|
|
<node>val6</node>
|
|
</group>
|
|
<node>val7</node>
|
|
<node>val8</node>
|
|
<node>val9</node>
|
|
</data>
|
|
</pre>
|
|
|
|
<p>the node tree returned by <tt>mxmlLoadFile()</tt> would look
|
|
like the following in memory:</p>
|
|
|
|
<pre>
|
|
?xml
|
|
|
|
|
data
|
|
|
|
|
node - node - node - group - node - node - node
|
|
| | | | | | |
|
|
val1 val2 val3 | val7 val8 val9
|
|
|
|
|
node - node - node
|
|
| | |
|
|
val4 val5 val6
|
|
</pre>
|
|
|
|
<p>where "-" is a pointer to the next node and "|" is a pointer
|
|
to the first child node.</p>
|
|
|
|
<p>Once you are done with the XML data, use the <a
|
|
href='reference.html#mxmlDelete'><tt>mxmlDelete()</tt></a>
|
|
function to recursively free the memory that is used for a
|
|
particular node or the entire tree:</p>
|
|
|
|
<pre>
|
|
mxmlDelete(tree);
|
|
</pre>
|
|
|
|
<h2>Loading and Saving XML Files</h2>
|
|
|
|
<p>You load an XML file using the <a
|
|
href='reference.html#mxmlLoadFile'><tt>mxmlLoadFile()</tt></a>
|
|
function:</p>
|
|
|
|
<pre>
|
|
FILE *fp;
|
|
<a href='reference.html#mxml_node_t'>mxml_node_t</a> *tree;
|
|
|
|
fp = fopen("filename.xml", "r");
|
|
tree = <a href='reference.html#mxmlLoadFile'>mxmlLoadFile</a>(NULL, fp, MXML_NO_CALLBACK);
|
|
fclose(fp);
|
|
</pre>
|
|
|
|
<p>The third argument specifies a callback function which
|
|
returns the value type of the immediate children for a new
|
|
element node: <tt>MXML_INTEGER</tt>, <tt>MXML_OPAQUE</tt>,
|
|
<tt>MXML_REAL</tt>, or <tt>MXML_TEXT</tt>. This function is
|
|
called <i>after</i> the element and its attributes have been
|
|
read, so you can look at the element name, attributes, and
|
|
attribute values to determine the proper value type to return.
|
|
The default value type is MXML_TEXT if no callback is used.</p>
|
|
|
|
<p>Similarly, you save an XML file using the <a
|
|
href='reference.html#mxmlSaveFile'><tt>mxmlSaveFile()</tt></a>
|
|
function:</p>
|
|
|
|
<pre>
|
|
FILE *fp;
|
|
<a href='reference.html#mxml_node_t'>mxml_node_t</a> *tree;
|
|
|
|
fp = fopen("filename.xml", "w");
|
|
<a href='reference.html#mxmlSaveFile'>mxmlSaveFile</a>(tree, fp, MXML_NO_CALLBACK);
|
|
fclose(fp);
|
|
</pre>
|
|
|
|
<p>Callback functions for saving are used to optionally insert
|
|
whitespace before and after elements in the node tree. Your
|
|
function will be called up to four times for each element node
|
|
with a pointer to the node and a "where" value of
|
|
<tt>MXML_WS_BEFORE_OPEN</tt>, <tt>MXML_WS_AFTER_OPEN</tt>,
|
|
<tt>MXML_WS_BEFORE_CLOSE</tt>, or <tt>MXML_WS_AFTER_CLOSE</tt>.
|
|
The callback function should return <tt>NULL</tt> if no
|
|
whitespace should be added and the string to insert (spaces,
|
|
tabs, carriage returns, and newlines) otherwise.</p>
|
|
|
|
<p>The <a
|
|
href='reference.html#mxmlLoadString'><tt>mxmlLoadString()</tt></a>,
|
|
<a
|
|
href='reference.html#mxmlSaveAllocString'><tt>mxmlSaveAllocString()</tt></a>,
|
|
and <a
|
|
href='reference.html#mxmlSaveString'><tt>mxmlSaveString()</tt></a>
|
|
functions load XML node trees from and save XML node trees to
|
|
strings:</p>
|
|
|
|
<pre>
|
|
char buffer[8192];
|
|
char *ptr;
|
|
<a href='reference.html#mxml_node_t'>mxml_node_t</a> *tree;
|
|
|
|
...
|
|
tree = <a href='reference.html#mxmlLoadString'>mxmlLoadString</a>(NULL, buffer, MXML_NO_CALLBACK);
|
|
|
|
...
|
|
<a href='reference.html#mxmlSaveString'>mxmlSaveString</a>(tree, buffer, sizeof(buffer), MXML_NO_CALLBACK);
|
|
|
|
...
|
|
ptr = <a href='reference.html#mxmlSaveAllocString'>mxmlSaveAllocString</a>(tree, MXML_NO_CALLBACK);
|
|
</pre>
|
|
|
|
<h3>Finding and Iterating Nodes</h3>
|
|
|
|
<p>The <a
|
|
href='reference.html#mxmlWalkPrev'><tt>mxmlWalkPrev()</tt></a>
|
|
and <a
|
|
href='reference.html#mxmlWalkNext'><tt>mxmlWalkNext()</tt></a>functions
|
|
can be used to iterate through the XML node tree:</p>
|
|
|
|
<pre>
|
|
<a href='reference.html#mxml_node_t'>mxml_node_t</a> *node = <a href='reference.html#mxmlWalkPrev'>mxmlWalkPrev</a>(current, tree, MXML_DESCEND);
|
|
|
|
<a href='reference.html#mxml_node_t'>mxml_node_t</a> *node = <a href='reference.html#mxmlWalkNext'>mxmlWalkNext</a>(current, tree, MXML_DESCEND);
|
|
</pre>
|
|
|
|
<p>In addition, you can find a named element/node using the <a
|
|
href='reference.html#mxmlFindElement'><tt>mxmlFindElement()</tt></a>
|
|
function:</p>
|
|
|
|
<pre>
|
|
<a href='reference.html#mxml_node_t'>mxml_node_t</a> *node = <a href='reference.html#mxmlFindElement'>mxmlFindElement</a>(tree, tree, "name", "attr",
|
|
"value", MXML_DESCEND);
|
|
</pre>
|
|
|
|
<p>The <tt>name</tt>, <tt>attr</tt>, and <tt>value</tt>
|
|
arguments can be passed as <tt>NULL</tt> to act as wildcards,
|
|
e.g.:</p>
|
|
|
|
<pre>
|
|
/* Find the first "a" element */
|
|
node = <a href='reference.html#mxmlFindElement'>mxmlFindElement</a>(tree, tree, "a", NULL, NULL, MXML_DESCEND);
|
|
|
|
/* Find the first "a" element with "href" attribute */
|
|
node = <a href='reference.html#mxmlFindElement'>mxmlFindElement</a>(tree, tree, "a", "href", NULL, MXML_DESCEND);
|
|
|
|
/* Find the first "a" element with "href" to a URL */
|
|
node = <a href='reference.html#mxmlFindElement'>mxmlFindElement</a>(tree, tree, "a", "href",
|
|
"http://www.easysw.com/~mike/mxml/", MXML_DESCEND);
|
|
|
|
/* Find the first element with a "src" attribute*/
|
|
node = <a href='reference.html#mxmlFindElement'>mxmlFindElement</a>(tree, tree, NULL, "src", NULL, MXML_DESCEND);
|
|
|
|
/* Find the first element with a "src" = "foo.jpg" */
|
|
node = <a href='reference.html#mxmlFindElement'>mxmlFindElement</a>(tree, tree, NULL, "src", "foo.jpg", MXML_DESCEND);
|
|
</pre>
|
|
|
|
<p>You can also iterate with the same function:</p>
|
|
|
|
<pre>
|
|
<a href='reference.html#mxml_node_t'>mxml_node_t</a> *node;
|
|
|
|
for (node = <a href='reference.html#mxmlFindElement'>mxmlFindElement</a>(tree, tree, "name", NULL, NULL, MXML_DESCEND);
|
|
node != NULL;
|
|
node = <a href='reference.html#mxmlFindElement'>mxmlFindElement</a>(node, tree, "name", NULL, NULL, MXML_DESCEND))
|
|
{
|
|
... do something ...
|
|
}
|
|
</pre>
|
|
|
|
<p>The <tt>MXML_DESCEND</tt> argument can actually be one of
|
|
three constants:</p>
|
|
|
|
<ul>
|
|
|
|
<li><tt>MXML_NO_DESCEND</tt> means to not to look at any
|
|
child nodes in the element hierarchy, just look at
|
|
siblings at the same level or parent nodes until the top
|
|
node or top-of-tree is reached. The previous node from
|
|
"group" would be the "node" element to the left, while
|
|
the next node from "group" would be the "node" element
|
|
to the right.</li>
|
|
|
|
<li><tt>MXML_DESCEND_FIRST</tt> means that it is OK to
|
|
descend to the first child of a node, but not to descend
|
|
further when searching. You'll normally use this when
|
|
iterating through direct children of a parent node, e.g.
|
|
all of the "node" elements under the "?xml" parent node
|
|
in the example above. This mode is only applicable to
|
|
the search function; the walk functions treat this as
|
|
<tt>MXML_DESCEND</tt> since every call is a first
|
|
time.</li>
|
|
|
|
<li><tt>MXML_DESCEND</tt> means to keep descending until
|
|
you hit the bottom of the tree. The previous node from
|
|
"group" would be the "val3" node and the next node would
|
|
be the first node element under "group". If you were to
|
|
walk from the root node "?xml" to the end of the
|
|
tree with <tt>mxmlWalkNext()</tt>, the order would be:
|
|
|
|
<pre>
|
|
?xml
|
|
data
|
|
node
|
|
val1
|
|
node
|
|
val2
|
|
node
|
|
val3
|
|
group
|
|
node
|
|
val4
|
|
node
|
|
val5
|
|
node
|
|
val6
|
|
node
|
|
val7
|
|
node
|
|
val8
|
|
node
|
|
val9
|
|
</pre>
|
|
|
|
<p>If you started at "val9" and walked using
|
|
<tt>mxmlWalkPrev()</tt>, the order would be reversed,
|
|
ending at "?xml".</p></li>
|
|
|
|
</ul>
|
|
|
|
</body>
|
|
</html>
|