mirror of
https://github.com/michaelrsweet/mxml.git
synced 2025-05-10 06:52:08 +00:00
2930 lines
146 KiB
HTML
2930 lines
146 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en-US">
|
|
<head>
|
|
<title>Mini-XML 4.0 Programming Manual</title>
|
|
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
|
<meta name="generator" content="codedoc v3.7">
|
|
<meta name="author" content="Michael R Sweet">
|
|
<meta name="language" content="en-US">
|
|
<meta name="copyright" content="Copyright © 2003-2024, All Rights Reserved.">
|
|
<meta name="version" content="4.0">
|
|
<style type="text/css"><!--
|
|
body {
|
|
background: white;
|
|
color: black;
|
|
font-family: sans-serif;
|
|
font-size: 12pt;
|
|
}
|
|
a {
|
|
color: black;
|
|
}
|
|
a:link, a:visited {
|
|
color: #00f;
|
|
}
|
|
a:link:hover, a:visited:hover, a:active {
|
|
color: #c0c;
|
|
}
|
|
body, p, h1, h2, h3, h4, h5, h6 {
|
|
font-family: sans-serif;
|
|
line-height: 1.4;
|
|
}
|
|
h1, h2, h3, h4, h5, h6 {
|
|
font-weight: bold;
|
|
page-break-inside: avoid;
|
|
}
|
|
h1 {
|
|
font-size: 250%;
|
|
margin: 0;
|
|
}
|
|
h2 {
|
|
font-size: 250%;
|
|
margin-top: 1.5em;
|
|
}
|
|
h3 {
|
|
font-size: 200%;
|
|
margin-bottom: 0.5em;
|
|
margin-top: 1.5em;
|
|
}
|
|
h4 {
|
|
font-size: 150%;
|
|
margin-bottom: 0.5em;
|
|
margin-top: 1.5em;
|
|
}
|
|
h5 {
|
|
font-size: 125%;
|
|
margin-bottom: 0.5em;
|
|
margin-top: 1.5em;
|
|
}
|
|
h6 {
|
|
font-size: 110%;
|
|
margin-bottom: 0.5em;
|
|
margin-top: 1.5em;
|
|
}
|
|
img.title {
|
|
width: 256px;
|
|
}
|
|
div.header h1, div.header p {
|
|
text-align: center;
|
|
}
|
|
div.contents, div.body, div.footer {
|
|
page-break-before: always;
|
|
}
|
|
.class, .enumeration, .function, .struct, .typedef, .union {
|
|
border-bottom: solid 2px gray;
|
|
}
|
|
.description {
|
|
margin-top: 0.5em;
|
|
}
|
|
.function {
|
|
margin-bottom: 0;
|
|
}
|
|
blockquote {
|
|
border: solid thin gray;
|
|
box-shadow: 3px 3px 5px rgba(127,127,127,0.25);
|
|
margin: 1em 0;
|
|
padding: 10px;
|
|
page-break-inside: avoid;
|
|
}
|
|
p code, li code, p.code, pre, ul.code li {
|
|
font-family: monospace;
|
|
hyphens: manual;
|
|
-webkit-hyphens: manual;
|
|
}
|
|
p.code, pre, ul.code li {
|
|
background: rgba(127,127,127,0.25);
|
|
border: thin dotted gray;
|
|
padding: 10px;
|
|
page-break-inside: avoid;
|
|
}
|
|
pre {
|
|
white-space: pre-wrap;
|
|
}
|
|
a:link, a:visited {
|
|
text-decoration: none;
|
|
}
|
|
span.info {
|
|
background: black;
|
|
border: solid thin black;
|
|
color: white;
|
|
font-size: 80%;
|
|
font-style: italic;
|
|
font-weight: bold;
|
|
white-space: nowrap;
|
|
}
|
|
h1 span.info, h2 span.info, h3 span.info, h4 span.info {
|
|
border-top-left-radius: 10px;
|
|
border-top-right-radius: 10px;
|
|
float: right;
|
|
padding: 3px 6px;
|
|
}
|
|
ul.code, ul.contents, ul.subcontents {
|
|
list-style-type: none;
|
|
margin: 0;
|
|
padding-left: 0;
|
|
}
|
|
ul.code li {
|
|
margin: 0;
|
|
}
|
|
ul.contents > li {
|
|
margin-top: 1em;
|
|
}
|
|
ul.contents li ul.code, ul.contents li ul.subcontents {
|
|
padding-left: 2em;
|
|
}
|
|
table {
|
|
border-collapse: collapse;
|
|
border-spacing: 0;
|
|
}
|
|
td {
|
|
border: solid 1px gray;
|
|
padding: 5px 10px;
|
|
vertical-align: top;
|
|
}
|
|
td.left {
|
|
text-align: left;
|
|
}
|
|
td.center {
|
|
text-align: center;
|
|
}
|
|
td.right {
|
|
text-align: right;
|
|
}
|
|
th {
|
|
border-bottom: solid 2px gray;
|
|
padding: 1px 5px;
|
|
text-align: center;
|
|
vertical-align: bottom;
|
|
}
|
|
tr:nth-child(even) {
|
|
background: rgba(127,127,127,0.25);
|
|
}
|
|
table.list {
|
|
border-collapse: collapse;
|
|
width: 100%;
|
|
}
|
|
table.list th {
|
|
border-bottom: none;
|
|
border-right: 2px solid gray;
|
|
font-family: monospace;
|
|
font-weight: normal;
|
|
padding: 5px 10px 5px 2px;
|
|
text-align: right;
|
|
vertical-align: top;
|
|
}
|
|
table.list td {
|
|
border: none;
|
|
padding: 5px 2px 5px 10px;
|
|
text-align: left;
|
|
vertical-align: top;
|
|
}
|
|
h2.title, h3.title {
|
|
border-bottom: solid 2px gray;
|
|
}
|
|
/* Syntax highlighting */
|
|
span.comment {
|
|
color: darkgreen;
|
|
}
|
|
span.directive {
|
|
color: purple;
|
|
}
|
|
span.number {
|
|
color: brown;
|
|
}
|
|
span.reserved {
|
|
color: darkcyan;
|
|
}
|
|
span.string {
|
|
color: magenta;
|
|
}
|
|
/* Dark mode overrides */
|
|
@media (prefers-color-scheme: dark) {
|
|
body {
|
|
background: black;
|
|
color: #ccc;
|
|
}
|
|
a {
|
|
color: #ccc;
|
|
}
|
|
a:link, a:visited {
|
|
color: #66f;
|
|
}
|
|
a:link:hover, a:visited:hover, a:active {
|
|
color: #f06;
|
|
}
|
|
}
|
|
/* Show contents on left side in web browser */
|
|
@media screen and (min-width: 800px) {
|
|
div.contents {
|
|
border-right: solid thin gray;
|
|
bottom: 0px;
|
|
box-shadow: 3px 3px 5px rgba(127,127,127,0.5);
|
|
font-size: 10pt;
|
|
left: 0px;
|
|
overflow: scroll;
|
|
padding: 1%;
|
|
position: fixed;
|
|
top: 0px;
|
|
width: 18%;
|
|
}
|
|
div.contents h2.title {
|
|
margin-top: 0px;
|
|
}
|
|
div.header, div.body, div.footer {
|
|
margin-left: 20%;
|
|
padding: 1% 2%;
|
|
}
|
|
}
|
|
/* Center title page content vertically */
|
|
@media print {
|
|
div.header {
|
|
padding-top: 33%;
|
|
}
|
|
}
|
|
--></style>
|
|
</head>
|
|
<body>
|
|
<div class="header">
|
|
<p><img class="title" src="mxml-cover.png"></p>
|
|
<h1 class="title">Mini-XML 4.0 Programming Manual</h1>
|
|
<p>Michael R Sweet</p>
|
|
<p>Copyright © 2003-2024, All Rights Reserved.</p>
|
|
</div>
|
|
<div class="contents">
|
|
<h2 class="title">Contents</h2>
|
|
<ul class="contents">
|
|
<li><a href="#introduction">Introduction</a><ul class="subcontents">
|
|
<li><a href="#history">History</a></li>
|
|
<li><a href="#resources">Resources</a></li>
|
|
<li><a href="#legal-stuff">Legal Stuff</a></li>
|
|
</ul></li>
|
|
<li><a href="#using-mini-xml">Using Mini-XML</a><ul class="subcontents">
|
|
<li><a href="#loading-an-xml-file">Loading an XML File</a></li>
|
|
<li><a href="#nodes">Nodes</a></li>
|
|
<li><a href="#creating-xml-documents">Creating XML Documents</a></li>
|
|
<li><a href="#saving-an-xml-file">Saving an XML File</a></li>
|
|
<li><a href="#memory-management">Memory Management</a></li>
|
|
</ul></li>
|
|
<li><a href="#more-about-nodes">More About Nodes</a><ul class="subcontents">
|
|
<li><a href="#element-nodes">Element Nodes</a></li>
|
|
<li><a href="#cdata-nodes">CDATA Nodes</a></li>
|
|
<li><a href="#comment-nodes">Comment Nodes</a></li>
|
|
<li><a href="#processing-instruction-nodes">Processing Instruction Nodes</a></li>
|
|
<li><a href="#integer-nodes">Integer Nodes</a></li>
|
|
<li><a href="#opaque-string-nodes">Opaque String Nodes</a></li>
|
|
<li><a href="#text-nodes">Text Nodes</a></li>
|
|
<li><a href="#real-number-nodes">Real Number Nodes</a></li>
|
|
</ul></li>
|
|
<li><a href="#locating-data-in-an-xml-document">Locating Data in an XML Document</a><ul class="subcontents">
|
|
<li><a href="#finding-nodes">Finding Nodes</a></li>
|
|
<li><a href="#iterating-nodes">Iterating Nodes</a></li>
|
|
<li><a href="#indexing">Indexing</a></li>
|
|
</ul></li>
|
|
<li><a href="#custom-data-types">Custom Data Types</a></li>
|
|
<li><a href="#sax-stream-loading-of-documents">SAX (Stream) Loading of Documents</a></li>
|
|
<li><a href="#migrating-from-mini-xml-v3.x">Migrating from Mini-XML v3.x</a></li>
|
|
<li><a href="#FUNCTIONS">Functions</a><ul class="subcontents">
|
|
<li><a href="#mxmlAdd">mxmlAdd</a></li>
|
|
<li><a href="#mxmlDelete">mxmlDelete</a></li>
|
|
<li><a href="#mxmlElementDeleteAttr">mxmlElementDeleteAttr</a></li>
|
|
<li><a href="#mxmlElementGetAttr">mxmlElementGetAttr</a></li>
|
|
<li><a href="#mxmlElementGetAttrByIndex">mxmlElementGetAttrByIndex</a></li>
|
|
<li><a href="#mxmlElementGetAttrCount">mxmlElementGetAttrCount</a></li>
|
|
<li><a href="#mxmlElementSetAttr">mxmlElementSetAttr</a></li>
|
|
<li><a href="#mxmlElementSetAttrf">mxmlElementSetAttrf</a></li>
|
|
<li><a href="#mxmlEntityAddCallback">mxmlEntityAddCallback</a></li>
|
|
<li><a href="#mxmlEntityGetName">mxmlEntityGetName</a></li>
|
|
<li><a href="#mxmlEntityGetValue">mxmlEntityGetValue</a></li>
|
|
<li><a href="#mxmlEntityRemoveCallback">mxmlEntityRemoveCallback</a></li>
|
|
<li><a href="#mxmlFindElement">mxmlFindElement</a></li>
|
|
<li><a href="#mxmlFindPath">mxmlFindPath</a></li>
|
|
<li><a href="#mxmlGetCDATA">mxmlGetCDATA</a></li>
|
|
<li><a href="#mxmlGetComment">mxmlGetComment</a></li>
|
|
<li><a href="#mxmlGetCustom">mxmlGetCustom</a></li>
|
|
<li><a href="#mxmlGetDeclaration">mxmlGetDeclaration</a></li>
|
|
<li><a href="#mxmlGetDirective">mxmlGetDirective</a></li>
|
|
<li><a href="#mxmlGetElement">mxmlGetElement</a></li>
|
|
<li><a href="#mxmlGetFirstChild">mxmlGetFirstChild</a></li>
|
|
<li><a href="#mxmlGetInteger">mxmlGetInteger</a></li>
|
|
<li><a href="#mxmlGetLastChild">mxmlGetLastChild</a></li>
|
|
<li><a href="#mxmlGetNextSibling">mxmlGetNextSibling</a></li>
|
|
<li><a href="#mxmlGetOpaque">mxmlGetOpaque</a></li>
|
|
<li><a href="#mxmlGetParent">mxmlGetParent</a></li>
|
|
<li><a href="#mxmlGetPrevSibling">mxmlGetPrevSibling</a></li>
|
|
<li><a href="#mxmlGetReal">mxmlGetReal</a></li>
|
|
<li><a href="#mxmlGetRefCount">mxmlGetRefCount</a></li>
|
|
<li><a href="#mxmlGetText">mxmlGetText</a></li>
|
|
<li><a href="#mxmlGetType">mxmlGetType</a></li>
|
|
<li><a href="#mxmlGetUserData">mxmlGetUserData</a></li>
|
|
<li><a href="#mxmlIndexDelete">mxmlIndexDelete</a></li>
|
|
<li><a href="#mxmlIndexEnum">mxmlIndexEnum</a></li>
|
|
<li><a href="#mxmlIndexFind">mxmlIndexFind</a></li>
|
|
<li><a href="#mxmlIndexGetCount">mxmlIndexGetCount</a></li>
|
|
<li><a href="#mxmlIndexNew">mxmlIndexNew</a></li>
|
|
<li><a href="#mxmlIndexReset">mxmlIndexReset</a></li>
|
|
<li><a href="#mxmlLoadFd">mxmlLoadFd</a></li>
|
|
<li><a href="#mxmlLoadFile">mxmlLoadFile</a></li>
|
|
<li><a href="#mxmlLoadString">mxmlLoadString</a></li>
|
|
<li><a href="#mxmlNewCDATA">mxmlNewCDATA</a></li>
|
|
<li><a href="#mxmlNewCDATAf">mxmlNewCDATAf</a></li>
|
|
<li><a href="#mxmlNewComment">mxmlNewComment</a></li>
|
|
<li><a href="#mxmlNewCommentf">mxmlNewCommentf</a></li>
|
|
<li><a href="#mxmlNewCustom">mxmlNewCustom</a></li>
|
|
<li><a href="#mxmlNewDeclaration">mxmlNewDeclaration</a></li>
|
|
<li><a href="#mxmlNewDeclarationf">mxmlNewDeclarationf</a></li>
|
|
<li><a href="#mxmlNewDirective">mxmlNewDirective</a></li>
|
|
<li><a href="#mxmlNewDirectivef">mxmlNewDirectivef</a></li>
|
|
<li><a href="#mxmlNewElement">mxmlNewElement</a></li>
|
|
<li><a href="#mxmlNewInteger">mxmlNewInteger</a></li>
|
|
<li><a href="#mxmlNewOpaque">mxmlNewOpaque</a></li>
|
|
<li><a href="#mxmlNewOpaquef">mxmlNewOpaquef</a></li>
|
|
<li><a href="#mxmlNewReal">mxmlNewReal</a></li>
|
|
<li><a href="#mxmlNewText">mxmlNewText</a></li>
|
|
<li><a href="#mxmlNewTextf">mxmlNewTextf</a></li>
|
|
<li><a href="#mxmlNewXML">mxmlNewXML</a></li>
|
|
<li><a href="#mxmlRelease">mxmlRelease</a></li>
|
|
<li><a href="#mxmlRemove">mxmlRemove</a></li>
|
|
<li><a href="#mxmlRetain">mxmlRetain</a></li>
|
|
<li><a href="#mxmlSAXLoadFd">mxmlSAXLoadFd</a></li>
|
|
<li><a href="#mxmlSAXLoadFile">mxmlSAXLoadFile</a></li>
|
|
<li><a href="#mxmlSAXLoadString">mxmlSAXLoadString</a></li>
|
|
<li><a href="#mxmlSaveAllocString">mxmlSaveAllocString</a></li>
|
|
<li><a href="#mxmlSaveFd">mxmlSaveFd</a></li>
|
|
<li><a href="#mxmlSaveFile">mxmlSaveFile</a></li>
|
|
<li><a href="#mxmlSaveString">mxmlSaveString</a></li>
|
|
<li><a href="#mxmlSetCDATA">mxmlSetCDATA</a></li>
|
|
<li><a href="#mxmlSetCDATAf">mxmlSetCDATAf</a></li>
|
|
<li><a href="#mxmlSetComment">mxmlSetComment</a></li>
|
|
<li><a href="#mxmlSetCommentf">mxmlSetCommentf</a></li>
|
|
<li><a href="#mxmlSetCustom">mxmlSetCustom</a></li>
|
|
<li><a href="#mxmlSetCustomHandlers">mxmlSetCustomHandlers</a></li>
|
|
<li><a href="#mxmlSetDeclaration">mxmlSetDeclaration</a></li>
|
|
<li><a href="#mxmlSetDeclarationf">mxmlSetDeclarationf</a></li>
|
|
<li><a href="#mxmlSetDirective">mxmlSetDirective</a></li>
|
|
<li><a href="#mxmlSetDirectivef">mxmlSetDirectivef</a></li>
|
|
<li><a href="#mxmlSetElement">mxmlSetElement</a></li>
|
|
<li><a href="#mxmlSetErrorCallback">mxmlSetErrorCallback</a></li>
|
|
<li><a href="#mxmlSetInteger">mxmlSetInteger</a></li>
|
|
<li><a href="#mxmlSetOpaque">mxmlSetOpaque</a></li>
|
|
<li><a href="#mxmlSetOpaquef">mxmlSetOpaquef</a></li>
|
|
<li><a href="#mxmlSetReal">mxmlSetReal</a></li>
|
|
<li><a href="#mxmlSetText">mxmlSetText</a></li>
|
|
<li><a href="#mxmlSetTextf">mxmlSetTextf</a></li>
|
|
<li><a href="#mxmlSetUserData">mxmlSetUserData</a></li>
|
|
<li><a href="#mxmlSetWrapMargin">mxmlSetWrapMargin</a></li>
|
|
<li><a href="#mxmlWalkNext">mxmlWalkNext</a></li>
|
|
<li><a href="#mxmlWalkPrev">mxmlWalkPrev</a></li>
|
|
</ul></li>
|
|
<li><a href="#TYPES">Data Types</a><ul class="subcontents">
|
|
<li><a href="#mxml_custom_destroy_cb_t">mxml_custom_destroy_cb_t</a></li>
|
|
<li><a href="#mxml_custom_load_cb_t">mxml_custom_load_cb_t</a></li>
|
|
<li><a href="#mxml_custom_save_cb_t">mxml_custom_save_cb_t</a></li>
|
|
<li><a href="#mxml_entity_cb_t">mxml_entity_cb_t</a></li>
|
|
<li><a href="#mxml_error_cb_t">mxml_error_cb_t</a></li>
|
|
<li><a href="#mxml_index_t">mxml_index_t</a></li>
|
|
<li><a href="#mxml_load_cb_t">mxml_load_cb_t</a></li>
|
|
<li><a href="#mxml_node_t">mxml_node_t</a></li>
|
|
<li><a href="#mxml_save_cb_t">mxml_save_cb_t</a></li>
|
|
<li><a href="#mxml_sax_cb_t">mxml_sax_cb_t</a></li>
|
|
<li><a href="#mxml_sax_event_t">mxml_sax_event_t</a></li>
|
|
<li><a href="#mxml_type_t">mxml_type_t</a></li>
|
|
</ul></li>
|
|
<li><a href="#ENUMERATIONS">Enumerations</a><ul class="subcontents">
|
|
<li><a href="#mxml_sax_event_e">mxml_sax_event_e</a></li>
|
|
<li><a href="#mxml_type_e">mxml_type_e</a></li>
|
|
</ul></li>
|
|
</ul>
|
|
</div>
|
|
<div class="body">
|
|
<h2 class="title" id="introduction">Introduction</h2>
|
|
<p>Mini-XML is a small XML parsing library that you can use to read XML data files or strings in your application without requiring large non-standard libraries. Mini-XML provides the following functionality:</p>
|
|
<ul>
|
|
<li><p>Reading of UTF-8 and UTF-16 and writing of UTF-8 encoded XML files and strings.</p>
|
|
</li>
|
|
<li><p>Data is stored in a linked-list tree structure, preserving the XML data hierarchy.</p>
|
|
</li>
|
|
<li><p>SAX (streamed) reading of XML files and strings to minimize memory usage.</p>
|
|
</li>
|
|
<li><p>Supports arbitrary element names, attributes, and attribute values with no preset limits, just available memory.</p>
|
|
</li>
|
|
<li><p>Supports integer, real, opaque ("CDATA"), and text data types in "leaf" nodes.</p>
|
|
</li>
|
|
<li><p>Functions for creating and managing trees of data.</p>
|
|
</li>
|
|
<li><p>"Find" and "walk" functions for easily locating and navigating trees of data.</p>
|
|
</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.</p>
|
|
<h3 class="title" id="history">History</h3>
|
|
<p>Mini-XML was initially developed for the <a href="http://gutenprint.sf.net/">Gutenprint</a> project to replace the rather large and unwieldy <code>libxml2</code> library with something substantially smaller and easier-to-use. It all began one morning in June of 2003 when Robert posted the following sentence to the developer's list:</p>
|
|
<blockquote>
|
|
<p>It's bad enough that we require libxml2, but rolling our own XML parser is a bit more than we can handle.</p>
|
|
</blockquote>
|
|
<p>I then replied with:</p>
|
|
<blockquote>
|
|
<p>Given the limited scope of what you use in XML, it should be trivial to code a mini-XML API in a few hundred lines of code.</p>
|
|
</blockquote>
|
|
<p>I took my own challenge and coded furiously for two days to produced the initial public release of Mini-XML, total lines of code: 696. Robert promptly integrated Mini-XML into Gutenprint and removed libxml2.</p>
|
|
<p>Thanks to lots of feedback and support from various developers, Mini-XML has evolved since then to provide a more complete XML implementation and now stands at a whopping 4,371 lines of code, compared to 175,808 lines of code for libxml2 version 2.11.7.</p>
|
|
<h3 class="title" id="resources">Resources</h3>
|
|
<p>The Mini-XML home page can be found at <a href="https://www.msweet.org/mxml">https://www.msweet.org/mxml</a>. From there you can download the current version of Mini-XML, access the issue tracker, and find other resources.</p>
|
|
<h3 class="title" id="legal-stuff">Legal Stuff</h3>
|
|
<p>The Mini-XML library is copyright © 2003-2024 by Michael R Sweet and is provided under the Apache License Version 2.0 with an (optional) exception to allow linking against GPL2/LGPL2-only software. See the files "LICENSE" and "NOTICE" for more information.</p>
|
|
<h2 class="title" id="using-mini-xml">Using Mini-XML</h2>
|
|
<p>Mini-XML provides a single header file which you include:</p>
|
|
<pre><code class="language-c"><span class="directive">#include <mxml.h></span>
|
|
</code></pre>
|
|
<p>The Mini-XML library is included with your program using the <code>-lmxml</code> option:</p>
|
|
<pre><code>gcc -o myprogram myprogram.c -lmxml
|
|
</code></pre>
|
|
<p>If you have the <code>pkg-config</code> software installed, you can use it to determine the proper compiler and linker options for your installation:</p>
|
|
<pre><code>gcc `pkg-config --cflags mxml4` -o myprogram myprogram.c `pkg-config --libs mxml4`
|
|
</code></pre>
|
|
<h3 class="title" id="loading-an-xml-file">Loading an XML File</h3>
|
|
<p>You load an XML file using the <code>mxmlLoadFile</code> function:</p>
|
|
<pre><code class="language-c">mxml_node_t *
|
|
mxmlLoadFile(mxml_node_t *top, FILE *fp,
|
|
mxml_type_t (*cb)(mxml_node_t *));
|
|
</code></pre>
|
|
<p>The <code>cb</code> argument specifies a function that assigns child (value) node types for each element in the document. The callback can be a function you provide or one of the standard functions provided with Mini-XML. For example, to load the XML file "filename.xml" containing text strings you can use the <code>MXML_OPAQUE_CALLBACK</code> function:</p>
|
|
<pre><code class="language-c">FILE *fp;
|
|
mxml_node_t *tree;
|
|
|
|
fp = fopen(<span class="string">"filename.xml"</span>, <span class="string">"r"</span>);
|
|
tree = mxmlLoadFile(NULL, fp, MXML_OPAQUE_CALLBACK);
|
|
fclose(fp);
|
|
</code></pre>
|
|
<p>Mini-XML also provides functions to load from a file descriptor or string:</p>
|
|
<pre><code class="language-c">mxml_node_t *
|
|
mxmlLoadFd(mxml_node_t *top, <span class="reserved">int</span> fd,
|
|
mxml_type_t (*cb)(mxml_node_t *));
|
|
|
|
mxml_node_t *
|
|
mxmlLoadString(mxml_node_t *top, <span class="reserved">const</span> <span class="reserved">char</span> *s,
|
|
mxml_type_t (*cb)(mxml_node_t *));
|
|
</code></pre>
|
|
<h4 id="load-callbacks">Load Callbacks</h4>
|
|
<p>The last argument to the <code>mxmlLoad</code> functions is a callback function which is used to determine the value type of each data node in an XML document. Mini-XML defines several standard callbacks for simple XML data files:</p>
|
|
<ul>
|
|
<li><p><code>MXML_INTEGER_CALLBACK</code>: All data nodes contain whitespace-separated integers.</p>
|
|
</li>
|
|
<li><p><code>MXML_OPAQUE_CALLBACK</code>: All data nodes contain opaque strings with whitespace preserved.</p>
|
|
</li>
|
|
<li><p><code>MXML_REAL_CALLBACK</code> - All data nodes contain whitespace-separated floating-point numbers.</p>
|
|
</li>
|
|
<li><p><code>MXML_TEXT_CALLBACK</code> - All data nodes contain whitespace-separated strings.</p>
|
|
</li>
|
|
</ul>
|
|
<p>You can provide your own callback functions for more complex XML documents. Your callback function will receive a pointer to the current element node and must return the value type of the immediate children for that element node: <code>MXML_TYPE_CUSTOM</code>, <code>MXML_TYPE_INTEGER</code>, <code>MXML_TYPE_OPAQUE</code>, <code>MXML_TYPE_REAL</code>, or <code>MXML_TYPE_TEXT</code>. The function is called <em>after</em> 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.</p>
|
|
<p>The following callback function looks for an attribute named "type" or the element name to determine the value type for its child nodes:</p>
|
|
<pre><code class="language-c">mxml_type_t
|
|
type_cb(mxml_node_t *node)
|
|
{
|
|
<span class="reserved">const</span> <span class="reserved">char</span> *type;
|
|
|
|
<span class="comment">/*</span>
|
|
<span class="comment"> * You can lookup attributes and/or use the element name,</span>
|
|
<span class="comment"> * hierarchy, etc...</span>
|
|
<span class="comment"> */</span>
|
|
|
|
type = mxmlElementGetAttr(node, <span class="string">"type"</span>);
|
|
<span class="reserved">if</span> (type == NULL)
|
|
type = mxmlGetElement(node);
|
|
|
|
<span class="reserved">if</span> (!strcmp(type, <span class="string">"integer"</span>))
|
|
<span class="reserved">return</span> (MXML_TYPE_INTEGER);
|
|
<span class="reserved">else</span> <span class="reserved">if</span> (!strcmp(type, <span class="string">"opaque"</span>))
|
|
<span class="reserved">return</span> (MXML_TYPE_OPAQUE);
|
|
<span class="reserved">else</span> <span class="reserved">if</span> (!strcmp(type, <span class="string">"real"</span>))
|
|
<span class="reserved">return</span> (MXML_TYPE_REAL);
|
|
<span class="reserved">else</span>
|
|
<span class="reserved">return</span> (MXML_TYPE_TEXT);
|
|
}
|
|
</code></pre>
|
|
<p>To use this callback function, simply use the name when you call any of the load functions:</p>
|
|
<pre><code class="language-c">FILE *fp;
|
|
mxml_node_t *tree;
|
|
|
|
fp = fopen(<span class="string">"filename.xml"</span>, <span class="string">"r"</span>);
|
|
tree = mxmlLoadFile(NULL, fp, type_cb);
|
|
fclose(fp);
|
|
</code></pre>
|
|
<h3 class="title" id="nodes">Nodes</h3>
|
|
<p>Every piece of information in an XML file is stored in memory in "nodes". Nodes are defined by the <code>mxml_node_t</code> structure. Each node has a typed value, optional user data, a parent node, sibling nodes (previous and next), and potentially child nodes.</p>
|
|
<p>For example, if you have an XML file like the following:</p>
|
|
<pre><code><?xml version="1.0" encoding="utf-8"?>
|
|
<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>
|
|
</data>
|
|
</code></pre>
|
|
<p>the node tree for the file would look like the following in memory:</p>
|
|
<pre><code>?xml version="1.0" encoding="utf-8"?
|
|
|
|
|
data
|
|
|
|
|
node - node - node - group - node - node
|
|
| | | | | |
|
|
val1 val2 val3 | val7 val8
|
|
|
|
|
node - node - node
|
|
| | |
|
|
val4 val5 val6
|
|
</code></pre>
|
|
<p>where "-" is a pointer to the sibling node and "|" is a pointer to the first child or parent node.</p>
|
|
<p>The <code>mxmlGetType</code> function gets the type of a node:</p>
|
|
<pre><code class="language-c">mxml_type_t
|
|
mxmlGetType(mxml_node_t *node);
|
|
</code></pre>
|
|
<ul>
|
|
<li><p><code>MXML_TYPE_CDATA</code> : CDATA,</p>
|
|
</li>
|
|
<li><p><code>MXML_TYPE_COMMENT</code> : A comment,</p>
|
|
</li>
|
|
<li><p><code>MXML_TYPE_CUSTOM</code> : A custom value defined by your application,</p>
|
|
</li>
|
|
<li><p><code>MXML_TYPE_DECLARATION</code> : A declaration such as <code><!DOCTYPE html></code>,</p>
|
|
</li>
|
|
<li><p><code>MXML_TYPE_DIRECTIVE</code> : A processing instruction such as <code><?xml version="1.0"?></code>,</p>
|
|
</li>
|
|
<li><p><code>MXML_TYPE_ELEMENT</code> : An XML element,</p>
|
|
</li>
|
|
<li><p><code>MXML_TYPE_INTEGER</code> : A whitespace-delimited integer value,</p>
|
|
</li>
|
|
<li><p><code>MXML_TYPE_OPAQUE</code> : An opaque string value that preserves all whitespace,</p>
|
|
</li>
|
|
<li><p><code>MXML_TYPE_REAL</code> : A whitespace-delimited floating point value, or</p>
|
|
</li>
|
|
<li><p><code>MXML_TYPE_TEXT</code> : A whitespace-delimited text (fragment) value.</p>
|
|
</li>
|
|
</ul>
|
|
<p>The parent and sibling nodes are accessed using the <code>mxmlGetParent</code>, <code>mxmlGetNextSibling</code>, and <code>mxmlGetPreviousSibling</code> functions, while the children of an element node are accessed using the <code>mxmlGetFirstChild</code> or <code>mxmlGetLastChild</code> functions:</p>
|
|
<pre><code class="language-c">mxml_node_t *
|
|
mxmlGetFirstChild(mxml_node_t *node);
|
|
|
|
mxml_node_t *
|
|
mxmlGetLastChild(mxml_node_t *node);
|
|
|
|
mxml_node_t *
|
|
mxmlGetNextSibling(mxml_node_t *node);
|
|
|
|
mxml_node_t *
|
|
mxmlGetParent(mxml_node_t *node);
|
|
|
|
mxml_node_t *
|
|
mxmlGetPrevSibling(mxml_node_t *node);
|
|
</code></pre>
|
|
<p>The <code>mxmlGetUserData</code> function gets any user (application) data associated with the node:</p>
|
|
<pre><code class="language-c"><span class="reserved">void</span> *
|
|
mxmlGetUserData(mxml_node_t *node);
|
|
</code></pre>
|
|
<h3 class="title" id="creating-xml-documents">Creating XML Documents</h3>
|
|
<p>You can create and update XML documents in memory using the various <code>mxmlNew</code> functions. The following code will create the XML document described in the previous section:</p>
|
|
<pre><code class="language-c">mxml_node_t *xml; <span class="comment">/* <?xml ... ?> */</span>
|
|
mxml_node_t *data; <span class="comment">/* <data> */</span>
|
|
mxml_node_t *node; <span class="comment">/* <node> */</span>
|
|
mxml_node_t *group; <span class="comment">/* <group> */</span>
|
|
|
|
xml = mxmlNewXML(<span class="string">"1.0"</span>);
|
|
|
|
data = mxmlNewElement(xml, <span class="string">"data"</span>);
|
|
|
|
node = mxmlNewElement(data, <span class="string">"node"</span>);
|
|
mxmlNewText(node, <span class="reserved">false</span>, <span class="string">"val1"</span>);
|
|
node = mxmlNewElement(data, <span class="string">"node"</span>);
|
|
mxmlNewText(node, <span class="reserved">false</span>, <span class="string">"val2"</span>);
|
|
node = mxmlNewElement(data, <span class="string">"node"</span>);
|
|
mxmlNewText(node, <span class="reserved">false</span>, <span class="string">"val3"</span>);
|
|
|
|
group = mxmlNewElement(data, <span class="string">"group"</span>);
|
|
|
|
node = mxmlNewElement(group, <span class="string">"node"</span>);
|
|
mxmlNewText(node, <span class="reserved">false</span>, <span class="string">"val4"</span>);
|
|
node = mxmlNewElement(group, <span class="string">"node"</span>);
|
|
mxmlNewText(node, <span class="reserved">false</span>, <span class="string">"val5"</span>);
|
|
node = mxmlNewElement(group, <span class="string">"node"</span>);
|
|
mxmlNewText(node, <span class="reserved">false</span>, <span class="string">"val6"</span>);
|
|
|
|
node = mxmlNewElement(data, <span class="string">"node"</span>);
|
|
mxmlNewText(node, <span class="reserved">false</span>, <span class="string">"val7"</span>);
|
|
node = mxmlNewElement(data, <span class="string">"node"</span>);
|
|
mxmlNewText(node, <span class="reserved">false</span>, <span class="string">"val8"</span>);
|
|
</code></pre>
|
|
<p>We start by creating the declaration node common to all XML files using the <code>mxmlNewXML</code> function:</p>
|
|
<pre><code class="language-c">xml = mxmlNewXML(<span class="string">"1.0"</span>);
|
|
</code></pre>
|
|
<p>We then create the <code><data></code> node used for this document using the <code>mxmlNewElement</code> function. The first argument specifies the parent node (<code>xml</code>) while the second specifies the element name (<code>data</code>):</p>
|
|
<pre><code class="language-c">data = mxmlNewElement(xml, <span class="string">"data"</span>);
|
|
</code></pre>
|
|
<p>Each <code><node>...</node></code> in the file is created using the <code>mxmlNewElement</code> and <code>mxmlNewText</code> functions. The first argument of <code>mxmlNewText</code> specifies the parent node (<code>node</code>). The second argument specifies whether whitespace appears before the text - 0 or false in this case. The last argument specifies the actual text to add:</p>
|
|
<pre><code class="language-c">node = mxmlNewElement(data, <span class="string">"node"</span>);
|
|
mxmlNewText(node, <span class="reserved">false</span>, <span class="string">"val1"</span>);
|
|
</code></pre>
|
|
<p>The resulting in-memory XML document can then be saved or processed just like one loaded from disk or a string.</p>
|
|
<h3 class="title" id="saving-an-xml-file">Saving an XML File</h3>
|
|
<p>You save an XML file using the <code>mxmlSaveFile</code> function:</p>
|
|
<pre><code class="language-c"><span class="reserved">bool</span>
|
|
mxmlSaveFile(mxml_node_t *node, FILE *fp,
|
|
mxml_save_cb_t cb);
|
|
</code></pre>
|
|
<p>The <code>cb</code> argument specifies a function that returns the whitespace (if any) that is inserted before and after each element node. The <code>MXML_NO_CALLBACK</code> constant tells Mini-XML to not include any extra whitespace. For example, so save an XML file to the file "filename.xml" with no extra whitespace:</p>
|
|
<pre><code class="language-c">FILE *fp;
|
|
|
|
fp = fopen(<span class="string">"filename.xml"</span>, <span class="string">"w"</span>);
|
|
mxmlSaveFile(xml, fp, MXML_NO_CALLBACK);
|
|
fclose(fp);
|
|
</code></pre>
|
|
<p>Mini-XML also provides functions to save to a file descriptor or strings:</p>
|
|
<pre><code class="language-c"><span class="reserved">char</span> *
|
|
mxmlSaveAllocString(mxml_node_t *node, mxml_save_cb_t cb);
|
|
|
|
<span class="reserved">bool</span>
|
|
mxmlSaveFd(mxml_node_t *node, <span class="reserved">int</span> fd, mxml_save_cb_t cb);
|
|
|
|
size_t
|
|
mxmlSaveString(mxml_node_t *node, <span class="reserved">char</span> *buffer, size_t bufsize,
|
|
mxml_save_cb_t cb);
|
|
</code></pre>
|
|
<h4 id="controlling-line-wrapping">Controlling Line Wrapping</h4>
|
|
<p>When saving XML documents, Mini-XML normally wraps output lines at column 75 so that the text is readable in terminal windows. The <code>mxmlSetWrapMargin</code> function overrides the default wrap margin for the current thread:</p>
|
|
<pre><code class="language-c"><span class="reserved">void</span> mxmlSetWrapMargin(<span class="reserved">int</span> column);
|
|
</code></pre>
|
|
<p>For example, the following code sets the margin to 132 columns:</p>
|
|
<pre><code class="language-c">mxmlSetWrapMargin(<span class="number">132</span>);
|
|
</code></pre>
|
|
<p>while the following code disables wrapping by setting the margin to 0:</p>
|
|
<pre><code class="language-c">mxmlSetWrapMargin(<span class="number">0</span>);
|
|
</code></pre>
|
|
<h4 id="save-callbacks">Save Callbacks</h4>
|
|
<p>The last argument to the <code>mxmlSave</code> functions is a callback function which is used to automatically insert whitespace in an XML document. Your callback function will be called up to four times for each element node with a pointer to the node and a "where" value of <code>MXML_WS_BEFORE_OPEN</code>, <code>MXML_WS_AFTER_OPEN</code>, <code>MXML_WS_BEFORE_CLOSE</code>, or <code>MXML_WS_AFTER_CLOSE</code>. The callback function should return <code>NULL</code> if no whitespace should be added or the string to insert (spaces, tabs, carriage returns, and newlines) otherwise.</p>
|
|
<p>The following whitespace callback can be used to add whitespace to XHTML output to make it more readable in a standard text editor:</p>
|
|
<pre><code class="language-c"><span class="reserved">const</span> <span class="reserved">char</span> *
|
|
whitespace_cb(mxml_node_t *node, <span class="reserved">int</span> where)
|
|
{
|
|
<span class="reserved">const</span> <span class="reserved">char</span> *element;
|
|
|
|
<span class="comment">/*</span>
|
|
<span class="comment"> * We can conditionally break to a new line before or after</span>
|
|
<span class="comment"> * any element. These are just common HTML elements...</span>
|
|
<span class="comment"> */</span>
|
|
|
|
element = mxmlGetElement(node);
|
|
|
|
<span class="reserved">if</span> (!strcmp(element, <span class="string">"html"</span>) ||
|
|
!strcmp(element, <span class="string">"head"</span>) ||
|
|
!strcmp(element, <span class="string">"body"</span>) ||
|
|
!strcmp(element, <span class="string">"pre"</span>) ||
|
|
!strcmp(element, <span class="string">"p"</span>) ||
|
|
!strcmp(element, <span class="string">"h1"</span>) ||
|
|
!strcmp(element, <span class="string">"h2"</span>) ||
|
|
!strcmp(element, <span class="string">"h3"</span>) ||
|
|
!strcmp(element, <span class="string">"h4"</span>) ||
|
|
!strcmp(element, <span class="string">"h5"</span>) ||
|
|
!strcmp(element, <span class="string">"h6"</span>))
|
|
{
|
|
<span class="comment">/*</span>
|
|
<span class="comment"> * Newlines before open and after close...</span>
|
|
<span class="comment"> */</span>
|
|
|
|
<span class="reserved">if</span> (where == MXML_WS_BEFORE_OPEN ||
|
|
where == MXML_WS_AFTER_CLOSE)
|
|
<span class="reserved">return</span> (<span class="string">"\n"</span>);
|
|
}
|
|
<span class="reserved">else</span> <span class="reserved">if</span> (!strcmp(element, <span class="string">"dl"</span>) ||
|
|
!strcmp(element, <span class="string">"ol"</span>) ||
|
|
!strcmp(element, <span class="string">"ul"</span>))
|
|
{
|
|
<span class="comment">/*</span>
|
|
<span class="comment"> * Put a newline before and after list elements...</span>
|
|
<span class="comment"> */</span>
|
|
|
|
<span class="reserved">return</span> (<span class="string">"\n"</span>);
|
|
}
|
|
<span class="reserved">else</span> <span class="reserved">if</span> (!strcmp(element, <span class="string">"dd"</span>) ||
|
|
!strcmp(element, <span class="string">"dt"</span>) ||
|
|
!strcmp(element, <span class="string">"li"</span>))
|
|
{
|
|
<span class="comment">/*</span>
|
|
<span class="comment"> * Put a tab before <li>'s, <dd>'s, and <dt>'s, and a</span>
|
|
<span class="comment"> * newline after them...</span>
|
|
<span class="comment"> */</span>
|
|
|
|
<span class="reserved">if</span> (where == MXML_WS_BEFORE_OPEN)
|
|
<span class="reserved">return</span> (<span class="string">"\t"</span>);
|
|
<span class="reserved">else</span> <span class="reserved">if</span> (where == MXML_WS_AFTER_CLOSE)
|
|
<span class="reserved">return</span> (<span class="string">"\n"</span>);
|
|
}
|
|
|
|
<span class="comment">/*</span>
|
|
<span class="comment"> * Otherwise return NULL for no added whitespace...</span>
|
|
<span class="comment"> */</span>
|
|
|
|
<span class="reserved">return</span> (NULL);
|
|
}
|
|
</code></pre>
|
|
<p>To use this callback function, simply use the name when you call any of the save functions:</p>
|
|
<pre><code class="language-c">FILE *fp;
|
|
mxml_node_t *tree;
|
|
|
|
fp = fopen(<span class="string">"filename.xml"</span>, <span class="string">"w"</span>);
|
|
mxmlSaveFile(tree, fp, whitespace_cb);
|
|
fclose(fp);
|
|
</code></pre>
|
|
<h3 class="title" id="memory-management">Memory Management</h3>
|
|
<p>Once you are done with the XML data, use the <code>mxmlDelete</code> function to recursively free the memory that is used for a particular node or the entire tree:</p>
|
|
<pre><code class="language-c"><span class="reserved">void</span>
|
|
mxmlDelete(mxml_node_t *tree);
|
|
</code></pre>
|
|
<p>You can also use reference counting to manage memory usage. The <code>mxmlRetain</code> and <code>mxmlRelease</code> functions increment and decrement a node's use count, respectively. When the use count goes to zero, <code>mxmlRelease</code> automatically calls <code>mxmlDelete</code> to actually free the memory used by the node tree. New nodes start with a use count of 1.</p>
|
|
<h2 class="title" id="more-about-nodes">More About Nodes</h2>
|
|
<h3 class="title" id="element-nodes">Element Nodes</h3>
|
|
<p>Element (<code>MXML_TYPE_ELEMENT</code>) nodes are created using the <code>mxmlNewElement</code> function. Element attributes are set using the <code>mxmlElementSetAttr</code> and <code>mxmlElementSetAttrf</code> functions and cleared using the <code>mxmlElementDeleteAttr</code> function:</p>
|
|
<pre><code class="language-c">mxml_node_t *
|
|
mxmlNewElement(mxml_node_t *parent, <span class="reserved">const</span> <span class="reserved">char</span> *name);
|
|
|
|
<span class="reserved">void</span>
|
|
mxmlElementDeleteAttr(mxml_node_t *node, <span class="reserved">const</span> <span class="reserved">char</span> *name);
|
|
|
|
<span class="reserved">void</span>
|
|
mxmlElementSetAttr(mxml_node_t *node, <span class="reserved">const</span> <span class="reserved">char</span> *name,
|
|
<span class="reserved">const</span> <span class="reserved">char</span> *value);
|
|
|
|
<span class="reserved">void</span>
|
|
mxmlElementSetAttrf(mxml_node_t *node, <span class="reserved">const</span> <span class="reserved">char</span> *name,
|
|
<span class="reserved">const</span> <span class="reserved">char</span> *format, ...);
|
|
</code></pre>
|
|
<p>Child nodes are added using the various <code>mxmlNew</code> functions. The top (root) node must be an element, usually created by the <code>mxmlNewXML</code> function:</p>
|
|
<pre><code class="language-c">mxml_node_t *
|
|
mxmlNewXML(<span class="reserved">const</span> <span class="reserved">char</span> *version);
|
|
</code></pre>
|
|
<p>The <code>mxmlGetElement</code> function retrieves the element name, the <code>mxmlElementGetAttr</code> function retrieves the value string for a named attribute associated with the element. The <code>mxmlElementGetAttrByIndex</code> and <code>mxmlElementGetAttrCount</code> functions retrieve attributes by index:</p>
|
|
<pre><code class="language-c"><span class="reserved">const</span> <span class="reserved">char</span> *
|
|
mxmlGetElement(mxml_node_t *node);
|
|
|
|
<span class="reserved">const</span> <span class="reserved">char</span> *
|
|
mxmlElementGetAttr(mxml_node_t *node, <span class="reserved">const</span> <span class="reserved">char</span> *name);
|
|
|
|
<span class="reserved">const</span> <span class="reserved">char</span> *
|
|
mxmlElementGetAttrByIndex(mxml_node_t *node, size_t idx,
|
|
<span class="reserved">const</span> <span class="reserved">char</span> **name);
|
|
|
|
size_t
|
|
mxmlElementGetAttrCount(mxml_node_t *node);
|
|
</code></pre>
|
|
<h3 class="title" id="cdata-nodes">CDATA Nodes</h3>
|
|
<p>CDATA (<code>MXML_TYPE_CDATA</code>) nodes are created using the <code>mxmlNewCDATA</code> function:</p>
|
|
<pre><code>mxml_node_t *mxmlNewCDATA(mxml_node_t *parent, const char *string);
|
|
</code></pre>
|
|
<p>The <code>mxmlGetCDATA</code> function retrieves the CDATA string pointer for a node:</p>
|
|
<pre><code>const char *mxmlGetCDATA(mxml_node_t *node);
|
|
</code></pre>
|
|
<h3 class="title" id="comment-nodes">Comment Nodes</h3>
|
|
<p>Comment (<code>MXML_TYPE_COMMENT</code>) nodes are created using the <code>mxmlNewComment</code> function, for example:</p>
|
|
<pre><code class="language-c">mxml_node_t *node = mxmlNewComment(<span class="string">" This is a comment "</span>);
|
|
</code></pre>
|
|
<p>Similarly, the <code>mxmlGetComment</code> function retrieves the comment string pointer for a node:</p>
|
|
<pre><code class="language-c"><span class="reserved">const</span> <span class="reserved">char</span> *comment = mxmlGetComment(node);
|
|
<span class="comment">/* returns " This is a comment " */</span>
|
|
</code></pre>
|
|
<h3 class="title" id="processing-instruction-nodes">Processing Instruction Nodes</h3>
|
|
<p>Processing instruction (<code>MXML_TYPE_DIRECTIVE</code>) nodes are created using the <code>mxmlNewDirective</code> function:</p>
|
|
<pre><code class="language-c">mxml_node_t *node = mxmlNewDirective(<span class="string">"xml-stylesheet type=\"text/css\" href=\"style.css\""</span>);
|
|
</code></pre>
|
|
<p>The <code>mxmlGetDirective</code> function retrieves the processing instruction string for a node:</p>
|
|
<pre><code class="language-c"><span class="reserved">const</span> <span class="reserved">char</span> *instr = mxmlGetElement(node);
|
|
<span class="comment">/* returns "xml-stylesheet type=\"text/css\" href=\"style.css\"" */</span>
|
|
</code></pre>
|
|
<h3 class="title" id="integer-nodes">Integer Nodes</h3>
|
|
<p>Integer (<code>MXML_TYPE_INTEGER</code>) nodes are created using the <code>mxmlNewInteger</code> function:</p>
|
|
<pre><code class="language-c">mxml_node_t *
|
|
mxmlNewInteger(mxml_node_t *parent, <span class="reserved">long</span> integer);
|
|
</code></pre>
|
|
<p>The <code>mxmlGetInteger</code> function retrieves the integer value for a node:</p>
|
|
<pre><code class="language-c"><span class="reserved">long</span>
|
|
mxmlGetInteger(mxml_node_t *node);
|
|
</code></pre>
|
|
<h3 class="title" id="opaque-string-nodes">Opaque String Nodes</h3>
|
|
<p>Opaque string (<code>MXML_TYPE_OPAQUE</code>) nodes are created using the <code>mxmlNewOpaque</code> function:</p>
|
|
<pre><code class="language-c">mxml_node_t *
|
|
mxmlNewOpaque(mxml_node_t *parent, <span class="reserved">const</span> <span class="reserved">char</span> *opaque);
|
|
</code></pre>
|
|
<p>The <code>mxmlGetOpaque</code> function retrieves the opaque string pointer for a node:</p>
|
|
<pre><code class="language-c"><span class="reserved">const</span> <span class="reserved">char</span> *
|
|
mxmlGetOpaque(mxml_node_t *node);
|
|
</code></pre>
|
|
<h3 class="title" id="text-nodes">Text Nodes</h3>
|
|
<p>Whitespace-delimited text string (<code>MXML_TYPE_TEXT</code>) nodes are created using the <code>mxmlNewText</code> and <code>mxmlNewTextf</code> functions. Each text node consists of a text string and (leading) whitespace boolean value.</p>
|
|
<pre><code class="language-c">mxml_node_t *
|
|
mxmlNewText(mxml_node_t *parent, <span class="reserved">bool</span> whitespace,
|
|
<span class="reserved">const</span> <span class="reserved">char</span> *string);
|
|
|
|
mxml_node_t *
|
|
mxmlNewTextf(mxml_node_t *parent, <span class="reserved">bool</span> whitespace,
|
|
<span class="reserved">const</span> <span class="reserved">char</span> *format, ...);
|
|
</code></pre>
|
|
<p>The <code>mxmlGetText</code> function retrieves the text string pointer and whitespace boolean value for a node:</p>
|
|
<pre><code class="language-c"><span class="reserved">const</span> <span class="reserved">char</span> *
|
|
mxmlGetText(mxml_node_t *node, <span class="reserved">bool</span> *whitespace);
|
|
</code></pre>
|
|
<h3 class="title" id="real-number-nodes">Real Number Nodes</h3>
|
|
<p>Real number (<code>MXML_TYPE_REAL</code>) nodes are created using the <code>mxmlNewReal</code> function:</p>
|
|
<pre><code class="language-c">mxml_node_t *
|
|
mxmlNewReal(mxml_node_t *parent, <span class="reserved">double</span> real);
|
|
</code></pre>
|
|
<p>The <code>mxmlGetReal</code> function retrieves the real number for a node:</p>
|
|
<pre><code class="language-c"><span class="reserved">double</span>
|
|
mxmlGetReal(mxml_node_t *node);
|
|
</code></pre>
|
|
<h2 class="title" id="locating-data-in-an-xml-document">Locating Data in an XML Document</h2>
|
|
<p>Mini-XML provides many functions for enumerating, searching, and indexing XML documents.</p>
|
|
<h3 class="title" id="finding-nodes">Finding Nodes</h3>
|
|
<p>The <code>mxmlFindPath</code> function finds the (first) value node under a specific element using a "path":</p>
|
|
<pre><code class="language-c">mxml_node_t *
|
|
mxmlFindPath(mxml_node_t *node, <span class="reserved">const</span> <span class="reserved">char</span> *path);
|
|
</code></pre>
|
|
<p>The <code>path</code> string can contain the "*" wildcard to match a single element node in the hierarchy. For example, the following code will find the first "node" element under the "group" element, first using an explicit path and then using a wildcard:</p>
|
|
<pre><code class="language-c">mxml_node_t *value = mxmlFindPath(xml, <span class="string">"data/group/node"</span>);
|
|
|
|
mxml_node_t *value = mxmlFindPath(xml, <span class="string">"data/*/node"</span>);
|
|
</code></pre>
|
|
<p>The <code>mxmlFindElement</code> function can be used to find a named element, optionally matching an attribute and value:</p>
|
|
<pre><code class="language-c">mxml_node_t *
|
|
mxmlFindElement(mxml_node_t *node, mxml_node_t *top,
|
|
<span class="reserved">const</span> <span class="reserved">char</span> *element, <span class="reserved">const</span> <span class="reserved">char</span> *attr,
|
|
<span class="reserved">const</span> <span class="reserved">char</span> *value, <span class="reserved">int</span> descend);
|
|
</code></pre>
|
|
<p>The "element", "attr", and "value" arguments can be passed as <code>NULL</code> to act as wildcards, e.g.:</p>
|
|
<pre><code class="language-c"><span class="comment">/* Find the first "a" element */</span>
|
|
node = mxmlFindElement(tree, tree, <span class="string">"a"</span>, NULL, NULL,
|
|
MXML_DESCEND);
|
|
|
|
<span class="comment">/* Find the first "a" element with "href" attribute */</span>
|
|
node = mxmlFindElement(tree, tree, <span class="string">"a"</span>, <span class="string">"href"</span>, NULL,
|
|
MXML_DESCEND);
|
|
|
|
<span class="comment">/* Find the first "a" element with "href" to a URL */</span>
|
|
node = mxmlFindElement(tree, tree, <span class="string">"a"</span>, <span class="string">"href"</span>,
|
|
<span class="string">"http://michaelrsweet.github.io/"</span>,
|
|
MXML_DESCEND);
|
|
|
|
<span class="comment">/* Find the first element with a "src" attribute*/</span>
|
|
node = mxmlFindElement(tree, tree, NULL, <span class="string">"src"</span>, NULL,
|
|
MXML_DESCEND);
|
|
|
|
<span class="comment">/* Find the first element with a "src" = "foo.jpg" */</span>
|
|
node = mxmlFindElement(tree, tree, NULL, <span class="string">"src"</span>, <span class="string">"foo.jpg"</span>,
|
|
MXML_DESCEND);
|
|
</code></pre>
|
|
<p>You can also iterate with the same function:</p>
|
|
<pre><code class="language-c">mxml_node_t *node;
|
|
|
|
<span class="reserved">for</span> (node = mxmlFindElement(tree, tree, <span class="string">"element"</span>, NULL,
|
|
NULL, MXML_DESCEND);
|
|
node != NULL;
|
|
node = mxmlFindElement(node, tree, <span class="string">"element"</span>, NULL,
|
|
NULL, MXML_DESCEND))
|
|
{
|
|
... <span class="reserved">do</span> something ...
|
|
}
|
|
</code></pre>
|
|
<p>The <code>descend</code> argument (<code>MXML_DESCEND</code> in the examples above) can be one of three constants:</p>
|
|
<ul>
|
|
<li><p><code>MXML_NO_DESCEND</code>: ignore child nodes in the element hierarchy, instead using siblings (same level) or parent nodes (above) until the top (root) node is reached.</p>
|
|
</li>
|
|
<li><p><code>MXML_DESCEND_FIRST</code>: start the search with the first child of the node, and then search siblings. You'll normally use this when iterating through direct children of a parent node, e.g. all of the "node" and "group" elements under the "?xml" parent node in the previous example.</p>
|
|
</li>
|
|
<li><p><code>MXML_DESCEND</code>: search child nodes first, then sibling nodes, and then parent nodes.</p>
|
|
</li>
|
|
</ul>
|
|
<h3 class="title" id="iterating-nodes">Iterating Nodes</h3>
|
|
<p>While the <code>mxmlFindNode</code> and <code>mxmlFindPath</code> functions will find a particular element node, sometimes you need to iterate over all nodes. The <code>mxmlWalkNext</code> and <code>mxmlWalkPrev</code> functions can be used to iterate through the XML node tree:</p>
|
|
<pre><code class="language-c">mxml_node_t *
|
|
mxmlWalkNext(mxml_node_t *node, mxml_node_t *top,
|
|
<span class="reserved">int</span> descend);
|
|
|
|
mxml_node_t *
|
|
mxmlWalkPrev(mxml_node_t *node, mxml_node_t *top,
|
|
<span class="reserved">int</span> descend);
|
|
</code></pre>
|
|
<p>Depending on the value of the <code>descend</code> argument, these functions will automatically traverse child, sibling, and parent nodes until the <code>top</code> node is reached. For example, the following code will iterate over all of the nodes in the sample XML document in the previous section:</p>
|
|
<pre><code class="language-c">mxml_node_t *node;
|
|
|
|
<span class="reserved">for</span> (node = xml;
|
|
node != NULL;
|
|
node = mxmlWalkNext(node, xml, MXML_DESCEND))
|
|
{
|
|
... <span class="reserved">do</span> something ...
|
|
}
|
|
</code></pre>
|
|
<p>The nodes will be returned in the following order:</p>
|
|
<pre><code class="language-c"><?xml version=<span class="string">"1.0"</span> encoding=<span class="string">"utf-8"</span>?>
|
|
<data>
|
|
<node>
|
|
val1
|
|
<node>
|
|
val2
|
|
<node>
|
|
val3
|
|
<group>
|
|
<node>
|
|
val4
|
|
<node>
|
|
val5
|
|
<node>
|
|
val6
|
|
<node>
|
|
val7
|
|
<node>
|
|
val8
|
|
</code></pre>
|
|
<h3 class="title" id="indexing">Indexing</h3>
|
|
<p>The <code>mxmlIndexNew</code> function allows you to create an index of nodes for faster searching and enumeration:</p>
|
|
<pre><code class="language-c">mxml_index_t *
|
|
mxmlIndexNew(mxml_node_t *node, <span class="reserved">const</span> <span class="reserved">char</span> *element,
|
|
<span class="reserved">const</span> <span class="reserved">char</span> *attr);
|
|
</code></pre>
|
|
<p>The <code>element</code> and <code>attr</code> arguments control which elements are included in the index. If <code>element</code> is not <code>NULL</code> then only elements with the specified name are added to the index. Similarly, if <code>attr</code> is not <code>NULL</code> then only elements containing the specified attribute are added to the index. The nodes are sorted in the index.</p>
|
|
<p>For example, the following code creates an index of all "id" values in an XML document:</p>
|
|
<pre><code class="language-c">mxml_index_t *ind = mxmlIndexNew(xml, NULL, <span class="string">"id"</span>);
|
|
</code></pre>
|
|
<p>Once the index is created, the <code>mxmlIndexFind</code> function can be used to find a matching node:</p>
|
|
<pre><code class="language-c">mxml_node_t *
|
|
mxmlIndexFind(mxml_index_t *ind, <span class="reserved">const</span> <span class="reserved">char</span> *element,
|
|
<span class="reserved">const</span> <span class="reserved">char</span> *value);
|
|
</code></pre>
|
|
<p>For example, the following code will find the element whose "id" string is "42":</p>
|
|
<pre><code class="language-c">mxml_node_t *node = mxmlIndexFind(ind, NULL, <span class="string">"42"</span>);
|
|
</code></pre>
|
|
<p>Alternately, the <code>mxmlIndexReset</code> and <code>mxmlIndexEnum</code> functions can be used to enumerate the nodes in the index:</p>
|
|
<pre><code class="language-c">mxml_node_t *
|
|
mxmlIndexReset(mxml_index_t *ind);
|
|
|
|
mxml_node_t *
|
|
mxmlIndexEnum(mxml_index_t *ind);
|
|
</code></pre>
|
|
<p>Typically these functions will be used in a <code>for</code> loop:</p>
|
|
<pre><code class="language-c">mxml_node_t *node;
|
|
|
|
<span class="reserved">for</span> (node = mxmlIndexReset(ind);
|
|
node != NULL;
|
|
node = mxmlIndexEnum(ind))
|
|
{
|
|
... <span class="reserved">do</span> something ...
|
|
}
|
|
</code></pre>
|
|
<p>The <code>mxmlIndexCount</code> function returns the number of nodes in the index:</p>
|
|
<pre><code class="language-c">size_t
|
|
mxmlIndexGetCount(mxml_index_t *ind);
|
|
</code></pre>
|
|
<p>Finally, the <code>mxmlIndexDelete</code> function frees all memory associated with the index:</p>
|
|
<pre><code class="language-c"><span class="reserved">void</span>
|
|
mxmlIndexDelete(mxml_index_t *ind);
|
|
</code></pre>
|
|
<h2 class="title" id="custom-data-types">Custom Data Types</h2>
|
|
<p>Mini-XML supports -------------------- data types via per-thread load and save callbacks. Only a single set of callbacks can be active at any time for the current thread, however your callbacks can store additional information in order to support multiple -------------------- data types as needed. The <code>MXML_TYPE_CUSTOM</code> node type identifies -------------------- data nodes.</p>
|
|
<p>The <code>mxmlGetCustom</code> function retrieves the -------------------- value pointer for a node.</p>
|
|
<pre><code class="language-c"><span class="reserved">const</span> <span class="reserved">void</span> *
|
|
mxmlGetCustom(mxml_node_t *node);
|
|
</code></pre>
|
|
<p>Custom (<code>MXML_TYPE_CUSTOM</code>) nodes are created using the <code>mxmlNewCustom</code> function or using a -------------------- per-thread load callbacks specified using the <code>mxmlSetCustomHandlers</code> function:</p>
|
|
<pre><code class="language-c"><span class="reserved">typedef</span> <span class="reserved">void</span> (*mxml_
|
|
--------------------_destroy_cb_t)(<span class="reserved">void</span> *);
|
|
<span class="reserved">typedef</span> <span class="reserved">bool</span> (*mxml_
|
|
--------------------_load_cb_t)(mxml_node_t *, <span class="reserved">const</span> <span class="reserved">char</span> *);
|
|
<span class="reserved">typedef</span> <span class="reserved">char</span> *(*mxml_
|
|
--------------------_save_cb_t)(mxml_node_t *);
|
|
|
|
mxml_node_t *
|
|
mxmlNewCustom(mxml_node_t *parent, <span class="reserved">void</span> *data,
|
|
mxml_
|
|
--------------------_destroy_cb_t destroy);
|
|
|
|
<span class="reserved">int</span>
|
|
mxmlSetCustom(mxml_node_t *node, <span class="reserved">void</span> *data,
|
|
mxml_
|
|
--------------------_destroy_cb_t destroy);
|
|
|
|
<span class="reserved">void</span>
|
|
mxmlSetCustomHandlers(mxml_
|
|
--------------------_load_cb_t load,
|
|
mxml_
|
|
--------------------_save_cb_t save);
|
|
</code></pre>
|
|
<p>The load callback receives a pointer to the current data node and a string of opaque character data from the XML source with character entities converted to the corresponding UTF-8 characters. For example, if we wanted to support a</p>
|
|
<p>-------------------- date/time type whose value is encoded as "yyyy-mm-ddThh:mm:ssZ" (ISO format), the load callback would look like the following:</p>
|
|
<pre><code class="language-c"><span class="reserved">typedef</span> <span class="reserved">struct</span>
|
|
{
|
|
<span class="reserved">unsigned</span> year, <span class="comment">/* Year */</span>
|
|
month, <span class="comment">/* Month */</span>
|
|
day, <span class="comment">/* Day */</span>
|
|
hour, <span class="comment">/* Hour */</span>
|
|
minute, <span class="comment">/* Minute */</span>
|
|
second; <span class="comment">/* Second */</span>
|
|
time_t unix; <span class="comment">/* UNIX time */</span>
|
|
} iso_date_time_t;
|
|
|
|
<span class="reserved">bool</span>
|
|
load_
|
|
--------------------(mxml_node_t *node, <span class="reserved">const</span> <span class="reserved">char</span> *data)
|
|
{
|
|
iso_date_time_t *dt;
|
|
<span class="reserved">struct</span> tm tmdata;
|
|
|
|
<span class="comment">/*</span>
|
|
<span class="comment"> * Allocate data structure...</span>
|
|
<span class="comment"> */</span>
|
|
|
|
dt = calloc(<span class="number">1</span>, <span class="reserved">sizeof</span>(iso_date_time_t));
|
|
|
|
<span class="comment">/*</span>
|
|
<span class="comment"> * Try reading 6 unsigned integers from the data string...</span>
|
|
<span class="comment"> */</span>
|
|
|
|
<span class="reserved">if</span> (sscanf(data, <span class="string">"%u-%u-%uT%u:%u:%uZ"</span>, &(dt->year),
|
|
&(dt->month), &(dt->day), &(dt->hour),
|
|
&(dt->minute), &(dt->second)) != <span class="number">6</span>)
|
|
{
|
|
<span class="comment">/*</span>
|
|
<span class="comment"> * Unable to read numbers, free the data structure and</span>
|
|
<span class="comment"> * return an error...</span>
|
|
<span class="comment"> */</span>
|
|
|
|
free(dt);
|
|
|
|
<span class="reserved">return</span> (<span class="reserved">false</span>);
|
|
}
|
|
|
|
<span class="comment">/*</span>
|
|
<span class="comment"> * Range check values...</span>
|
|
<span class="comment"> */</span>
|
|
|
|
<span class="reserved">if</span> (dt->month < <span class="number">1</span> || dt->month > <span class="number">12</span> ||
|
|
dt->day < <span class="number">1</span> || dt->day > <span class="number">31</span> ||
|
|
dt->hour < <span class="number">0</span> || dt->hour > <span class="number">23</span> ||
|
|
dt->minute < <span class="number">0</span> || dt->minute > <span class="number">59</span> ||
|
|
dt->second < <span class="number">0</span> || dt->second > <span class="number">60</span>)
|
|
{
|
|
<span class="comment">/*</span>
|
|
<span class="comment"> * Date information is out of range...</span>
|
|
<span class="comment"> */</span>
|
|
|
|
free(dt);
|
|
|
|
<span class="reserved">return</span> (<span class="reserved">false</span>);
|
|
}
|
|
|
|
<span class="comment">/*</span>
|
|
<span class="comment"> * Convert ISO time to UNIX time in seconds...</span>
|
|
<span class="comment"> */</span>
|
|
|
|
tmdata.tm_year = dt->year - <span class="number">1900</span>;
|
|
tmdata.tm_mon = dt->month - <span class="number">1</span>;
|
|
tmdata.tm_day = dt->day;
|
|
tmdata.tm_hour = dt->hour;
|
|
tmdata.tm_min = dt->minute;
|
|
tmdata.tm_sec = dt->second;
|
|
|
|
dt->unix = gmtime(&tmdata);
|
|
|
|
<span class="comment">/*</span>
|
|
<span class="comment"> * Assign</span>
|
|
<span class="comment">-------------------- node data and destroy (free) function</span>
|
|
<span class="comment"> * pointers...</span>
|
|
<span class="comment"> */</span>
|
|
|
|
mxmlSetCustom(node, data, free);
|
|
|
|
<span class="comment">/*</span>
|
|
<span class="comment"> * Return with no errors...</span>
|
|
<span class="comment"> */</span>
|
|
|
|
<span class="reserved">return</span> (<span class="reserved">true</span>);
|
|
}
|
|
</code></pre>
|
|
<p>The function itself can return <code>true</code> on success or <code>false</code> if it is unable to decode the -------------------- data or the data contains an error. Custom data nodes contain a <code>void</code> pointer to the allocated -------------------- data for the node and a pointer to a destructor function which will free the -------------------- data when the node is deleted. In this example, we use the standard <code>free</code> function since everything is contained in a single calloc'd block.</p>
|
|
<p>The save callback receives the node pointer and returns an allocated string containing the -------------------- data value. The following save callback could be used for our ISO date/time type:</p>
|
|
<pre><code class="language-c"><span class="reserved">char</span> *
|
|
save_
|
|
--------------------(mxml_node_t *node)
|
|
{
|
|
<span class="reserved">char</span> data[<span class="number">255</span>];
|
|
iso_date_time_t *dt;
|
|
|
|
|
|
dt = (iso_date_time_t *)mxmlGetCustom(node);
|
|
|
|
snprintf(data, <span class="reserved">sizeof</span>(data),
|
|
<span class="string">"%04u-%02u-%02uT%02u:%02u:%02uZ"</span>,
|
|
dt->year, dt->month, dt->day, dt->hour,
|
|
dt->minute, dt->second);
|
|
|
|
<span class="reserved">return</span> (strdup(data));
|
|
}
|
|
</code></pre>
|
|
<p>You register the callback functions using the <code>mxmlSetCustomHandlers</code> function:</p>
|
|
<pre><code class="language-c">mxmlSetCustomHandlers(load_
|
|
--------------------, save_
|
|
--------------------);
|
|
</code></pre>
|
|
<h2 class="title" id="sax-stream-loading-of-documents">SAX (Stream) Loading of Documents</h2>
|
|
<p>Mini-XML supports an implementation of the Simple API for XML (SAX) which allows you to load and process an XML document as a stream of nodes. Aside from allowing you to process XML documents of any size, the Mini-XML implementation also allows you to retain portions of the document in memory for later processing.</p>
|
|
<p>The <code>mxmlSAXLoadFd</code>, <code>mxmlSAXLoadFile</code>, and <code>mxmlSAXLoadString</code> functions provide the SAX loading APIs:</p>
|
|
<pre><code class="language-c">mxml_node_t *
|
|
mxmlSAXLoadFd(mxml_node_t *top, <span class="reserved">int</span> fd,
|
|
mxml_type_t (*cb)(mxml_node_t *),
|
|
mxml_sax_cb_t sax, <span class="reserved">void</span> *sax_data);
|
|
|
|
mxml_node_t *
|
|
mxmlSAXLoadFile(mxml_node_t *top, FILE *fp,
|
|
mxml_type_t (*cb)(mxml_node_t *),
|
|
mxml_sax_cb_t sax, <span class="reserved">void</span> *sax_data);
|
|
|
|
mxml_node_t *
|
|
mxmlSAXLoadString(mxml_node_t *top, <span class="reserved">const</span> <span class="reserved">char</span> *s,
|
|
mxml_type_t (*cb)(mxml_node_t *),
|
|
mxml_sax_cb_t sax, <span class="reserved">void</span> *sax_data);
|
|
</code></pre>
|
|
<p>Each function works like the corresponding <code>mxmlLoad</code> function but uses a callback to process each node as it is read. The callback function receives the node, an event code, and a user data pointer you supply and returns <code>true</code> to continue processing or <code>false</code> to stop:</p>
|
|
<pre><code class="language-c"><span class="reserved">bool</span>
|
|
sax_cb(mxml_node_t *node, mxml_sax_event_t event,
|
|
<span class="reserved">void</span> *data)
|
|
{
|
|
... <span class="reserved">do</span> something ...
|
|
|
|
<span class="comment">// Continue processing...</span>
|
|
<span class="reserved">return</span> (<span class="reserved">true</span>);
|
|
}
|
|
</code></pre>
|
|
<p>The event will be one of the following:</p>
|
|
<ul>
|
|
<li><p><code>MXML_SAX_EVENT_CDATA</code>: CDATA was just read.</p>
|
|
</li>
|
|
<li><p><code>MXML_SAX_EVENT_COMMENT</code>: A comment was just read.</p>
|
|
</li>
|
|
<li><p><code>MXML_SAX_EVENT_DATA</code>: Data (integer, opaque, real, or text) was just read.</p>
|
|
</li>
|
|
<li><p><code>MXML_SAX_EVENT_DECLARATION</code>: A declaration was just read.</p>
|
|
</li>
|
|
<li><p><code>MXML_SAX_EVENT_DIRECTIVE</code>: A processing directive/instruction was just read.</p>
|
|
</li>
|
|
<li><p><code>MXML_SAX_EVENT_ELEMENT_CLOSE</code> - A close element was just read (<code></element></code>)</p>
|
|
</li>
|
|
<li><p><code>MXML_SAX_EVENT_ELEMENT_OPEN</code> - An open element was just read (<code><element></code>)</p>
|
|
</li>
|
|
</ul>
|
|
<p>Elements are <em>released</em> after the close element is processed. All other nodes are released after they are processed. The SAX callback can <em>retain</em> the node using the <code>mxmlRetain</code> function. For example, the following SAX callback will retain all nodes, effectively simulating a normal in-memory load:</p>
|
|
<pre><code class="language-c"><span class="reserved">bool</span>
|
|
sax_cb(mxml_node_t *node, mxml_sax_event_t event,
|
|
<span class="reserved">void</span> *data)
|
|
{
|
|
<span class="reserved">if</span> (event != MXML_SAX_ELEMENT_CLOSE)
|
|
mxmlRetain(node);
|
|
|
|
<span class="reserved">return</span> (<span class="reserved">true</span>);
|
|
}
|
|
</code></pre>
|
|
<p>More typically the SAX callback will only retain a small portion of the document that is needed for post-processing. For example, the following SAX callback will retain the title and headings in an XHTML file. It also retains the (parent) elements like <code><html></code>, <code><head></code>, and <code><body></code>, and processing directives like <code><?xml ... ?></code> and declarations like <code><!DOCTYPE ... ></code>:</p>
|
|
<pre><code class="language-c"><span class="reserved">bool</span>
|
|
sax_cb(mxml_node_t *node, mxml_sax_event_t event,
|
|
<span class="reserved">void</span> *data)
|
|
{
|
|
<span class="reserved">if</span> (event == MXML_SAX_ELEMENT_OPEN)
|
|
{
|
|
<span class="comment">/*</span>
|
|
<span class="comment"> * Retain headings and titles...</span>
|
|
<span class="comment"> */</span>
|
|
|
|
<span class="reserved">const</span> <span class="reserved">char</span> *element = mxmlGetElement(node);
|
|
|
|
<span class="reserved">if</span> (!strcmp(element, <span class="string">"html"</span>) ||
|
|
!strcmp(element, <span class="string">"head"</span>) ||
|
|
!strcmp(element, <span class="string">"title"</span>) ||
|
|
!strcmp(element, <span class="string">"body"</span>) ||
|
|
!strcmp(element, <span class="string">"h1"</span>) ||
|
|
!strcmp(element, <span class="string">"h2"</span>) ||
|
|
!strcmp(element, <span class="string">"h3"</span>) ||
|
|
!strcmp(element, <span class="string">"h4"</span>) ||
|
|
!strcmp(element, <span class="string">"h5"</span>) ||
|
|
!strcmp(element, <span class="string">"h6"</span>))
|
|
mxmlRetain(node);
|
|
}
|
|
<span class="reserved">else</span> <span class="reserved">if</span> (event == MXML_SAX_DECLARATION)
|
|
mxmlRetain(node);
|
|
<span class="reserved">else</span> <span class="reserved">if</span> (event == MXML_SAX_DIRECTIVE)
|
|
mxmlRetain(node);
|
|
<span class="reserved">else</span> <span class="reserved">if</span> (event == MXML_SAX_DATA)
|
|
{
|
|
<span class="reserved">if</span> (mxmlGetRefCount(mxmlGetParent(node)) > <span class="number">1</span>)
|
|
{
|
|
<span class="comment">/*</span>
|
|
<span class="comment"> * If the parent was retained, then retain this data</span>
|
|
<span class="comment"> * node as well.</span>
|
|
<span class="comment"> */</span>
|
|
|
|
mxmlRetain(node);
|
|
}
|
|
}
|
|
|
|
<span class="reserved">return</span> (<span class="reserved">true</span>);
|
|
}
|
|
</code></pre>
|
|
<p>The resulting skeleton document tree can then be searched just like one loaded using the <code>mxmlLoad</code> functions. For example, a filter that reads an XHTML document from stdin and then shows the title and headings in the document would look like:</p>
|
|
<pre><code class="language-c">mxml_node_t *doc, *title, *body, *heading;
|
|
|
|
doc = mxmlSAXLoadFd(NULL, <span class="number">0</span>, MXML_TEXT_CALLBACK, sax_cb,
|
|
NULL);
|
|
|
|
title = mxmlFindElement(doc, doc, <span class="string">"title"</span>, NULL, NULL,
|
|
MXML_DESCEND);
|
|
|
|
<span class="reserved">if</span> (title)
|
|
print_children(title);
|
|
|
|
body = mxmlFindElement(doc, doc, <span class="string">"body"</span>, NULL, NULL,
|
|
MXML_DESCEND);
|
|
|
|
<span class="reserved">if</span> (body)
|
|
{
|
|
<span class="reserved">for</span> (heading = mxmlGetFirstChild(body);
|
|
heading;
|
|
heading = mxmlGetNextSibling(heading))
|
|
print_children(heading);
|
|
}
|
|
</code></pre>
|
|
<p>The <code>print_children</code> function is:</p>
|
|
<pre><code class="language-c"><span class="reserved">void</span>
|
|
print_children(mxml_node_t *parent)
|
|
{
|
|
mxml_node_t *node;
|
|
<span class="reserved">const</span> <span class="reserved">char</span> *text;
|
|
<span class="reserved">bool</span> whitespace;
|
|
|
|
<span class="reserved">for</span> (node = mxmlGetFirstChild(parent);
|
|
node != NULL;
|
|
node = mxmlGetNextSibling(node))
|
|
{
|
|
text = mxmlGetText(node, &whitespace);
|
|
|
|
<span class="reserved">if</span> (whitespace)
|
|
putchar(<span class="string">' '</span>);
|
|
|
|
fputs(text, stdout);
|
|
}
|
|
|
|
putchar(<span class="string">'\n'</span>);
|
|
}
|
|
</code></pre>
|
|
<h2 class="title" id="migrating-from-mini-xml-v3.x">Migrating from Mini-XML v3.x</h2>
|
|
<p>The following incompatible API changes were made in Mini-XML v4.0:</p>
|
|
<ul>
|
|
<li><p>SAX events are now named <code>MXML_SAX_EVENT_foo</code> instead of <code>MXML_SAX_foo</code>.</p>
|
|
</li>
|
|
<li><p>SAX callbacks now return a boolean value.</p>
|
|
</li>
|
|
<li><p>Node types are now named <code>MXML_TYPE_foo</code> instead of <code>MXML_foo</code>.</p>
|
|
</li>
|
|
<li><p>Functions that returned <code>0</code> on success and <code>-1</code> on error now return <code>true</code> on success and <code>false</code> on error.</p>
|
|
</li>
|
|
<li><p>CDATA nodes ("<code><![CDATA[...]]></code>") now have their own type (<code>MXML_TYPE_CDATA</code>).</p>
|
|
</li>
|
|
<li><p>Comment nodes ("<code><!-- ... --></code>") now have their own type (<code>MXML_TYPE_COMMENT</code>).</p>
|
|
</li>
|
|
<li><p>Declaration nodes ("<code><!...></code>") now have their own type (<code>MXML_TYPE_DECLARATION</code>).</p>
|
|
</li>
|
|
<li><p>Processing instruction/directive nodes ("<code><?...?></code>") now have their own type (<code>MXML_TYPE_DIRECTIVE</code>).</p>
|
|
</li>
|
|
<li><p>Integer nodes (<code>MXML_TYPE_INTEGER</code>) now use the <code>long</code> type.</p>
|
|
</li>
|
|
<li><p>Text nodes (<code>MXML_TYPE_TEXT</code>) now use the <code>bool</code> type for the whitespace value.</p>
|
|
</li>
|
|
</ul>
|
|
<h2 class="title"><a id="FUNCTIONS">Functions</a></h2>
|
|
<h3 class="function"><a id="mxmlAdd">mxmlAdd</a></h3>
|
|
<p class="description">Add a node to a tree.</p>
|
|
<p class="code">
|
|
void mxmlAdd(<a href="#mxml_node_t">mxml_node_t</a> *parent, int where, <a href="#mxml_node_t">mxml_node_t</a> *child, <a href="#mxml_node_t">mxml_node_t</a> *node);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>parent</th>
|
|
<td class="description">Parent node</td></tr>
|
|
<tr><th>where</th>
|
|
<td class="description">Where to add, <code>MXML_ADD_BEFORE</code> or <code>MXML_ADD_AFTER</code></td></tr>
|
|
<tr><th>child</th>
|
|
<td class="description">Child node for where or <code>MXML_ADD_TO_PARENT</code></td></tr>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to add</td></tr>
|
|
</tbody></table>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">Adds the specified node to the parent. If the child argument is not
|
|
<code>NULL</code>, puts the new node before or after the specified child depending
|
|
on the value of the where argument. If the child argument is <code>NULL</code>,
|
|
puts the new node at the beginning of the child list (<code>MXML_ADD_BEFORE</code>)
|
|
or at the end of the child list (<code>MXML_ADD_AFTER</code>). The constant
|
|
<code>MXML_ADD_TO_PARENT</code> can be used to specify a <code>NULL</code> child pointer.</p>
|
|
<h3 class="function"><a id="mxmlDelete">mxmlDelete</a></h3>
|
|
<p class="description">Delete a node and all of its children.</p>
|
|
<p class="code">
|
|
void mxmlDelete(<a href="#mxml_node_t">mxml_node_t</a> *node);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to delete</td></tr>
|
|
</tbody></table>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">If the specified node has a parent, this function first removes the
|
|
node from its parent using the <a href="#mxmlRemove"><code>mxmlRemove</code></a> function.</p>
|
|
<h3 class="function"><a id="mxmlElementDeleteAttr">mxmlElementDeleteAttr</a></h3>
|
|
<p class="description">Delete an attribute.</p>
|
|
<p class="code">
|
|
void mxmlElementDeleteAttr(<a href="#mxml_node_t">mxml_node_t</a> *node, const char *name);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Element</td></tr>
|
|
<tr><th>name</th>
|
|
<td class="description">Attribute name</td></tr>
|
|
</tbody></table>
|
|
<h3 class="function"><a id="mxmlElementGetAttr">mxmlElementGetAttr</a></h3>
|
|
<p class="description">Get an attribute.</p>
|
|
<p class="code">
|
|
const char *mxmlElementGetAttr(<a href="#mxml_node_t">mxml_node_t</a> *node, const char *name);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Element node</td></tr>
|
|
<tr><th>name</th>
|
|
<td class="description">Name of attribute</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">Attribute value or <code>NULL</code></p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">This function returns <code>NULL</code> if the node is not an element or the
|
|
named attribute does not exist.</p>
|
|
<h3 class="function"><a id="mxmlElementGetAttrByIndex">mxmlElementGetAttrByIndex</a></h3>
|
|
<p class="description">Get an element attribute by index.</p>
|
|
<p class="code">
|
|
const char *mxmlElementGetAttrByIndex(<a href="#mxml_node_t">mxml_node_t</a> *node, int idx, const char **name);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node</td></tr>
|
|
<tr><th>idx</th>
|
|
<td class="description">Attribute index, starting at 0</td></tr>
|
|
<tr><th>name</th>
|
|
<td class="description">Attribute name</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">Attribute value</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The index ("idx") is 0-based. <code>NULL</code> is returned if the specified index
|
|
is out of range.</p>
|
|
<h3 class="function"><a id="mxmlElementGetAttrCount">mxmlElementGetAttrCount</a></h3>
|
|
<p class="description">Get the number of element attributes.</p>
|
|
<p class="code">
|
|
size_t mxmlElementGetAttrCount(<a href="#mxml_node_t">mxml_node_t</a> *node);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">Number of attributes</p>
|
|
<h3 class="function"><a id="mxmlElementSetAttr">mxmlElementSetAttr</a></h3>
|
|
<p class="description">Set an attribute.</p>
|
|
<p class="code">
|
|
void mxmlElementSetAttr(<a href="#mxml_node_t">mxml_node_t</a> *node, const char *name, const char *value);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Element node</td></tr>
|
|
<tr><th>name</th>
|
|
<td class="description">Name of attribute</td></tr>
|
|
<tr><th>value</th>
|
|
<td class="description">Attribute value</td></tr>
|
|
</tbody></table>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">If the named attribute already exists, the value of the attribute
|
|
is replaced by the new string value. The string value is copied
|
|
into the element node. This function does nothing if the node is
|
|
not an element.</p>
|
|
<h3 class="function"><a id="mxmlElementSetAttrf">mxmlElementSetAttrf</a></h3>
|
|
<p class="description">Set an attribute with a formatted value.</p>
|
|
<p class="code">
|
|
void mxmlElementSetAttrf(<a href="#mxml_node_t">mxml_node_t</a> *node, const char *name, const char *format, ...);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Element node</td></tr>
|
|
<tr><th>name</th>
|
|
<td class="description">Name of attribute</td></tr>
|
|
<tr><th>format</th>
|
|
<td class="description">Printf-style attribute value</td></tr>
|
|
<tr><th>...</th>
|
|
<td class="description">Additional arguments as needed</td></tr>
|
|
</tbody></table>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">If the named attribute already exists, the value of the attribute
|
|
is replaced by the new formatted string. The formatted string value is
|
|
copied into the element node. This function does nothing if the node
|
|
is not an element.</p>
|
|
<h3 class="function"><a id="mxmlEntityAddCallback">mxmlEntityAddCallback</a></h3>
|
|
<p class="description">Add a callback to convert entities to Unicode.</p>
|
|
<p class="code">
|
|
bool mxmlEntityAddCallback(<a href="#mxml_entity_cb_t">mxml_entity_cb_t</a> cb);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>cb</th>
|
|
<td class="description">Callback function to add</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
|
|
<h3 class="function"><a id="mxmlEntityGetName">mxmlEntityGetName</a></h3>
|
|
<p class="description">Get the name that corresponds to the character value.</p>
|
|
<p class="code">
|
|
const char *mxmlEntityGetName(int val);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>val</th>
|
|
<td class="description">Character value</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">Entity name or <code>NULL</code></p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">If val does not need to be represented by a named entity, <code>NULL</code> is returned.</p>
|
|
<h3 class="function"><a id="mxmlEntityGetValue">mxmlEntityGetValue</a></h3>
|
|
<p class="description">Get the character corresponding to a named entity.</p>
|
|
<p class="code">
|
|
int mxmlEntityGetValue(const char *name);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>name</th>
|
|
<td class="description">Entity name</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">Character value or <code>-1</code> on error</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The entity name can also be a numeric constant. <code>-1</code> is returned if the
|
|
name is not known.</p>
|
|
<h3 class="function"><a id="mxmlEntityRemoveCallback">mxmlEntityRemoveCallback</a></h3>
|
|
<p class="description">Remove a callback.</p>
|
|
<p class="code">
|
|
void mxmlEntityRemoveCallback(<a href="#mxml_entity_cb_t">mxml_entity_cb_t</a> cb);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>cb</th>
|
|
<td class="description">Callback function to remove</td></tr>
|
|
</tbody></table>
|
|
<h3 class="function"><a id="mxmlFindElement">mxmlFindElement</a></h3>
|
|
<p class="description">Find the named element.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlFindElement(<a href="#mxml_node_t">mxml_node_t</a> *node, <a href="#mxml_node_t">mxml_node_t</a> *top, const char *element, const char *attr, const char *value, int descend);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Current node</td></tr>
|
|
<tr><th>top</th>
|
|
<td class="description">Top node</td></tr>
|
|
<tr><th>element</th>
|
|
<td class="description">Element name or <code>NULL</code> for any</td></tr>
|
|
<tr><th>attr</th>
|
|
<td class="description">Attribute name, or <code>NULL</code> for none</td></tr>
|
|
<tr><th>value</th>
|
|
<td class="description">Attribute value, or <code>NULL</code> for any</td></tr>
|
|
<tr><th>descend</th>
|
|
<td class="description">Descend into tree - <code>MXML_DESCEND</code>, <code>MXML_NO_DESCEND</code>, or <code>MXML_DESCEND_FIRST</code></td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">Element node or <code>NULL</code></p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The search is constrained by the name, attribute name, and value; any
|
|
<code>NULL</code> names or values are treated as wildcards, so different kinds of
|
|
searches can be implemented by looking for all elements of a given name
|
|
or all elements with a specific attribute. The descend argument determines
|
|
whether the search descends into child nodes; normally you will use
|
|
<code>MXML_DESCEND_FIRST</code> for the initial search and <code>MXML_NO_DESCEND</code>
|
|
to find additional direct descendents of the node. The top node argument
|
|
constrains the search to a particular node's children.</p>
|
|
<h3 class="function"><a id="mxmlFindPath">mxmlFindPath</a></h3>
|
|
<p class="description">Find a node with the given path.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlFindPath(<a href="#mxml_node_t">mxml_node_t</a> *top, const char *path);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>top</th>
|
|
<td class="description">Top node</td></tr>
|
|
<tr><th>path</th>
|
|
<td class="description">Path to element</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">Found node or <code>NULL</code></p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The "path" is a slash-separated list of element names. The name "<em>" is
|
|
considered a wildcard for one or more levels of elements. For example,
|
|
"foo/one/two", "bar/two/one", "</em>/one", and so forth.<br>
|
|
<br>
|
|
The first child node of the found node is returned if the given node has
|
|
children and the first child is a value node.</p>
|
|
<h3 class="function"><a id="mxmlGetCDATA">mxmlGetCDATA</a></h3>
|
|
<p class="description">Get the value for a CDATA node.</p>
|
|
<p class="code">
|
|
const char *mxmlGetCDATA(<a href="#mxml_node_t">mxml_node_t</a> *node);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to get</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">CDATA value or <code>NULL</code></p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion"><code>NULL</code> is returned if the node is not a CDATA element.</p>
|
|
<h3 class="function"><a id="mxmlGetComment">mxmlGetComment</a></h3>
|
|
<p class="description">Get the value for a comment node.</p>
|
|
<p class="code">
|
|
const char *mxmlGetComment(<a href="#mxml_node_t">mxml_node_t</a> *node);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to get</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">Comment value or <code>NULL</code></p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion"><code>NULL</code> is returned if the node is not a comment.</p>
|
|
<h3 class="function"><a id="mxmlGetCustom">mxmlGetCustom</a></h3>
|
|
<p class="description">Get the value for a custom node.</p>
|
|
<p class="code">
|
|
const void *mxmlGetCustom(<a href="#mxml_node_t">mxml_node_t</a> *node);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to get</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">Custom value or <code>NULL</code></p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion"><code>NULL</code> is returned if the node (or its first child) is not a custom
|
|
value node.</p>
|
|
<h3 class="function"><a id="mxmlGetDeclaration">mxmlGetDeclaration</a></h3>
|
|
<p class="description">Get the value for a declaration node.</p>
|
|
<p class="code">
|
|
const char *mxmlGetDeclaration(<a href="#mxml_node_t">mxml_node_t</a> *node);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to get</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">Declaraction value or <code>NULL</code></p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion"><code>NULL</code> is returned if the node is not a declaration.</p>
|
|
<h3 class="function"><a id="mxmlGetDirective">mxmlGetDirective</a></h3>
|
|
<p class="description">Get the value for a processing instruction node.</p>
|
|
<p class="code">
|
|
const char *mxmlGetDirective(<a href="#mxml_node_t">mxml_node_t</a> *node);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to get</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">Comment value or <code>NULL</code></p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion"><code>NULL</code> is returned if the node is not a processing instruction.</p>
|
|
<h3 class="function"><a id="mxmlGetElement">mxmlGetElement</a></h3>
|
|
<p class="description">Get the name for an element node.</p>
|
|
<p class="code">
|
|
const char *mxmlGetElement(<a href="#mxml_node_t">mxml_node_t</a> *node);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to get</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">Element name or <code>NULL</code></p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion"><code>NULL</code> is returned if the node is not an element node.</p>
|
|
<h3 class="function"><a id="mxmlGetFirstChild">mxmlGetFirstChild</a></h3>
|
|
<p class="description">Get the first child of an element node.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlGetFirstChild(<a href="#mxml_node_t">mxml_node_t</a> *node);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to get</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">First child or <code>NULL</code></p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion"><code>NULL</code> is returned if the node is not an element node or if the node
|
|
has no children.</p>
|
|
<h3 class="function"><a id="mxmlGetInteger">mxmlGetInteger</a></h3>
|
|
<p class="description">Get the integer value from the specified node or its
|
|
first child.</p>
|
|
<p class="code">
|
|
long mxmlGetInteger(<a href="#mxml_node_t">mxml_node_t</a> *node);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to get</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">Integer value or <code>0</code></p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion"><code>0</code> is returned if the node (or its first child) is not an integer value node.</p>
|
|
<h3 class="function"><a id="mxmlGetLastChild">mxmlGetLastChild</a></h3>
|
|
<p class="description">Get the last child of an element node.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlGetLastChild(<a href="#mxml_node_t">mxml_node_t</a> *node);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to get</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">Last child or <code>NULL</code></p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion"><code>NULL</code> is returned if the node is not an element node or if the node
|
|
has no children.</p>
|
|
<h3 class="function"><a id="mxmlGetNextSibling">mxmlGetNextSibling</a></h3>
|
|
<p class="description"></p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlGetNextSibling(<a href="#mxml_node_t">mxml_node_t</a> *node);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to get</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">Get the next node for the current parent.</p>
|
|
<p class="discussion"><code>NULL</code> is returned if this is the last child for the current parent.</p>
|
|
<h3 class="function"><a id="mxmlGetOpaque">mxmlGetOpaque</a></h3>
|
|
<p class="description">Get an opaque string value for a node or its first child.</p>
|
|
<p class="code">
|
|
const char *mxmlGetOpaque(<a href="#mxml_node_t">mxml_node_t</a> *node);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to get</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">Opaque string or <code>NULL</code></p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion"><code>NULL</code> is returned if the node (or its first child) is not an opaque
|
|
value node.</p>
|
|
<h3 class="function"><a id="mxmlGetParent">mxmlGetParent</a></h3>
|
|
<p class="description">Get the parent node.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlGetParent(<a href="#mxml_node_t">mxml_node_t</a> *node);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to get</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">Parent node or <code>NULL</code></p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion"><code>NULL</code> is returned for a root node.</p>
|
|
<h3 class="function"><a id="mxmlGetPrevSibling">mxmlGetPrevSibling</a></h3>
|
|
<p class="description">Get the previous node for the current parent.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlGetPrevSibling(<a href="#mxml_node_t">mxml_node_t</a> *node);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to get</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">Previous node or <code>NULL</code></p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion"><code>NULL</code> is returned if this is the first child for the current parent.</p>
|
|
<h3 class="function"><a id="mxmlGetReal">mxmlGetReal</a></h3>
|
|
<p class="description">Get the real value for a node or its first child.</p>
|
|
<p class="code">
|
|
double mxmlGetReal(<a href="#mxml_node_t">mxml_node_t</a> *node);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to get</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">Real value or 0.0</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">0.0 is returned if the node (or its first child) is not a real value node.</p>
|
|
<h3 class="function"><a id="mxmlGetRefCount">mxmlGetRefCount</a></h3>
|
|
<p class="description">Get the current reference (use) count for a node.</p>
|
|
<p class="code">
|
|
size_t mxmlGetRefCount(<a href="#mxml_node_t">mxml_node_t</a> *node);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">Reference count</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The initial reference count of new nodes is 1. Use the <a href="#mxmlRetain"><code>mxmlRetain</code></a>
|
|
and <a href="#mxmlRelease"><code>mxmlRelease</code></a> functions to increment and decrement a node's
|
|
reference count.</p>
|
|
<h3 class="function"><a id="mxmlGetText">mxmlGetText</a></h3>
|
|
<p class="description">Get the text value for a node or its first child.</p>
|
|
<p class="code">
|
|
const char *mxmlGetText(<a href="#mxml_node_t">mxml_node_t</a> *node, bool *whitespace);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to get</td></tr>
|
|
<tr><th>whitespace</th>
|
|
<td class="description"><code>true</code> if string is preceded by whitespace, <code>false</code> otherwise</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">Text string or <code>NULL</code></p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion"><code>NULL</code> is returned if the node (or its first child) is not a text node.
|
|
The "whitespace" argument can be <code>NULL</code>.<br>
|
|
<br>
|
|
Note: Text nodes consist of whitespace-delimited words. You will only get
|
|
single words of text when reading an XML file with <code>MXML_TYPE_TEXT</code> nodes.
|
|
If you want the entire string between elements in the XML file, you MUST read
|
|
the XML file with <code>MXML_TYPE_OPAQUE</code> nodes and get the resulting strings
|
|
using the <a href="#mxmlGetOpaque"><code>mxmlGetOpaque</code></a> function instead.</p>
|
|
<h3 class="function"><a id="mxmlGetType">mxmlGetType</a></h3>
|
|
<p class="description">Get the node type.</p>
|
|
<p class="code">
|
|
<a href="#mxml_type_t">mxml_type_t</a> mxmlGetType(<a href="#mxml_node_t">mxml_node_t</a> *node);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to get</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">Type of node</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion"><code>MXML_TYPE_IGNORE</code> is returned if "node" is <code>NULL</code>.</p>
|
|
<h3 class="function"><a id="mxmlGetUserData">mxmlGetUserData</a></h3>
|
|
<p class="description">Get the user data pointer for a node.</p>
|
|
<p class="code">
|
|
void *mxmlGetUserData(<a href="#mxml_node_t">mxml_node_t</a> *node);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to get</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">User data pointer</p>
|
|
<h3 class="function"><a id="mxmlIndexDelete">mxmlIndexDelete</a></h3>
|
|
<p class="description">Delete an index.</p>
|
|
<p class="code">
|
|
void mxmlIndexDelete(<a href="#mxml_index_t">mxml_index_t</a> *ind);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>ind</th>
|
|
<td class="description">Index to delete</td></tr>
|
|
</tbody></table>
|
|
<h3 class="function"><a id="mxmlIndexEnum">mxmlIndexEnum</a></h3>
|
|
<p class="description">Return the next node in the index.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlIndexEnum(<a href="#mxml_index_t">mxml_index_t</a> *ind);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>ind</th>
|
|
<td class="description">Index to enumerate</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">Next node or <code>NULL</code> if there is none</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">You should call <a href="#mxmlIndexReset"><code>mxmlIndexReset</code></a> prior to using this function to get
|
|
the first node in the index. Nodes are returned in the sorted order of the
|
|
index.</p>
|
|
<h3 class="function"><a id="mxmlIndexFind">mxmlIndexFind</a></h3>
|
|
<p class="description">Find the next matching node.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlIndexFind(<a href="#mxml_index_t">mxml_index_t</a> *ind, const char *element, const char *value);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>ind</th>
|
|
<td class="description">Index to search</td></tr>
|
|
<tr><th>element</th>
|
|
<td class="description">Element name to find, if any</td></tr>
|
|
<tr><th>value</th>
|
|
<td class="description">Attribute value, if any</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">Node or <code>NULL</code> if none found</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">You should call <a href="#mxmlIndexReset"><code>mxmlIndexReset</code></a> prior to using this function for
|
|
the first time with a particular set of "element" and "value"
|
|
strings. Passing <code>NULL</code> for both "element" and "value" is equivalent
|
|
to calling <a href="#mxmlIndexEnum"><code>mxmlIndexEnum</code></a>.</p>
|
|
<h3 class="function"><a id="mxmlIndexGetCount">mxmlIndexGetCount</a></h3>
|
|
<p class="description">Get the number of nodes in an index.</p>
|
|
<p class="code">
|
|
int mxmlIndexGetCount(<a href="#mxml_index_t">mxml_index_t</a> *ind);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>ind</th>
|
|
<td class="description">Index of nodes</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">Number of nodes in index</p>
|
|
<h3 class="function"><a id="mxmlIndexNew">mxmlIndexNew</a></h3>
|
|
<p class="description">Create a new index.</p>
|
|
<p class="code">
|
|
<a href="#mxml_index_t">mxml_index_t</a> *mxmlIndexNew(<a href="#mxml_node_t">mxml_node_t</a> *node, const char *element, const char *attr);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">XML node tree</td></tr>
|
|
<tr><th>element</th>
|
|
<td class="description">Element to index or <code>NULL</code> for all</td></tr>
|
|
<tr><th>attr</th>
|
|
<td class="description">Attribute to index or <code>NULL</code> for none</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">New index</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The index will contain all nodes that contain the named element and/or
|
|
attribute. If both "element" and "attr" are <code>NULL</code>, then the index will
|
|
contain a sorted list of the elements in the node tree. Nodes are
|
|
sorted by element name and optionally by attribute value if the "attr"
|
|
argument is not NULL.</p>
|
|
<h3 class="function"><a id="mxmlIndexReset">mxmlIndexReset</a></h3>
|
|
<p class="description">Reset the enumeration/find pointer in the index and
|
|
return the first node in the index.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlIndexReset(<a href="#mxml_index_t">mxml_index_t</a> *ind);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>ind</th>
|
|
<td class="description">Index to reset</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">First node or <code>NULL</code> if there is none</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">This function should be called prior to using <a href="#mxmlIndexEnum"><code>mxmlIndexEnum</code></a> or
|
|
<a href="#mxmlIndexFind"><code>mxmlIndexFind</code></a> for the first time.</p>
|
|
<h3 class="function"><a id="mxmlLoadFd">mxmlLoadFd</a></h3>
|
|
<p class="description">Load a file descriptor into an XML node tree.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlLoadFd(<a href="#mxml_node_t">mxml_node_t</a> *top, int fd, <a href="#mxml_load_cb_t">mxml_load_cb_t</a> cb);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>top</th>
|
|
<td class="description">Top node</td></tr>
|
|
<tr><th>fd</th>
|
|
<td class="description">File descriptor to read from</td></tr>
|
|
<tr><th>cb</th>
|
|
<td class="description">Callback function or constant</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">First node or <code>NULL</code> if the file could not be read.</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The nodes in the specified file are added to the specified top node.
|
|
If no top node is provided, the XML file MUST be well-formed with a
|
|
single parent node like <a href="?xml">?xml</a> for the entire file. The callback
|
|
function returns the value type that should be used for child nodes.
|
|
The constants <code>MXML_INTEGER_CALLBACK</code>, <code>MXML_TYPE_OPAQUE_CALLBACK</code>,
|
|
<code>MXML_REAL_CALLBACK</code>, and <code>MXML_TYPE_TEXT_CALLBACK</code> are defined for
|
|
loading child (data) nodes of the specified type.<br>
|
|
<br>
|
|
Note: The most common programming error when using the Mini-XML library is
|
|
to load an XML file using the <code>MXML_TEXT_CALLBACK</code>, which returns inline
|
|
text as a series of whitespace-delimited words, instead of using the
|
|
<code>MXML_OPAQUE_CALLBACK</code> which returns the inline text as a single string
|
|
(including whitespace).</p>
|
|
<h3 class="function"><a id="mxmlLoadFile">mxmlLoadFile</a></h3>
|
|
<p class="description">Load a file into an XML node tree.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlLoadFile(<a href="#mxml_node_t">mxml_node_t</a> *top, FILE *fp, <a href="#mxml_load_cb_t">mxml_load_cb_t</a> cb);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>top</th>
|
|
<td class="description">Top node</td></tr>
|
|
<tr><th>fp</th>
|
|
<td class="description">File to read from</td></tr>
|
|
<tr><th>cb</th>
|
|
<td class="description">Callback function or constant</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">First node or <code>NULL</code> if the file could not be read.</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The nodes in the specified file are added to the specified top node.
|
|
If no top node is provided, the XML file MUST be well-formed with a
|
|
single parent node like <a href="?xml">?xml</a> for the entire file. The callback
|
|
function returns the value type that should be used for child nodes.
|
|
The constants <code>MXML_INTEGER_CALLBACK</code>, <code>MXML_TYPE_OPAQUE_CALLBACK</code>,
|
|
<code>MXML_REAL_CALLBACK</code>, and <code>MXML_TYPE_TEXT_CALLBACK</code> are defined for
|
|
loading child (data) nodes of the specified type.<br>
|
|
<br>
|
|
Note: The most common programming error when using the Mini-XML library is
|
|
to load an XML file using the <code>MXML_TEXT_CALLBACK</code>, which returns inline
|
|
text as a series of whitespace-delimited words, instead of using the
|
|
<code>MXML_OPAQUE_CALLBACK</code> which returns the inline text as a single string
|
|
(including whitespace).</p>
|
|
<h3 class="function"><a id="mxmlLoadString">mxmlLoadString</a></h3>
|
|
<p class="description">Load a string into an XML node tree.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlLoadString(<a href="#mxml_node_t">mxml_node_t</a> *top, const char *s, <a href="#mxml_load_cb_t">mxml_load_cb_t</a> cb);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>top</th>
|
|
<td class="description">Top node</td></tr>
|
|
<tr><th>s</th>
|
|
<td class="description">String to load</td></tr>
|
|
<tr><th>cb</th>
|
|
<td class="description">Callback function or constant</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">First node or <code>NULL</code> if the string has errors.</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The nodes in the specified string are added to the specified top node.
|
|
If no top node is provided, the XML string MUST be well-formed with a
|
|
single parent node like <a href="?xml">?xml</a> for the entire string. The callback
|
|
function returns the value type that should be used for child nodes.
|
|
The constants <code>MXML_INTEGER_CALLBACK</code>, <code>MXML_TYPE_OPAQUE_CALLBACK</code>,
|
|
<code>MXML_REAL_CALLBACK</code>, and <code>MXML_TYPE_TEXT_CALLBACK</code> are defined for
|
|
loading child (data) nodes of the specified type.<br>
|
|
<br>
|
|
Note: The most common programming error when using the Mini-XML library is
|
|
to load an XML file using the <code>MXML_TEXT_CALLBACK</code>, which returns inline
|
|
text as a series of whitespace-delimited words, instead of using the
|
|
<code>MXML_OPAQUE_CALLBACK</code> which returns the inline text as a single string
|
|
(including whitespace).</p>
|
|
<h3 class="function"><a id="mxmlNewCDATA">mxmlNewCDATA</a></h3>
|
|
<p class="description">Create a new CDATA node.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlNewCDATA(<a href="#mxml_node_t">mxml_node_t</a> *parent, const char *data);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>parent</th>
|
|
<td class="description">Parent node or <code>MXML_NO_PARENT</code></td></tr>
|
|
<tr><th>data</th>
|
|
<td class="description">Data string</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">New node</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The new CDATA node is added to the end of the specified parent's child
|
|
list. The constant <code>MXML_NO_PARENT</code> can be used to specify that the new
|
|
CDATA node has no parent. The data string must be nul-terminated and
|
|
is copied into the new node. CDATA nodes currently use the
|
|
<code>MXML_TYPE_ELEMENT</code> type.</p>
|
|
<h3 class="function"><a id="mxmlNewCDATAf">mxmlNewCDATAf</a></h3>
|
|
<p class="description">Create a new formatted CDATA node.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlNewCDATAf(<a href="#mxml_node_t">mxml_node_t</a> *parent, const char *format, ...);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>parent</th>
|
|
<td class="description">Parent node or <code>MXML_NO_PARENT</code></td></tr>
|
|
<tr><th>format</th>
|
|
<td class="description">Printf-style format string</td></tr>
|
|
<tr><th>...</th>
|
|
<td class="description">Additional args as needed</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">New node</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The new CDATA node is added to the end of the specified parent's
|
|
child list. The constant <code>MXML_NO_PARENT</code> can be used to specify that
|
|
the new opaque string node has no parent. The format string must be
|
|
nul-terminated and is formatted into the new node.</p>
|
|
<h3 class="function"><a id="mxmlNewComment">mxmlNewComment</a></h3>
|
|
<p class="description">Create a new comment node.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlNewComment(<a href="#mxml_node_t">mxml_node_t</a> *parent, const char *comment);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>parent</th>
|
|
<td class="description">Parent node or <code>MXML_NO_PARENT</code></td></tr>
|
|
<tr><th>comment</th>
|
|
<td class="description">Comment string</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">New node</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The new comment node is added to the end of the specified parent's child
|
|
list. The constant <code>MXML_NO_PARENT</code> can be used to specify that the new
|
|
comment node has no parent. The comment string must be nul-terminated and
|
|
is copied into the new node.</p>
|
|
<h3 class="function"><a id="mxmlNewCommentf">mxmlNewCommentf</a></h3>
|
|
<p class="description">Create a new formatted comment string node.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlNewCommentf(<a href="#mxml_node_t">mxml_node_t</a> *parent, const char *format, ...);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>parent</th>
|
|
<td class="description">Parent node or <code>MXML_NO_PARENT</code></td></tr>
|
|
<tr><th>format</th>
|
|
<td class="description">Printf-style format string</td></tr>
|
|
<tr><th>...</th>
|
|
<td class="description">Additional args as needed</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">New node</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The new comment string node is added to the end of the specified parent's
|
|
child list. The constant <code>MXML_NO_PARENT</code> can be used to specify that
|
|
the new opaque string node has no parent. The format string must be
|
|
nul-terminated and is formatted into the new node.</p>
|
|
<h3 class="function"><a id="mxmlNewCustom">mxmlNewCustom</a></h3>
|
|
<p class="description">Create a new custom data node.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlNewCustom(<a href="#mxml_node_t">mxml_node_t</a> *parent, void *data, <a href="#mxml_custom_destroy_cb_t">mxml_custom_destroy_cb_t</a> destroy);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>parent</th>
|
|
<td class="description">Parent node or <code>MXML_NO_PARENT</code></td></tr>
|
|
<tr><th>data</th>
|
|
<td class="description">Pointer to data</td></tr>
|
|
<tr><th>destroy</th>
|
|
<td class="description">Function to destroy data</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">New node</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The new custom node is added to the end of the specified parent's child
|
|
list. The constant <code>MXML_NO_PARENT</code> can be used to specify that the new
|
|
element node has no parent. <code>NULL</code> can be passed when the data in the
|
|
node is not dynamically allocated or is separately managed.</p>
|
|
<h3 class="function"><a id="mxmlNewDeclaration">mxmlNewDeclaration</a></h3>
|
|
<p class="description">Create a new declaraction node.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlNewDeclaration(<a href="#mxml_node_t">mxml_node_t</a> *parent, const char *declaration);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>parent</th>
|
|
<td class="description">Parent node or <code>MXML_NO_PARENT</code></td></tr>
|
|
<tr><th>declaration</th>
|
|
<td class="description">Declaration string</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">New node</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The new declaration node is added to the end of the specified parent's child
|
|
list. The constant <code>MXML_NO_PARENT</code> can be used to specify that the new
|
|
declaration node has no parent. The declaration string must be nul-
|
|
terminated and is copied into the new node.</p>
|
|
<h3 class="function"><a id="mxmlNewDeclarationf">mxmlNewDeclarationf</a></h3>
|
|
<p class="description">Create a new formatted declaration node.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlNewDeclarationf(<a href="#mxml_node_t">mxml_node_t</a> *parent, const char *format, ...);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>parent</th>
|
|
<td class="description">Parent node or <code>MXML_NO_PARENT</code></td></tr>
|
|
<tr><th>format</th>
|
|
<td class="description">Printf-style format string</td></tr>
|
|
<tr><th>...</th>
|
|
<td class="description">Additional args as needed</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">New node</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The new declaration node is added to the end of the specified parent's
|
|
child list. The constant <code>MXML_NO_PARENT</code> can be used to specify that
|
|
the new opaque string node has no parent. The format string must be
|
|
nul-terminated and is formatted into the new node.</p>
|
|
<h3 class="function"><a id="mxmlNewDirective">mxmlNewDirective</a></h3>
|
|
<p class="description">Create a new processing instruction node.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlNewDirective(<a href="#mxml_node_t">mxml_node_t</a> *parent, const char *directive);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>parent</th>
|
|
<td class="description">Parent node or <code>MXML_NO_PARENT</code></td></tr>
|
|
<tr><th>directive</th>
|
|
<td class="description">Directive string</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">New node</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The new processing instruction node is added to the end of the specified
|
|
parent's child list. The constant <code>MXML_NO_PARENT</code> can be used to specify
|
|
that the new processing instruction node has no parent. The data string must
|
|
be nul-terminated and is copied into the new node.</p>
|
|
<h3 class="function"><a id="mxmlNewDirectivef">mxmlNewDirectivef</a></h3>
|
|
<p class="description">Create a new formatted processing instruction node.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlNewDirectivef(<a href="#mxml_node_t">mxml_node_t</a> *parent, const char *format, ...);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>parent</th>
|
|
<td class="description">Parent node or <code>MXML_NO_PARENT</code></td></tr>
|
|
<tr><th>format</th>
|
|
<td class="description">Printf-style format string</td></tr>
|
|
<tr><th>...</th>
|
|
<td class="description">Additional args as needed</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">New node</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The new processing instruction node is added to the end of the specified parent's
|
|
child list. The constant <code>MXML_NO_PARENT</code> can be used to specify that
|
|
the new opaque string node has no parent. The format string must be
|
|
nul-terminated and is formatted into the new node.</p>
|
|
<h3 class="function"><a id="mxmlNewElement">mxmlNewElement</a></h3>
|
|
<p class="description">Create a new element node.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlNewElement(<a href="#mxml_node_t">mxml_node_t</a> *parent, const char *name);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>parent</th>
|
|
<td class="description">Parent node or <code>MXML_NO_PARENT</code></td></tr>
|
|
<tr><th>name</th>
|
|
<td class="description">Name of element</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">New node</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The new element node is added to the end of the specified parent's child
|
|
list. The constant <code>MXML_NO_PARENT</code> can be used to specify that the new
|
|
element node has no parent.</p>
|
|
<h3 class="function"><a id="mxmlNewInteger">mxmlNewInteger</a></h3>
|
|
<p class="description">Create a new integer node.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlNewInteger(<a href="#mxml_node_t">mxml_node_t</a> *parent, long integer);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>parent</th>
|
|
<td class="description">Parent node or <code>MXML_NO_PARENT</code></td></tr>
|
|
<tr><th>integer</th>
|
|
<td class="description">Integer value</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">New node</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The new integer node is added to the end of the specified parent's child
|
|
list. The constant <code>MXML_NO_PARENT</code> can be used to specify that the new
|
|
integer node has no parent.</p>
|
|
<h3 class="function"><a id="mxmlNewOpaque">mxmlNewOpaque</a></h3>
|
|
<p class="description">Create a new opaque string.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlNewOpaque(<a href="#mxml_node_t">mxml_node_t</a> *parent, const char *opaque);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>parent</th>
|
|
<td class="description">Parent node or <code>MXML_NO_PARENT</code></td></tr>
|
|
<tr><th>opaque</th>
|
|
<td class="description">Opaque string</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">New node</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The new opaque string node is added to the end of the specified parent's
|
|
child list. The constant <code>MXML_NO_PARENT</code> can be used to specify that
|
|
the new opaque string node has no parent. The opaque string must be nul-
|
|
terminated and is copied into the new node.</p>
|
|
<h3 class="function"><a id="mxmlNewOpaquef">mxmlNewOpaquef</a></h3>
|
|
<p class="description">Create a new formatted opaque string node.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlNewOpaquef(<a href="#mxml_node_t">mxml_node_t</a> *parent, const char *format, ...);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>parent</th>
|
|
<td class="description">Parent node or <code>MXML_NO_PARENT</code></td></tr>
|
|
<tr><th>format</th>
|
|
<td class="description">Printf-style format string</td></tr>
|
|
<tr><th>...</th>
|
|
<td class="description">Additional args as needed</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">New node</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The new opaque string node is added to the end of the specified parent's
|
|
child list. The constant <code>MXML_NO_PARENT</code> can be used to specify that
|
|
the new opaque string node has no parent. The format string must be
|
|
nul-terminated and is formatted into the new node.</p>
|
|
<h3 class="function"><a id="mxmlNewReal">mxmlNewReal</a></h3>
|
|
<p class="description">Create a new real number node.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlNewReal(<a href="#mxml_node_t">mxml_node_t</a> *parent, double real);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>parent</th>
|
|
<td class="description">Parent node or <code>MXML_NO_PARENT</code></td></tr>
|
|
<tr><th>real</th>
|
|
<td class="description">Real number value</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">New node</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The new real number node is added to the end of the specified parent's
|
|
child list. The constant <code>MXML_NO_PARENT</code> can be used to specify that
|
|
the new real number node has no parent.</p>
|
|
<h3 class="function"><a id="mxmlNewText">mxmlNewText</a></h3>
|
|
<p class="description">Create a new text fragment node.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlNewText(<a href="#mxml_node_t">mxml_node_t</a> *parent, bool whitespace, const char *string);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>parent</th>
|
|
<td class="description">Parent node or <code>MXML_NO_PARENT</code></td></tr>
|
|
<tr><th>whitespace</th>
|
|
<td class="description"><code>true</code> = leading whitespace, <code>false</code> = no whitespace</td></tr>
|
|
<tr><th>string</th>
|
|
<td class="description">String</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">New node</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The new text node is added to the end of the specified parent's child
|
|
list. The constant <code>MXML_NO_PARENT</code> can be used to specify that the new
|
|
text node has no parent. The whitespace parameter is used to specify
|
|
whether leading whitespace is present before the node. The text
|
|
string must be nul-terminated and is copied into the new node.</p>
|
|
<h3 class="function"><a id="mxmlNewTextf">mxmlNewTextf</a></h3>
|
|
<p class="description">Create a new formatted text fragment node.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlNewTextf(<a href="#mxml_node_t">mxml_node_t</a> *parent, bool whitespace, const char *format, ...);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>parent</th>
|
|
<td class="description">Parent node or <code>MXML_NO_PARENT</code></td></tr>
|
|
<tr><th>whitespace</th>
|
|
<td class="description"><code>true</code> = leading whitespace, <code>false</code> = no whitespace</td></tr>
|
|
<tr><th>format</th>
|
|
<td class="description">Printf-style format string</td></tr>
|
|
<tr><th>...</th>
|
|
<td class="description">Additional args as needed</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">New node</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The new text node is added to the end of the specified parent's child
|
|
list. The constant <code>MXML_NO_PARENT</code> can be used to specify that the new
|
|
text node has no parent. The whitespace parameter is used to specify
|
|
whether leading whitespace is present before the node. The format
|
|
string must be nul-terminated and is formatted into the new node.</p>
|
|
<h3 class="function"><a id="mxmlNewXML">mxmlNewXML</a></h3>
|
|
<p class="description">Create a new XML document tree.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlNewXML(const char *version);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>version</th>
|
|
<td class="description">Version number to use</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">New ?xml node</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The "version" argument specifies the version number to put in the
|
|
?xml directive node. If <code>NULL</code>, version "1.0" is assumed.</p>
|
|
<h3 class="function"><a id="mxmlRelease">mxmlRelease</a></h3>
|
|
<p class="description">Release a node.</p>
|
|
<p class="code">
|
|
int mxmlRelease(<a href="#mxml_node_t">mxml_node_t</a> *node);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">New reference count</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">When the reference count reaches zero, the node (and any children)
|
|
is deleted via <a href="#mxmlDelete"><code>mxmlDelete</code></a>.</p>
|
|
<h3 class="function"><a id="mxmlRemove">mxmlRemove</a></h3>
|
|
<p class="description">Remove a node from its parent.</p>
|
|
<p class="code">
|
|
void mxmlRemove(<a href="#mxml_node_t">mxml_node_t</a> *node);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to remove</td></tr>
|
|
</tbody></table>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">This function does not free memory used by the node - use <a href="#mxmlDelete"><code>mxmlDelete</code></a>
|
|
for that. This function does nothing if the node has no parent.</p>
|
|
<h3 class="function"><a id="mxmlRetain">mxmlRetain</a></h3>
|
|
<p class="description">Retain a node.</p>
|
|
<p class="code">
|
|
int mxmlRetain(<a href="#mxml_node_t">mxml_node_t</a> *node);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">New reference count</p>
|
|
<h3 class="function"><a id="mxmlSAXLoadFd">mxmlSAXLoadFd</a></h3>
|
|
<p class="description">Load a file descriptor into an XML node tree
|
|
using a SAX callback.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlSAXLoadFd(<a href="#mxml_node_t">mxml_node_t</a> *top, int fd, <a href="#mxml_load_cb_t">mxml_load_cb_t</a> cb, <a href="#mxml_sax_cb_t">mxml_sax_cb_t</a> sax_cb, void *sax_data);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>top</th>
|
|
<td class="description">Top node</td></tr>
|
|
<tr><th>fd</th>
|
|
<td class="description">File descriptor to read from</td></tr>
|
|
<tr><th>cb</th>
|
|
<td class="description">Callback function or constant</td></tr>
|
|
<tr><th>sax_cb</th>
|
|
<td class="description">SAX callback or <code>MXML_NO_CALLBACK</code></td></tr>
|
|
<tr><th>sax_data</th>
|
|
<td class="description">SAX user data</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">First node or <code>NULL</code> if the file could not be read.</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The nodes in the specified file are added to the specified top node.
|
|
If no top node is provided, the XML file MUST be well-formed with a
|
|
single parent node like <a href="?xml">?xml</a> for the entire file. The callback
|
|
function returns the value type that should be used for child nodes.
|
|
The constants <code>MXML_INTEGER_CALLBACK</code>, <code>MXML_TYPE_OPAQUE_CALLBACK</code>,
|
|
<code>MXML_REAL_CALLBACK</code>, and <code>MXML_TYPE_TEXT_CALLBACK</code> are defined for
|
|
loading child nodes of the specified type.<br>
|
|
<br>
|
|
The SAX callback must call <a href="#mxmlRetain"><code>mxmlRetain</code></a> for any nodes that need to
|
|
be kept for later use. Otherwise, nodes are deleted when the parent
|
|
node is closed or after each data, comment, CDATA, or directive node.</p>
|
|
<h3 class="function"><a id="mxmlSAXLoadFile">mxmlSAXLoadFile</a></h3>
|
|
<p class="description">Load a file into an XML node tree
|
|
using a SAX callback.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlSAXLoadFile(<a href="#mxml_node_t">mxml_node_t</a> *top, FILE *fp, <a href="#mxml_load_cb_t">mxml_load_cb_t</a> cb, <a href="#mxml_sax_cb_t">mxml_sax_cb_t</a> sax_cb, void *sax_data);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>top</th>
|
|
<td class="description">Top node</td></tr>
|
|
<tr><th>fp</th>
|
|
<td class="description">File to read from</td></tr>
|
|
<tr><th>cb</th>
|
|
<td class="description">Callback function or constant</td></tr>
|
|
<tr><th>sax_cb</th>
|
|
<td class="description">SAX callback or <code>MXML_NO_CALLBACK</code></td></tr>
|
|
<tr><th>sax_data</th>
|
|
<td class="description">SAX user data</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">First node or <code>NULL</code> if the file could not be read.</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The nodes in the specified file are added to the specified top node.
|
|
If no top node is provided, the XML file MUST be well-formed with a
|
|
single parent node like <a href="?xml">?xml</a> for the entire file. The callback
|
|
function returns the value type that should be used for child nodes.
|
|
The constants <code>MXML_INTEGER_CALLBACK</code>, <code>MXML_TYPE_OPAQUE_CALLBACK</code>,
|
|
<code>MXML_REAL_CALLBACK</code>, and <code>MXML_TYPE_TEXT_CALLBACK</code> are defined for
|
|
loading child nodes of the specified type.<br>
|
|
<br>
|
|
The SAX callback must call <a href="#mxmlRetain"><code>mxmlRetain</code></a> for any nodes that need to
|
|
be kept for later use. Otherwise, nodes are deleted when the parent
|
|
node is closed or after each data, comment, CDATA, or directive node.</p>
|
|
<h3 class="function"><a id="mxmlSAXLoadString">mxmlSAXLoadString</a></h3>
|
|
<p class="description">Load a string into an XML node tree
|
|
using a SAX callback.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlSAXLoadString(<a href="#mxml_node_t">mxml_node_t</a> *top, const char *s, <a href="#mxml_load_cb_t">mxml_load_cb_t</a> cb, <a href="#mxml_sax_cb_t">mxml_sax_cb_t</a> sax_cb, void *sax_data);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>top</th>
|
|
<td class="description">Top node</td></tr>
|
|
<tr><th>s</th>
|
|
<td class="description">String to load</td></tr>
|
|
<tr><th>cb</th>
|
|
<td class="description">Callback function or constant</td></tr>
|
|
<tr><th>sax_cb</th>
|
|
<td class="description">SAX callback or <code>MXML_NO_CALLBACK</code></td></tr>
|
|
<tr><th>sax_data</th>
|
|
<td class="description">SAX user data</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">First node or <code>NULL</code> if the string has errors.</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The nodes in the specified string are added to the specified top node.
|
|
If no top node is provided, the XML string MUST be well-formed with a
|
|
single parent node like <a href="?xml">?xml</a> for the entire string. The callback
|
|
function returns the value type that should be used for child nodes.
|
|
The constants <code>MXML_INTEGER_CALLBACK</code>, <code>MXML_TYPE_OPAQUE_CALLBACK</code>,
|
|
<code>MXML_REAL_CALLBACK</code>, and <code>MXML_TYPE_TEXT_CALLBACK</code> are defined for
|
|
loading child nodes of the specified type.<br>
|
|
<br>
|
|
The SAX callback must call <a href="#mxmlRetain"><code>mxmlRetain</code></a> for any nodes that need to
|
|
be kept for later use. Otherwise, nodes are deleted when the parent
|
|
node is closed or after each data, comment, CDATA, or directive node.</p>
|
|
<h3 class="function"><a id="mxmlSaveAllocString">mxmlSaveAllocString</a></h3>
|
|
<p class="description">Save an XML tree to an allocated string.</p>
|
|
<p class="code">
|
|
char *mxmlSaveAllocString(<a href="#mxml_node_t">mxml_node_t</a> *node, <a href="#mxml_save_cb_t">mxml_save_cb_t</a> cb);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to write</td></tr>
|
|
<tr><th>cb</th>
|
|
<td class="description">Whitespace callback or <code>MXML_NO_CALLBACK</code></td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">Allocated string or <code>NULL</code></p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">This function returns a pointer to a string containing the textual
|
|
representation of the XML node tree. The string should be freed
|
|
using <code>free()</code> when you are done with it. <code>NULL</code> is returned if the node
|
|
would produce an empty string or if the string cannot be allocated.<br>
|
|
<br>
|
|
The callback argument specifies a function that returns a whitespace
|
|
string or <code>NULL</code> before and after each element. If <code>MXML_NO_CALLBACK</code>
|
|
is specified, whitespace will only be added before <code>MXML_TYPE_TEXT</code> nodes
|
|
with leading whitespace and before attribute names inside opening
|
|
element tags.</p>
|
|
<h3 class="function"><a id="mxmlSaveFd">mxmlSaveFd</a></h3>
|
|
<p class="description">Save an XML tree to a file descriptor.</p>
|
|
<p class="code">
|
|
bool mxmlSaveFd(<a href="#mxml_node_t">mxml_node_t</a> *node, int fd, <a href="#mxml_save_cb_t">mxml_save_cb_t</a> cb);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to write</td></tr>
|
|
<tr><th>fd</th>
|
|
<td class="description">File descriptor to write to</td></tr>
|
|
<tr><th>cb</th>
|
|
<td class="description">Whitespace callback or <code>MXML_NO_CALLBACK</code></td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description"><code>true</code> on success, <code>false</code> on error.</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The callback argument specifies a function that returns a whitespace
|
|
string or NULL before and after each element. If <code>MXML_NO_CALLBACK</code>
|
|
is specified, whitespace will only be added before <code>MXML_TYPE_TEXT</code> nodes
|
|
with leading whitespace and before attribute names inside opening
|
|
element tags.</p>
|
|
<h3 class="function"><a id="mxmlSaveFile">mxmlSaveFile</a></h3>
|
|
<p class="description">Save an XML tree to a file.</p>
|
|
<p class="code">
|
|
bool mxmlSaveFile(<a href="#mxml_node_t">mxml_node_t</a> *node, FILE *fp, <a href="#mxml_save_cb_t">mxml_save_cb_t</a> cb);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to write</td></tr>
|
|
<tr><th>fp</th>
|
|
<td class="description">File to write to</td></tr>
|
|
<tr><th>cb</th>
|
|
<td class="description">Whitespace callback or <code>MXML_NO_CALLBACK</code></td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description"><code>true</code> on success, <code>false</code> on error.</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The callback argument specifies a function that returns a whitespace
|
|
string or NULL before and after each element. If <code>MXML_NO_CALLBACK</code>
|
|
is specified, whitespace will only be added before <code>MXML_TYPE_TEXT</code> nodes
|
|
with leading whitespace and before attribute names inside opening
|
|
element tags.</p>
|
|
<h3 class="function"><a id="mxmlSaveString">mxmlSaveString</a></h3>
|
|
<p class="description">Save an XML node tree to a string.</p>
|
|
<p class="code">
|
|
size_t mxmlSaveString(<a href="#mxml_node_t">mxml_node_t</a> *node, char *buffer, size_t bufsize, <a href="#mxml_save_cb_t">mxml_save_cb_t</a> cb);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to write</td></tr>
|
|
<tr><th>buffer</th>
|
|
<td class="description">String buffer</td></tr>
|
|
<tr><th>bufsize</th>
|
|
<td class="description">Size of string buffer</td></tr>
|
|
<tr><th>cb</th>
|
|
<td class="description">Whitespace callback or <code>MXML_NO_CALLBACK</code></td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">Size of string</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">This function returns the total number of bytes that would be
|
|
required for the string but only copies (bufsize - 1) characters
|
|
into the specified buffer.<br>
|
|
<br>
|
|
The callback argument specifies a function that returns a whitespace
|
|
string or NULL before and after each element. If <code>MXML_NO_CALLBACK</code>
|
|
is specified, whitespace will only be added before <code>MXML_TYPE_TEXT</code> nodes
|
|
with leading whitespace and before attribute names inside opening
|
|
element tags.</p>
|
|
<h3 class="function"><a id="mxmlSetCDATA">mxmlSetCDATA</a></h3>
|
|
<p class="description">Set the data for a CDATA node.</p>
|
|
<p class="code">
|
|
bool mxmlSetCDATA(<a href="#mxml_node_t">mxml_node_t</a> *node, const char *data);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to set</td></tr>
|
|
<tr><th>data</th>
|
|
<td class="description">New data string</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The node is not changed if it (or its first child) is not a CDATA node.</p>
|
|
<h3 class="function"><a id="mxmlSetCDATAf">mxmlSetCDATAf</a></h3>
|
|
<p class="description">Set the data for a CDATA to a formatted string.</p>
|
|
<p class="code">
|
|
bool mxmlSetCDATAf(<a href="#mxml_node_t">mxml_node_t</a> *node, const char *format, ...);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node</td></tr>
|
|
<tr><th>format</th>
|
|
<td class="description"><code>printf</code>-style format string</td></tr>
|
|
<tr><th>...</th>
|
|
<td class="description">Additional arguments as needed</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
|
|
<h3 class="function"><a id="mxmlSetComment">mxmlSetComment</a></h3>
|
|
<p class="description">Set a comment to a literal string.</p>
|
|
<p class="code">
|
|
bool mxmlSetComment(<a href="#mxml_node_t">mxml_node_t</a> *node, const char *comment);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node</td></tr>
|
|
<tr><th>comment</th>
|
|
<td class="description">Literal string</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
|
|
<h3 class="function"><a id="mxmlSetCommentf">mxmlSetCommentf</a></h3>
|
|
<p class="description">Set a comment to a formatted string.</p>
|
|
<p class="code">
|
|
bool mxmlSetCommentf(<a href="#mxml_node_t">mxml_node_t</a> *node, const char *format, ...);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node</td></tr>
|
|
<tr><th>format</th>
|
|
<td class="description"><code>printf</code>-style format string</td></tr>
|
|
<tr><th>...</th>
|
|
<td class="description">Additional arguments as needed</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
|
|
<h3 class="function"><a id="mxmlSetCustom">mxmlSetCustom</a></h3>
|
|
<p class="description">Set the data and destructor of a custom data node.</p>
|
|
<p class="code">
|
|
bool mxmlSetCustom(<a href="#mxml_node_t">mxml_node_t</a> *node, void *data, <a href="#mxml_custom_destroy_cb_t">mxml_custom_destroy_cb_t</a> destroy);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to set</td></tr>
|
|
<tr><th>data</th>
|
|
<td class="description">New data pointer</td></tr>
|
|
<tr><th>destroy</th>
|
|
<td class="description">New destructor function</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The node is not changed if it (or its first child) is not a custom node.</p>
|
|
<h3 class="function"><a id="mxmlSetCustomHandlers">mxmlSetCustomHandlers</a></h3>
|
|
<p class="description">Set the handling functions for custom data.</p>
|
|
<p class="code">
|
|
void mxmlSetCustomHandlers(<a href="#mxml_custom_load_cb_t">mxml_custom_load_cb_t</a> load, <a href="#mxml_custom_save_cb_t">mxml_custom_save_cb_t</a> save);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>load</th>
|
|
<td class="description">Load function</td></tr>
|
|
<tr><th>save</th>
|
|
<td class="description">Save function</td></tr>
|
|
</tbody></table>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The load function accepts a node pointer and a data string and must
|
|
return 0 on success and non-zero on error.<br>
|
|
<br>
|
|
The save function accepts a node pointer and must return a malloc'd
|
|
string on success and <code>NULL</code> on error.</p>
|
|
<h3 class="function"><a id="mxmlSetDeclaration">mxmlSetDeclaration</a></h3>
|
|
<p class="description">Set a comment to a literal string.</p>
|
|
<p class="code">
|
|
bool mxmlSetDeclaration(<a href="#mxml_node_t">mxml_node_t</a> *node, const char *declaration);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node</td></tr>
|
|
<tr><th>declaration</th>
|
|
<td class="description">Literal string</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
|
|
<h3 class="function"><a id="mxmlSetDeclarationf">mxmlSetDeclarationf</a></h3>
|
|
<p class="description">Set a comment to a formatted string.</p>
|
|
<p class="code">
|
|
bool mxmlSetDeclarationf(<a href="#mxml_node_t">mxml_node_t</a> *node, const char *format, ...);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node</td></tr>
|
|
<tr><th>format</th>
|
|
<td class="description"><code>printf</code>-style format string</td></tr>
|
|
<tr><th>...</th>
|
|
<td class="description">Additional arguments as needed</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
|
|
<h3 class="function"><a id="mxmlSetDirective">mxmlSetDirective</a></h3>
|
|
<p class="description">Set a directive to a literal string.</p>
|
|
<p class="code">
|
|
bool mxmlSetDirective(<a href="#mxml_node_t">mxml_node_t</a> *node, const char *directive);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node</td></tr>
|
|
<tr><th>directive</th>
|
|
<td class="description">Literal string</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
|
|
<h3 class="function"><a id="mxmlSetDirectivef">mxmlSetDirectivef</a></h3>
|
|
<p class="description">Set a directive to a formatted string.</p>
|
|
<p class="code">
|
|
bool mxmlSetDirectivef(<a href="#mxml_node_t">mxml_node_t</a> *node, const char *format, ...);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node</td></tr>
|
|
<tr><th>format</th>
|
|
<td class="description"><code>printf</code>-style format string</td></tr>
|
|
<tr><th>...</th>
|
|
<td class="description">Additional arguments as needed</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
|
|
<h3 class="function"><a id="mxmlSetElement">mxmlSetElement</a></h3>
|
|
<p class="description">Set the name of an element node.</p>
|
|
<p class="code">
|
|
bool mxmlSetElement(<a href="#mxml_node_t">mxml_node_t</a> *node, const char *name);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to set</td></tr>
|
|
<tr><th>name</th>
|
|
<td class="description">New name string</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The node is not changed if it is not an element node.</p>
|
|
<h3 class="function"><a id="mxmlSetErrorCallback">mxmlSetErrorCallback</a></h3>
|
|
<p class="description">Set the error message callback.</p>
|
|
<p class="code">
|
|
void mxmlSetErrorCallback(<a href="#mxml_error_cb_t">mxml_error_cb_t</a> cb);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>cb</th>
|
|
<td class="description">Error callback function</td></tr>
|
|
</tbody></table>
|
|
<h3 class="function"><a id="mxmlSetInteger">mxmlSetInteger</a></h3>
|
|
<p class="description">Set the value of an integer node.</p>
|
|
<p class="code">
|
|
bool mxmlSetInteger(<a href="#mxml_node_t">mxml_node_t</a> *node, long integer);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to set</td></tr>
|
|
<tr><th>integer</th>
|
|
<td class="description">Integer value</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The node is not changed if it (or its first child) is not an integer node.</p>
|
|
<h3 class="function"><a id="mxmlSetOpaque">mxmlSetOpaque</a></h3>
|
|
<p class="description">Set the value of an opaque node.</p>
|
|
<p class="code">
|
|
bool mxmlSetOpaque(<a href="#mxml_node_t">mxml_node_t</a> *node, const char *opaque);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to set</td></tr>
|
|
<tr><th>opaque</th>
|
|
<td class="description">Opaque string</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The node is not changed if it (or its first child) is not an opaque node.</p>
|
|
<h3 class="function"><a id="mxmlSetOpaquef">mxmlSetOpaquef</a></h3>
|
|
<p class="description">Set the value of an opaque string node to a formatted string.</p>
|
|
<p class="code">
|
|
bool mxmlSetOpaquef(<a href="#mxml_node_t">mxml_node_t</a> *node, const char *format, ...);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to set</td></tr>
|
|
<tr><th>format</th>
|
|
<td class="description">Printf-style format string</td></tr>
|
|
<tr><th>...</th>
|
|
<td class="description">Additional arguments as needed</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The node is not changed if it (or its first child) is not an opaque node.</p>
|
|
<h3 class="function"><a id="mxmlSetReal">mxmlSetReal</a></h3>
|
|
<p class="description">Set the value of a real number node.</p>
|
|
<p class="code">
|
|
bool mxmlSetReal(<a href="#mxml_node_t">mxml_node_t</a> *node, double real);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to set</td></tr>
|
|
<tr><th>real</th>
|
|
<td class="description">Real number value</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The node is not changed if it (or its first child) is not a real number node.</p>
|
|
<h3 class="function"><a id="mxmlSetText">mxmlSetText</a></h3>
|
|
<p class="description">Set the value of a text node.</p>
|
|
<p class="code">
|
|
bool mxmlSetText(<a href="#mxml_node_t">mxml_node_t</a> *node, bool whitespace, const char *string);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to set</td></tr>
|
|
<tr><th>whitespace</th>
|
|
<td class="description"><code>true</code> = leading whitespace, <code>false</code> = no whitespace</td></tr>
|
|
<tr><th>string</th>
|
|
<td class="description">String</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The node is not changed if it (or its first child) is not a text node.</p>
|
|
<h3 class="function"><a id="mxmlSetTextf">mxmlSetTextf</a></h3>
|
|
<p class="description">Set the value of a text node to a formatted string.</p>
|
|
<p class="code">
|
|
bool mxmlSetTextf(<a href="#mxml_node_t">mxml_node_t</a> *node, bool whitespace, const char *format, ...);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to set</td></tr>
|
|
<tr><th>whitespace</th>
|
|
<td class="description"><code>true</code> = leading whitespace, <code>false</code> = no whitespace</td></tr>
|
|
<tr><th>format</th>
|
|
<td class="description">Printf-style format string</td></tr>
|
|
<tr><th>...</th>
|
|
<td class="description">Additional arguments as needed</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The node is not changed if it (or its first child) is not a text node.</p>
|
|
<h3 class="function"><a id="mxmlSetUserData">mxmlSetUserData</a></h3>
|
|
<p class="description">Set the user data pointer for a node.</p>
|
|
<p class="code">
|
|
bool mxmlSetUserData(<a href="#mxml_node_t">mxml_node_t</a> *node, void *data);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Node to set</td></tr>
|
|
<tr><th>data</th>
|
|
<td class="description">User data pointer</td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description"><code>true</code> on success, <code>false</code> on failure</p>
|
|
<h3 class="function"><a id="mxmlSetWrapMargin">mxmlSetWrapMargin</a></h3>
|
|
<p class="description">Set the wrap margin when saving XML data.</p>
|
|
<p class="code">
|
|
void mxmlSetWrapMargin(int column);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>column</th>
|
|
<td class="description">Column for wrapping, 0 to disable wrapping</td></tr>
|
|
</tbody></table>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">Wrapping is disabled when "column" is 0.</p>
|
|
<h3 class="function"><a id="mxmlWalkNext">mxmlWalkNext</a></h3>
|
|
<p class="description">Walk to the next logical node in the tree.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlWalkNext(<a href="#mxml_node_t">mxml_node_t</a> *node, <a href="#mxml_node_t">mxml_node_t</a> *top, int descend);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Current node</td></tr>
|
|
<tr><th>top</th>
|
|
<td class="description">Top node</td></tr>
|
|
<tr><th>descend</th>
|
|
<td class="description">Descend into tree - <code>MXML_DESCEND</code>, <code>MXML_NO_DESCEND</code>, or <code>MXML_DESCEND_FIRST</code></td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">Next node or <code>NULL</code></p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The descend argument controls whether the first child is considered
|
|
to be the next node. The top node argument constrains the walk to
|
|
the node's children.</p>
|
|
<h3 class="function"><a id="mxmlWalkPrev">mxmlWalkPrev</a></h3>
|
|
<p class="description">Walk to the previous logical node in the tree.</p>
|
|
<p class="code">
|
|
<a href="#mxml_node_t">mxml_node_t</a> *mxmlWalkPrev(<a href="#mxml_node_t">mxml_node_t</a> *node, <a href="#mxml_node_t">mxml_node_t</a> *top, int descend);</p>
|
|
<h4 class="parameters">Parameters</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>node</th>
|
|
<td class="description">Current node</td></tr>
|
|
<tr><th>top</th>
|
|
<td class="description">Top node</td></tr>
|
|
<tr><th>descend</th>
|
|
<td class="description">Descend into tree - <code>MXML_DESCEND</code>, <code>MXML_NO_DESCEND</code>, or <code>MXML_DESCEND_FIRST</code></td></tr>
|
|
</tbody></table>
|
|
<h4 class="returnvalue">Return Value</h4>
|
|
<p class="description">Previous node or <code>NULL</code></p>
|
|
<h4 class="discussion">Discussion</h4>
|
|
<p class="discussion">The descend argument controls whether the previous node's last child
|
|
is considered to be the previous node. The top node argument constrains
|
|
the walk to the node's children.</p>
|
|
<h2 class="title"><a id="TYPES">Data Types</a></h2>
|
|
<h3 class="typedef"><a id="mxml_custom_destroy_cb_t">mxml_custom_destroy_cb_t</a></h3>
|
|
<p class="description">Custom data destructor</p>
|
|
<p class="code">
|
|
typedef void (*mxml_custom_destroy_cb_t)(void *);
|
|
</p>
|
|
<h3 class="typedef"><a id="mxml_custom_load_cb_t">mxml_custom_load_cb_t</a></h3>
|
|
<p class="description">Custom data load callback function</p>
|
|
<p class="code">
|
|
typedef bool (*mxml_custom_load_cb_t)(<a href="#mxml_node_t">mxml_node_t</a> *, const char *);
|
|
</p>
|
|
<h3 class="typedef"><a id="mxml_custom_save_cb_t">mxml_custom_save_cb_t</a></h3>
|
|
<p class="description">Custom data save callback function</p>
|
|
<p class="code">
|
|
typedef char *(*mxml_custom_save_cb_t)(<a href="#mxml_node_t">mxml_node_t</a> *);
|
|
</p>
|
|
<h3 class="typedef"><a id="mxml_entity_cb_t">mxml_entity_cb_t</a></h3>
|
|
<p class="description">Entity callback function</p>
|
|
<p class="code">
|
|
typedef int (*mxml_entity_cb_t)(const char *);
|
|
</p>
|
|
<h3 class="typedef"><a id="mxml_error_cb_t">mxml_error_cb_t</a></h3>
|
|
<p class="description">Error callback function</p>
|
|
<p class="code">
|
|
typedef void (*mxml_error_cb_t)(const char *);
|
|
</p>
|
|
<h3 class="typedef"><a id="mxml_index_t">mxml_index_t</a></h3>
|
|
<p class="description">An XML node index.</p>
|
|
<p class="code">
|
|
typedef struct _mxml_index_s mxml_index_t;
|
|
</p>
|
|
<h3 class="typedef"><a id="mxml_load_cb_t">mxml_load_cb_t</a></h3>
|
|
<p class="description">Load callback function</p>
|
|
<p class="code">
|
|
typedef <a href="#mxml_type_t">mxml_type_t</a> (*mxml_load_cb_t)(<a href="#mxml_node_t">mxml_node_t</a> *);
|
|
</p>
|
|
<h3 class="typedef"><a id="mxml_node_t">mxml_node_t</a></h3>
|
|
<p class="description">An XML node.</p>
|
|
<p class="code">
|
|
typedef struct _mxml_node_s mxml_node_t;
|
|
</p>
|
|
<h3 class="typedef"><a id="mxml_save_cb_t">mxml_save_cb_t</a></h3>
|
|
<p class="description">Save callback function</p>
|
|
<p class="code">
|
|
typedef const char *(*mxml_save_cb_t)(<a href="#mxml_node_t">mxml_node_t</a> *, int);
|
|
</p>
|
|
<h3 class="typedef"><a id="mxml_sax_cb_t">mxml_sax_cb_t</a></h3>
|
|
<p class="description">SAX callback function</p>
|
|
<p class="code">
|
|
typedef bool (*mxml_sax_cb_t)(<a href="#mxml_node_t">mxml_node_t</a> *, mxml_sax_event_t, void *);
|
|
</p>
|
|
<h3 class="typedef"><a id="mxml_sax_event_t">mxml_sax_event_t</a></h3>
|
|
<p class="description">SAX event type.</p>
|
|
<p class="code">
|
|
typedef enum <a href="#mxml_sax_event_e">mxml_sax_event_e</a> mxml_sax_event_t;
|
|
</p>
|
|
<h3 class="typedef"><a id="mxml_type_t">mxml_type_t</a></h3>
|
|
<p class="description">The XML node type.</p>
|
|
<p class="code">
|
|
typedef enum <a href="#mxml_type_e">mxml_type_e</a> mxml_type_t;
|
|
</p>
|
|
<h2 class="title"><a id="ENUMERATIONS">Constants</a></h2>
|
|
<h3 class="enumeration"><a id="mxml_sax_event_e">mxml_sax_event_e</a></h3>
|
|
<p class="description">SAX event type.</p>
|
|
<h4 class="constants">Constants</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>MXML_SAX_EVENT_CDATA </th><td class="description">CDATA node</td></tr>
|
|
<tr><th>MXML_SAX_EVENT_COMMENT </th><td class="description">Comment node</td></tr>
|
|
<tr><th>MXML_SAX_EVENT_DATA </th><td class="description">Data node</td></tr>
|
|
<tr><th>MXML_SAX_EVENT_DECLARATION </th><td class="description">Declaration node</td></tr>
|
|
<tr><th>MXML_SAX_EVENT_DIRECTIVE </th><td class="description">Processing instruction node</td></tr>
|
|
<tr><th>MXML_SAX_EVENT_ELEMENT_CLOSE </th><td class="description">Element closed</td></tr>
|
|
<tr><th>MXML_SAX_EVENT_ELEMENT_OPEN </th><td class="description">Element opened</td></tr>
|
|
</tbody></table>
|
|
<h3 class="enumeration"><a id="mxml_type_e">mxml_type_e</a></h3>
|
|
<p class="description">The XML node type.</p>
|
|
<h4 class="constants">Constants</h4>
|
|
<table class="list"><tbody>
|
|
<tr><th>MXML_TYPE_CDATA </th><td class="description">CDATA value ("<a href="[CDATA[...]]">[CDATA[...]]</a>")</td></tr>
|
|
<tr><th>MXML_TYPE_COMMENT </th><td class="description">Comment ("<a href="!--...--">!--...--</a>")</td></tr>
|
|
<tr><th>MXML_TYPE_CUSTOM </th><td class="description">Custom data</td></tr>
|
|
<tr><th>MXML_TYPE_DECLARATION </th><td class="description">Declaration ("<a href="!...">!...</a>")</td></tr>
|
|
<tr><th>MXML_TYPE_DIRECTIVE </th><td class="description">Processing instruction ("<a href="?...?">?...?</a>")</td></tr>
|
|
<tr><th>MXML_TYPE_ELEMENT </th><td class="description">XML element with attributes</td></tr>
|
|
<tr><th>MXML_TYPE_IGNORE </th><td class="description">Ignore/throw away node</td></tr>
|
|
<tr><th>MXML_TYPE_INTEGER </th><td class="description">Integer value</td></tr>
|
|
<tr><th>MXML_TYPE_OPAQUE </th><td class="description">Opaque string</td></tr>
|
|
<tr><th>MXML_TYPE_REAL </th><td class="description">Real value</td></tr>
|
|
<tr><th>MXML_TYPE_TEXT </th><td class="description">Text fragment</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
</body>
|
|
</html>
|