mirror of
https://github.com/michaelrsweet/mxml.git
synced 2024-11-08 13:39:58 +00:00
337baeddb5
Prep for new "standard" opaque, integer, etc. callbacks. Add new vsnprintf check. Drop old string function checks for functions we don't actually use.
401 lines
12 KiB
HTML
401 lines
12 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
|
<head>
|
|
<title>Mini-XML Home Page</title>
|
|
<style><!--
|
|
body, h1, h2, h3, p { font-family: sans-serif; text-align: justify; }
|
|
h1.title, p.title { font-family: sans-serif; text-align: center; }
|
|
tt, pre a:link, pre a:visited, tt a:link, tt a:visited { font-weight: bold; color: #7f0000; }
|
|
pre { font-weight: bold; color: #7f0000; margin-left: 2em; text-align: left }
|
|
--></style>
|
|
</head>
|
|
<body>
|
|
|
|
<p class="title" align="center">[ <a
|
|
href="../index.html">Back to Home Page</a> ]</p>
|
|
|
|
<h1 class="title" align="center">Mini-XML Home Page</h1>
|
|
|
|
<p class="title" align="center">Current Release: v1.2, September 28, 2003<br/>
|
|
[ <a
|
|
href="mxml-1.2.tar.gz">Download Source (.tar.gz 70k)</a>
|
|
| <a
|
|
href="mxml-1.2-1.i386.rpm">Download Linux RPM (.i386.rpm 64k)</a>
|
|
| <a href="CHANGES">Change Log</a> | <a
|
|
href="documentation.html">Documentation</a> | <a
|
|
href="http://freshmeat.net/projects/mxml">Rate/Make Comments</A> ]</p>
|
|
|
|
<h2>Introduction</h2>
|
|
|
|
<p>Mini-XML is a small XML parsing library that you can use to
|
|
read XML and XML-like data files in your application without
|
|
requiring large non-standard libraries. Mini-XML only requires
|
|
an ANSI C compatible compiler (GCC works, as do most vendors'
|
|
ANSI C compilers) and a "make" program.</p>
|
|
|
|
<p>Mini-XML provides the following functionality:</p>
|
|
|
|
<ul>
|
|
<li>Reading and writing of UTF-8 encoded XML files.</li>
|
|
<li>Data is stored in a linked-list tree structure,
|
|
preserving the XML data hierarchy.</li>
|
|
<li>Supports arbitrary element names, attributes, and
|
|
attribute values with no preset limits, just available
|
|
memory.</li>
|
|
<li>Supports integer, real, opaque ("cdata"), and text
|
|
data types in "leaf" nodes.</li>
|
|
<li>Functions for creating and managing trees of data.</li>
|
|
<li>"Find" and "walk" functions for easily locating and
|
|
navigating trees of data.</li>
|
|
</ul>
|
|
|
|
<p>Mini-XML doesn't do validation or other types of processing
|
|
on the data based upon schema files or other sources of
|
|
definition information, nor does it support character entities
|
|
other than those required by the XML specification. Also, since
|
|
Mini-XML does not support the UTF-16 encoding, it is technically
|
|
not a conforming XML consumer/client.</p>
|
|
|
|
<h2>Building Mini-XML</h2>
|
|
|
|
<p>Mini-XML comes with an autoconf-based configure script; just
|
|
type the following command to get things going:</p>
|
|
|
|
<pre>
|
|
./configure
|
|
</pre>
|
|
|
|
<p>The default install prefix is /usr/local, which can be
|
|
overridden using the --prefix option:</p>
|
|
|
|
<pre>
|
|
./configure --prefix=/foo
|
|
</pre>
|
|
|
|
<p>Once you have configured the software, type "make" to do the
|
|
build and run the test program to verify that things are
|
|
working, as follows:</p>
|
|
|
|
<pre>
|
|
make
|
|
</pre>
|
|
|
|
<h2>Installing Mini-XML</h2>
|
|
|
|
<p>The "install" target will install Mini-XML in the lib and
|
|
include directories:</p>
|
|
|
|
<pre>
|
|
make install
|
|
</pre>
|
|
|
|
<p>Once you have installed it, use the "-lmxml" option to link
|
|
your application against it.</p>
|
|
|
|
<h2>Documentation</h2>
|
|
|
|
<p>The documentation is currently a work in progress. Aside from
|
|
the information that follows, the <a
|
|
href="documentation.html">documentation</a> page provides a
|
|
handy reference and is automatically generated using Mini-XML.
|
|
You can also look at the <tt><a
|
|
href="testmxml.c">testmxml.c</a></tt> and <tt><a
|
|
href="mxmldoc.c">mxmldoc.c</a></tt> source files for examples of
|
|
using Mini-XML.</p>
|
|
|
|
<h3>The Basics</h3>
|
|
|
|
<p>Mini-XML provides a single header file which you include:</p>
|
|
|
|
<pre>
|
|
<a href="mxml.h">#include <mxml.h></a>
|
|
</pre>
|
|
|
|
<p>Nodes are defined by the <a
|
|
href="documentation.html#mxml_node_t"><tt>mxml_node_t</tt></a>
|
|
structure; the <a
|
|
href="documentation.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="documentation.html#mxml_value_t"><tt>value</tt></a>
|
|
union. New nodes can be created using the <a
|
|
href="documentation.html#mxmlNewElement"><tt>mxmlNewElement()</tt></a>,
|
|
<a
|
|
href="documentation.html#mxmlNewInteger"><tt>mxmlNewInteger()</tt></a>,
|
|
<a
|
|
href="documentation.html#mxmlNewOpaque"><tt>mxmlNewOpaque()</tt></a>,
|
|
<a
|
|
href="documentation.html#mxmlNewReal"><tt>mxmlNewReal()</tt></a>,
|
|
and <a
|
|
href="documentation.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="documentation.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>
|
|
|
|
<h3>Loading and Saving XML Files</h3>
|
|
|
|
<p>You load an XML file using the <a
|
|
href="documentation.html#mxmlLoadFile"><tt>mxmlLoadFile()</tt></a>
|
|
function:</p>
|
|
|
|
<pre>
|
|
FILE *fp;
|
|
mxml_node_t *tree;
|
|
|
|
fp = fopen("filename.xml", "r");
|
|
tree = mxmlLoadFile(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="documentation.html#mxmlSaveFile"><tt>mxmlSaveFile()</tt></a>
|
|
function:</p>
|
|
|
|
<pre>
|
|
FILE *fp;
|
|
mxml_node_t *tree;
|
|
|
|
fp = fopen("filename.xml", "w");
|
|
mxmlSaveFile(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 0 if no whitespace should be
|
|
added and the character to insert (space, tab, newline)
|
|
otherwise.</p>
|
|
|
|
<p>The <a
|
|
href="documentation.html#mxmlLoadString"><tt>mxmlLoadString()</tt></a>,
|
|
<a
|
|
href="documentation.html#mxmlSaveAllocString"><tt>mxmlSaveAllocString()</tt></a>,
|
|
and <a
|
|
href="documentation.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;
|
|
mxml_node_t *tree;
|
|
|
|
...
|
|
tree = mxmlLoadString(NULL, buffer, MXML_NO_CALLBACK);
|
|
|
|
...
|
|
mxmlSaveString(tree, buffer, sizeof(buffer), MXML_NO_CALLBACK);
|
|
|
|
...
|
|
ptr = mxmlSaveAllocString(tree, MXML_NO_CALLBACK);
|
|
</pre>
|
|
|
|
<h3>Finding and Iterating Nodes</h3>
|
|
|
|
<p>The <a
|
|
href="documentation.html#mxmlWalkPrev"><tt>mxmlWalkPrev()</tt></a>
|
|
and <a
|
|
href="documentation.html#mxmlWalkNext"><tt>mxmlWalkNext()</tt></a>functions
|
|
can be used to iterate through the XML node tree:</p>
|
|
|
|
<pre>
|
|
mxml_node_t *node = mxmlWalkPrev(current, tree, MXML_DESCEND);
|
|
|
|
mxml_node_t *node = mxmlWalkNext(current, tree, MXML_DESCEND);
|
|
</pre>
|
|
|
|
<p>In addition, you can find a named element/node using the <a
|
|
href="documentation.html#mxmlFindElement"><tt>mxmlFindElement()</tt></a>
|
|
function:</p>
|
|
|
|
<pre>
|
|
mxml_node_t *node = mxmlFindElement(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 = mxmlFindElement(tree, tree, "a", NULL, NULL, MXML_DESCEND);
|
|
|
|
/* Find the first "a" element with "href" attribute */
|
|
node = mxmlFindElement(tree, tree, "a", "href", NULL, MXML_DESCEND);
|
|
|
|
/* Find the first "a" element with "href" to a URL */
|
|
node = mxmlFindElement(tree, tree, "a", "href",
|
|
"http://www.easysw.com/~mike/mxml/", MXML_DESCEND);
|
|
|
|
/* Find the first element with a "src" attribute*/
|
|
node = mxmlFindElement(tree, tree, NULL, "src", NULL, MXML_DESCEND);
|
|
|
|
/* Find the first element with a "src" = "foo.jpg" */
|
|
node = mxmlFindElement(tree, tree, NULL, "src", "foo.jpg", MXML_DESCEND);
|
|
</pre>
|
|
|
|
<p>You can also iterate with the same function:</p>
|
|
|
|
<pre>
|
|
mxml_node_t *node;
|
|
|
|
for (node = mxmlFindElement(tree, tree, "name", NULL, NULL, MXML_DESCEND);
|
|
node != NULL;
|
|
node = mxmlFindElement(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>
|
|
|
|
<h2>Getting Help and Reporting Problems</h2>
|
|
|
|
<p>You can email me at "mxml <i>at</i> easysw <i>dot</i> com" to
|
|
report problems and/or ask for help. Just don't expect an
|
|
instant response, as I get a <i>lot</i> of email...</p>
|
|
|
|
<h2>Legal Stuff</h2>
|
|
|
|
<p>The Mini-XML library is Copyright 2003 by Michael Sweet.</p>
|
|
|
|
<p>This library is free software; you can redistribute it
|
|
and/or modify it under the terms of the GNU Library General
|
|
Public License as published by the Free Software Foundation;
|
|
either version 2 of the License, or (at your option) any
|
|
later version.</p>
|
|
|
|
<p>This library is distributed in the hope that it will be
|
|
useful, but WITHOUT ANY WARRANTY; without even the implied
|
|
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
PURPOSE. See the GNU Library General Public License for
|
|
more details.</p>
|
|
|
|
<p>You should have received a copy of the GNU Library General
|
|
Public License along with this library; if not, write to the
|
|
Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
|
|
02139, USA.</p>
|
|
|
|
</body>
|
|
</html>
|