| <h2 class='title'><a name='INTRODUCTION'>Introduction</a></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 of UTF-8 and UTF-16 and writing of UTF-8 encoded XML files |
| and strings.</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, indexing, 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.</p> |
| |
| <h2 class='title'><a name='USING'>Using Mini-XML</a></h2> |
| |
| <p>Mini-XML provides a single header file which you include:</p> |
| |
| <pre class='example'> |
| #include <mxml.h> |
| </pre> |
| |
| <p>Nodes are defined by the "<a href='#mxml_node_s'>mxml_node_t</a>" structure; |
| the "type" member defines the node type (element, integer, opaque, real, or |
| text) which determines which value you want to look at in the "value" union. |
| New nodes can be created using the |
| "<a href='#mxmlNewElement'>mxmlNewElement()</a>", |
| "<a href='#mxmlNewInteger'>mxmlNewInteger()</a>", |
| "<a href='#mxmlNewOpaque'>mxmlNewOpaque()</a>", |
| "<a href='#mxmlNewReal'>mxmlNewReal()</a>", and |
| "<a href='#mxmlNewText'>mxmlNewText()</a>" functions. Only elements can have |
| child nodes, and the top node must be an element, usually "?xml".</p> |
| |
| <p>You load an XML file using the "mxmlLoadFile()" function:</p> |
| |
| <pre class='example'> |
| FILE *fp; |
| mxml_node_t *tree; |
| |
| fp = fopen("filename.xml", "r"); |
| tree = mxmlLoadFile(NULL, fp, MXML_NO_CALLBACK); |
| fclose(fp); |
| </pre> |
| |
| <p>Similarly, you save an XML file using the |
| "<a href='#mxmlSaveFile'>mxmlSaveFile()</a>" function: |
| |
| <pre class='example'> |
| FILE *fp; |
| mxml_node_t *tree; |
| |
| fp = fopen("filename.xml", "w"); |
| mxmlSaveFile(tree, fp, MXML_NO_CALLBACK); |
| fclose(fp); |
| </pre> |
| |
| <p>The "<a href='#mxmlLoadString'>mxmlLoadString()</a>", |
| "<a href='#mxmlSaveAllocString'>mxmlSaveAllocString()</a>", and |
| "<a href='#mxmlSaveString'>mxmlSaveString()</a>" functions load XML node trees |
| from and save XML node trees to strings:</p> |
| |
| <pre class='example'> |
| 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> |
| |
| <p>You can find a named element/node using the |
| "<a href='#mxmlFindElement'>mxmlFindElement()</a>" function:</p> |
| |
| <pre class='example'> |
| mxml_node_t *node = mxmlFindElement(tree, tree, "name", |
| "attr", "value", |
| MXML_DESCEND); |
| </pre> |
| |
| <p>The "name", "attr", and "value" arguments can be passed as |
| <code>NULL</code> to act as wildcards, e.g.:</p> |
| |
| <pre class='example'> |
| /* 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 class='example'> |
| 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 "mxmlFindPath()" function finds the (first) value node under a specific |
| element using a "path":</p> |
| |
| <pre class='example'> |
| mxml_node_t *value = mxmlFindPath(tree, "path/to/*/foo/bar"); |
| </pre> |
| |
| <p>The "mxmlGetInteger()", "mxmlGetOpaque()", "mxmlGetReal()", and |
| "mxmlGetText()" functions retrieve the value from a node:</p> |
| |
| <pre class='example'> |
| mxml_node_t *node; |
| |
| int intvalue = mxmlGetInteger(node); |
| |
| const char *opaquevalue = mxmlGetOpaque(node); |
| |
| double realvalue = mxmlGetReal(node); |
| |
| int whitespacevalue; |
| const char *textvalue = mxmlGetText(node, &whitespacevalue); |
| </pre> |
| |
| <p>Finally, once you are done with the XML data, use the |
| "<a href='#mxmlDelete'>mxmlDelete()</a>" function to recursively free the |
| memory that is used for a particular node or the entire tree:</p> |
| |
| <pre class='example'> |
| mxmlDelete(tree); |
| </pre> |