mirror of
https://github.com/michaelrsweet/mxml.git
synced 2024-11-08 13:39:58 +00:00
Add mxmlNewXML() function and use it.
More updates to the manual.
This commit is contained in:
parent
94ad843d35
commit
0f8052e766
25
CHANGES
25
CHANGES
@ -1,11 +1,12 @@
|
||||
CHANGES - 2007-04-18
|
||||
CHANGES - 2007-04-19
|
||||
--------------------
|
||||
|
||||
CHANGES IN Mini-XML 2.3
|
||||
|
||||
- Added two exceptions to the LGPL to support static
|
||||
linking of applications against Mini-XML.
|
||||
- Added mxmlElementSetAttrf() function (STR #43)
|
||||
linking of applications against Mini-XML
|
||||
- Added a mxmlNewXML() function
|
||||
- Added a mxmlElementSetAttrf() function (STR #43)
|
||||
- Added snprintf() emulation function for test program (STR
|
||||
#32)
|
||||
- Added the _CRT_SECURE_NO_DEPRECATE definition when
|
||||
@ -15,31 +16,31 @@ CHANGES IN Mini-XML 2.3
|
||||
- mxmlLoad*() did not detect missing close tags at the end
|
||||
of an XML document (STR #45)
|
||||
- Added user_data and ref_count members to mxml_node_t
|
||||
structure.
|
||||
structure
|
||||
- Added mxmlReleaseNode() and mxmlRetainNode() APIs for
|
||||
reference-counted nodes.
|
||||
reference-counted nodes
|
||||
- Added mxmlSetWrapMargin() to control the wrapping of XML
|
||||
output.
|
||||
output
|
||||
- Added conditional check for EINTR error code for
|
||||
certain Windows compilers that do not define it (STR
|
||||
#33)
|
||||
- The mxmldoc program now generates correct HTML 4.0
|
||||
output (previously it generated invalid XHTML...)
|
||||
output - previously it generated invalid XHTML
|
||||
- The mxmldoc program now supports "@deprecated@,
|
||||
"@private@", and "@since version@" comments.
|
||||
"@private@", and "@since version@" comments
|
||||
- Fixed function and enumeration type bugs in mxmldoc.
|
||||
- Fixed XML schema for mxmldoc.
|
||||
- Fixed the XML schema for mxmldoc
|
||||
- The mxmldoc program now supports --intro, --section,
|
||||
and --title options.
|
||||
and --title options
|
||||
- The mxmlLoad*() functions could leak a node on an error
|
||||
(STR #27)
|
||||
- The mxml_vsnprintf() function could get in an infinite
|
||||
loop on a buffer overflow (STR #25)
|
||||
- Added new mxmlNewCDATA() and mxmlSetCDATA() functions
|
||||
to create and set CDATA nodes, which are really just
|
||||
special element nodes.
|
||||
special element nodes
|
||||
- Added new MXML_IGNORE type and MXML_IGNORE_CB callback
|
||||
to ignore non-element nodes (i.e. whitespace)
|
||||
to ignore non-element nodes, e.g. whitespace
|
||||
- mxmlLoad*() crashed when reporting an error in some
|
||||
invalid XML (STR #23)
|
||||
|
||||
|
@ -21,11 +21,11 @@ XML data files:</p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li><tt>MXML_INTEGER_CALLBACK</tt> - All data nodes contain
|
||||
whitespace-separated integers.</li>
|
||||
<li><tt>MXML_INTEGER_CALLBACK</tt> - All data nodes
|
||||
contain whitespace-separated integers.</li>
|
||||
|
||||
<li><tt>MXML_OPAQUE_CALLBACK</tt> - All data nodes contain
|
||||
opaque strings ("CDATA").</li>
|
||||
<li><tt>MXML_OPAQUE_CALLBACK</tt> - All data nodes
|
||||
contain opaque strings ("CDATA").</li>
|
||||
|
||||
<li><tt>MXML_REAL_CALLBACK</tt> - All data nodes contain
|
||||
whitespace-separated floating-point numbers.</li>
|
||||
@ -51,21 +51,18 @@ type to return.</p>
|
||||
child nodes:</p>
|
||||
|
||||
<pre>
|
||||
/*
|
||||
* 'type_cb()' - XML data type callback for mxmlLoadFile()...
|
||||
*/
|
||||
|
||||
mxml_type_t /* O - Data type */
|
||||
type_cb(mxml_node_t *node) /* I - Element node */
|
||||
mxml_type_t
|
||||
type_cb(mxml_node_t *node)
|
||||
{
|
||||
const char *type; /* Type string */
|
||||
|
||||
const char *type;
|
||||
|
||||
/*
|
||||
* You can lookup attributes and/or use the element name, hierarchy, etc...
|
||||
* You can lookup attributes and/or use the
|
||||
* element name, hierarchy, etc...
|
||||
*/
|
||||
|
||||
if ((type = mxmlElementGetAttr(node, "type")) == NULL)
|
||||
type = mxmlElementGetAttr(node, "type");
|
||||
if (type == NULL)
|
||||
type = node->value.element.name;
|
||||
|
||||
if (!strcmp(type, "integer"))
|
||||
@ -84,10 +81,10 @@ call any of the load functions:</p>
|
||||
|
||||
<pre>
|
||||
FILE *fp;
|
||||
<a href='#mxml_node_t'>mxml_node_t</a> *tree;
|
||||
mxml_node_t *tree;
|
||||
|
||||
fp = fopen("filename.xml", "r");
|
||||
tree = <a href='#mxmlLoadFile'>mxmlLoadFile</a>(NULL, fp, <b>type_cb</b>);
|
||||
tree = mxmlLoadFile(NULL, fp, <b>type_cb</b>);
|
||||
fclose(fp);
|
||||
</pre>
|
||||
|
||||
@ -108,54 +105,66 @@ of <tt>MXML_WS_BEFORE_OPEN</tt>, <tt>MXML_WS_AFTER_OPEN</tt>,
|
||||
<tt>MXML_WS_BEFORE_CLOSE</tt>, or <tt>MXML_WS_AFTER_CLOSE</tt>.
|
||||
The callback function should return <tt>NULL</tt> if no
|
||||
whitespace should be added and the string to insert (spaces,
|
||||
tabs, carriage returns, and newlines) otherwise. The following
|
||||
whitespace callback can be used to add whitespace to XHTML
|
||||
output to make it more readable in a standard text editor:</p>
|
||||
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>
|
||||
|
||||
<!-- NEW PAGE -->
|
||||
<pre>
|
||||
/*
|
||||
* 'whitespace_cb()' - Let the mxmlSaveFile() function know when to insert
|
||||
* newlines and tabs...
|
||||
*/
|
||||
|
||||
const char * /* O - Whitespace string or NULL */
|
||||
whitespace_cb(mxml_node_t *node, /* I - Element node */
|
||||
int where) /* I - Open or close tag? */
|
||||
const char *
|
||||
whitespace_cb(mxml_node_t *node,
|
||||
int where)
|
||||
{
|
||||
const char *name; /* Name of element */
|
||||
const char *name;
|
||||
|
||||
/*
|
||||
* We can conditionally break to a new line before or after any element.
|
||||
* These are just common HTML elements...
|
||||
* We can conditionally break to a new line
|
||||
* before or after any element. These are
|
||||
* just common HTML elements...
|
||||
*/
|
||||
|
||||
name = node->value.element.name;
|
||||
|
||||
if (!strcmp(name, "html") || !strcmp(name, "head") || !strcmp(name, "body") ||
|
||||
!strcmp(name, "pre") || !strcmp(name, "p") ||
|
||||
!strcmp(name, "h1") || !strcmp(name, "h2") || !strcmp(name, "h3") ||
|
||||
!strcmp(name, "h4") || !strcmp(name, "h5") || !strcmp(name, "h6"))
|
||||
if (!strcmp(name, "html") ||
|
||||
!strcmp(name, "head") ||
|
||||
!strcmp(name, "body") ||
|
||||
!strcmp(name, "pre") ||
|
||||
!strcmp(name, "p") ||
|
||||
!strcmp(name, "h1") ||
|
||||
!strcmp(name, "h2") ||
|
||||
!strcmp(name, "h3") ||
|
||||
!strcmp(name, "h4") ||
|
||||
!strcmp(name, "h5") ||
|
||||
!strcmp(name, "h6"))
|
||||
{
|
||||
/*
|
||||
* Newlines before open and after close...
|
||||
* Newlines before open and after
|
||||
* close...
|
||||
*/
|
||||
|
||||
if (where == MXML_WS_BEFORE_OPEN || where == MXML_WS_AFTER_CLOSE)
|
||||
if (where == MXML_WS_BEFORE_OPEN ||
|
||||
where == MXML_WS_AFTER_CLOSE)
|
||||
return ("\n");
|
||||
}
|
||||
else if (!strcmp(name, "dl") || !strcmp(name, "ol") || !strcmp(name, "ul"))
|
||||
else if (!strcmp(name, "dl") ||
|
||||
!strcmp(name, "ol") ||
|
||||
!strcmp(name, "ul"))
|
||||
{
|
||||
/*
|
||||
* Put a newline before and after list elements...
|
||||
* Put a newline before and after list
|
||||
* elements...
|
||||
*/
|
||||
|
||||
return ("\n");
|
||||
}
|
||||
else if (!strcmp(name, "dd") || !strcmp(name, "dt") || !strcmp(name, "li"))
|
||||
else if (!strcmp(name, "dd") ||
|
||||
!strcmp(name, "dt") ||
|
||||
!strcmp(name, "li"))
|
||||
{
|
||||
/*
|
||||
* Put a tab before <li>'s, <dd>'s, and <dt>'s, and a newline after them...
|
||||
* Put a tab before <li>'s, * <dd>'s,
|
||||
* and <dt>'s, and a newline after them...
|
||||
*/
|
||||
|
||||
if (where == MXML_WS_BEFORE_OPEN)
|
||||
@ -172,20 +181,20 @@ output to make it more readable in a standard text editor:</p>
|
||||
}
|
||||
</pre>
|
||||
|
||||
<!-- NEW PAGE -->
|
||||
<p>To use this callback function, simply use the name when you
|
||||
call any of the save functions:</p>
|
||||
|
||||
<pre>
|
||||
FILE *fp;
|
||||
<a href='#mxml_node_t'>mxml_node_t</a> *tree;
|
||||
mxml_node_t *tree;
|
||||
|
||||
fp = fopen("filename.xml", "w");
|
||||
<a href='#mxmlSaveFile'>mxmlSaveFile</a>(tree, fp, whitespace_cb);
|
||||
mxmlSaveFile(tree, fp, <b>whitespace_cb</b>);
|
||||
fclose(fp);
|
||||
</pre>
|
||||
|
||||
|
||||
<!-- NEED 10 -->
|
||||
<h2>Custom Data Types</h2>
|
||||
|
||||
<p>Mini-XML supports custom data types via global load and save
|
||||
@ -205,22 +214,21 @@ following:</p>
|
||||
<pre>
|
||||
typedef struct
|
||||
{
|
||||
unsigned year, /* Year */
|
||||
month, /* Month */
|
||||
day, /* Day */
|
||||
hour, /* Hour */
|
||||
minute, /* Minute */
|
||||
second; /* Second */
|
||||
time_t unix; /* UNIX time value */
|
||||
unsigned year, /* Year */
|
||||
month, /* Month */
|
||||
day, /* Day */
|
||||
hour, /* Hour */
|
||||
minute, /* Minute */
|
||||
second; /* Second */
|
||||
time_t unix; /* UNIX time */
|
||||
} iso_date_time_t;
|
||||
|
||||
int /* I - 0 on success, -1 on error */
|
||||
load_custom(mxml_node_t *node, /* I - Node */
|
||||
const char *data) /* I - Value */
|
||||
int
|
||||
load_custom(mxml_node_t *node,
|
||||
const char *data)
|
||||
{
|
||||
iso_date_time_t *dt; /* Date/time value */
|
||||
struct tm tmdata; /* UNIX time data */
|
||||
|
||||
iso_date_time_t *dt;
|
||||
struct tm tmdata;
|
||||
|
||||
/*
|
||||
* Allocate data structure...
|
||||
@ -229,16 +237,19 @@ following:</p>
|
||||
dt = calloc(1, sizeof(iso_date_time_t));
|
||||
|
||||
/*
|
||||
* Try reading 6 unsigned integers from the data string...
|
||||
* Try reading 6 unsigned integers from the
|
||||
* data string...
|
||||
*/
|
||||
|
||||
if (sscanf(data, "%u-%u-%uT%u:%u:%uZ",
|
||||
&(dt->year), &(dt->month), &(dt->day),
|
||||
&(dt->hour), &(dt->minute), &(dt->second)) != 6)
|
||||
&(dt->year), &(dt->month),
|
||||
&(dt->day), &(dt->hour),
|
||||
&(dt->minute),
|
||||
&(dt->second)) != 6)
|
||||
{
|
||||
/*
|
||||
* Unable to read numbers, free the data structure and return an
|
||||
* error...
|
||||
* Unable to read numbers, free the data
|
||||
* structure and return an error...
|
||||
*/
|
||||
|
||||
free(dt);
|
||||
@ -266,7 +277,8 @@ following:</p>
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert ISO time to UNIX time in seconds...
|
||||
* Convert ISO time to UNIX time in
|
||||
* seconds...
|
||||
*/
|
||||
|
||||
tmdata.tm_year = dt->year - 1900;
|
||||
@ -276,10 +288,11 @@ following:</p>
|
||||
tmdata.tm_min = dt->minute;
|
||||
tmdata.tm_sec = dt->second;
|
||||
|
||||
dt->unix = gmtime(&tmdata);
|
||||
dt->unix = gmtime(&tmdata);
|
||||
|
||||
/*
|
||||
* Assign custom node data and destroy function pointers...
|
||||
* Assign custom node data and destroy
|
||||
* function pointers...
|
||||
*/
|
||||
|
||||
node->value.custom.data = dt;
|
||||
@ -300,24 +313,24 @@ allocated custom data for the node and a pointer to a destructor
|
||||
function which will free the custom data when the node is
|
||||
deleted.</p>
|
||||
|
||||
<!-- NEED 3in -->
|
||||
<p>The save callback receives the node pointer and returns an
|
||||
allocated string containing the custom data value. The following
|
||||
save callback could be used for our ISO date/time type:</p>
|
||||
|
||||
<pre>
|
||||
char * /* I - Allocated string */
|
||||
save_custom(mxml_node_t *node) /* I - Node */
|
||||
char *
|
||||
save_custom(mxml_node_t *node)
|
||||
{
|
||||
char data[255]; /* Data string */
|
||||
iso_date_time_t *dt; /* ISO date/time pointer */
|
||||
char data[255];
|
||||
iso_date_time_t *dt;
|
||||
|
||||
|
||||
dt = (iso_date_time_t *)node->custom.data;
|
||||
|
||||
snprintf(data, sizeof(data), "%04u-%02u-%02uT%02u:%02u:%02uZ",
|
||||
dt->year, dt->month, dt->day, dt->hour,
|
||||
dt->minute, dt->second);
|
||||
snprintf(data, sizeof(data),
|
||||
"%04u-%02u-%02uT%02u:%02u:%02uZ",
|
||||
dt->year, dt->month, dt->day,
|
||||
dt->hour, dt->minute, dt->second);
|
||||
|
||||
return (strdup(data));
|
||||
}
|
||||
@ -328,7 +341,8 @@ href='#mxmlSetCustomHandlers'><tt>mxmlSetCustomHandlers()</tt></a>
|
||||
function:</p>
|
||||
|
||||
<pre>
|
||||
mxmlSetCustomHandlers(load_custom, save_custom);
|
||||
mxmlSetCustomHandlers(<b>load_custom</b>,
|
||||
<b>save_custom</b>);
|
||||
</pre>
|
||||
|
||||
|
||||
@ -344,30 +358,32 @@ without leaking memory.</p>
|
||||
href='#mxmlSetElement'><tt>mxmlSetElement()</tt></a>, <a
|
||||
href='#mxmlSetInteger'><tt>mxmlSetInteger()</tt></a>, <a
|
||||
href='#mxmlSetOpaque'><tt>mxmlSetOpaque()</tt></a>, <a
|
||||
href='#mxmlSetReal'><tt>mxmlSetReal()</tt></a>, and <a
|
||||
href='#mxmlSetText'><tt>mxmlSetText()</tt></a> functions. For
|
||||
href='#mxmlSetReal'><tt>mxmlSetReal()</tt></a>, <a
|
||||
href='#mxmlSetText'><tt>mxmlSetText()</tt></a>, and <a
|
||||
href='#mxmlSetTextf'><tt>mxmlSetTextf()</tt></a> functions. For
|
||||
example, use the following function call to change a text node
|
||||
to contain the text "new" with leading whitespace:</p>
|
||||
|
||||
<pre>
|
||||
<a href='#mxml_node_t'>mxml_node_t</a> *node;
|
||||
mxml_node_t *node;
|
||||
|
||||
<a href='#mxmlSetText'>mxmlSetText</a>(node, 1, "new");
|
||||
mxmlSetText(node, 1, "new");
|
||||
</pre>
|
||||
|
||||
|
||||
<h2>Formatted Text</h2>
|
||||
|
||||
<p>The <a href='#mxmlNewTextf'><tt>mxmlNewTextf()</tt></a> and
|
||||
<a href='#mxmlSetTextf'><tt>mxmlSetTextf()</tt></a> functions
|
||||
create and change text nodes, respectively, using
|
||||
<tt>printf</tt>-style format strings and arguments. For example,
|
||||
use the following function call to create a new text node:</p>
|
||||
<p>The <a href='#mxmlNewTextf'><tt>mxmlNewTextf()</tt></a> and <a
|
||||
href='#mxmlSetTextf'><tt>mxmlSetTextf()</tt></a> functions create
|
||||
and change text nodes, respectively, using <tt>printf</tt>-style
|
||||
format strings and arguments. For example, use the following
|
||||
function call to create a new text node containing a constructed
|
||||
filename:</p>
|
||||
|
||||
<pre>
|
||||
<a href='#mxml_node_t'>mxml_node_t</a> *node;
|
||||
mxml_node_t</a> *node;
|
||||
|
||||
node = <a href='#mxmlNewTextf'>mxmlNewTextf</a>(node, 1, "%s/%s",
|
||||
node = mxmlNewTextf(node, 1, "%s/%s",
|
||||
path, filename);
|
||||
</pre>
|
||||
|
||||
@ -376,7 +392,7 @@ use the following function call to create a new text node:</p>
|
||||
|
||||
<p>Mini-XML provides functions for managing indices of nodes.
|
||||
The current implementation provides the same functionality as
|
||||
the <a href='#mxmlFindElement'><tt>mxmlFindElement()</tt></a>.
|
||||
<a href='#mxmlFindElement'><tt>mxmlFindElement()</tt></a>.
|
||||
The advantage of using an index is that searching and
|
||||
enumeration of elements is significantly faster. The only
|
||||
disadvantage is that each index is a static snapshot of the XML
|
||||
@ -392,10 +408,11 @@ href='#mxml_index_t'><tt>mxml_index_t</tt></a> structures. The
|
||||
creates a new index:</p>
|
||||
|
||||
<pre>
|
||||
<a href='#mxml_node_t'>mxml_node_t</a> *tree;
|
||||
<a href='#mxml_index_t'>mxml_index_t</a> *ind;
|
||||
mxml_node_t *tree;
|
||||
mxml_index_t *ind;
|
||||
|
||||
ind = <a href='#mxmlIndexNew'>mxmlIndexNew</a>(tree, "element", "attribute");
|
||||
ind = mxmlIndexNew(tree, "element",
|
||||
"attribute");
|
||||
</pre>
|
||||
|
||||
<p>The first argument is the XML node tree to index. Normally this
|
||||
@ -424,8 +441,7 @@ function enumerates each of the nodes in the index and can be
|
||||
used in a loop as follows:</p>
|
||||
|
||||
<pre>
|
||||
<a href='#mxml_node_t'>mxml_node_t</a> *node;
|
||||
<a href='#mxml_index_t'>mxml_index_t</a> *ind;
|
||||
mxml_node_t *node;
|
||||
|
||||
mxmlIndexReset(ind);
|
||||
|
||||
@ -441,12 +457,13 @@ attribute value in the index. It can be used to find all
|
||||
matching elements in an index, as follows:</p>
|
||||
|
||||
<pre>
|
||||
<a href='#mxml_node_t'>mxml_node_t</a> *node;
|
||||
<a href='#mxml_index_t'>mxml_index_t</a> *ind;
|
||||
mxml_node_t *node;
|
||||
|
||||
mxmlIndexReset(ind);
|
||||
|
||||
while ((node = mxmlIndexFind(ind, "element", "attr-value")) != NULL)
|
||||
while ((node = mxmlIndexFind(ind, "element",
|
||||
"attr-value"))
|
||||
!= NULL)
|
||||
{
|
||||
// do something with node
|
||||
}
|
||||
@ -458,14 +475,11 @@ to return all elements or attributes in the index. Passing
|
||||
<tt>NULL</tt> for both the element name and attribute value
|
||||
is equivalent to calling <tt>mxmlIndexEnum</tt>.</p>
|
||||
|
||||
<!-- NEED 2in -->
|
||||
<p>When you are done using the index, delete it using the
|
||||
<a href='#mxmlIndexDelete()'><tt>mxmlIndexDelete()</tt></a>
|
||||
function:</p>
|
||||
|
||||
<pre>
|
||||
<a href='#mxml_index_t'>mxml_index_t</a> *ind;
|
||||
|
||||
mxmlIndexDelete(ind);
|
||||
</pre>
|
||||
|
||||
|
266
doc/basics.html
266
doc/basics.html
@ -44,18 +44,20 @@ which determines which value you want to look at in the <a
|
||||
href='#mxml_value_t'><tt>value</tt></a> union.</p>
|
||||
|
||||
<p>New nodes can be created using the <a
|
||||
href='#mxmlNewElement'><tt>mxmlNewElement()</tt></a>,
|
||||
<a
|
||||
href='#mxmlNewInteger'><tt>mxmlNewInteger()</tt></a>,
|
||||
<a
|
||||
href='#mxmlNewOpaque'><tt>mxmlNewOpaque()</tt></a>,
|
||||
<a href='#mxmlNewReal'><tt>mxmlNewReal()</tt></a>,
|
||||
and <a
|
||||
href='#mxmlNewText'><tt>mxmlNewText()</tt></a>
|
||||
functions. Only elements can have child nodes, and the top node
|
||||
must be an element, usually "?xml".</p>
|
||||
href='#mxmlNewElement'><tt>mxmlNewElement()</tt></a>, <a
|
||||
href='#mxmlNewInteger'><tt>mxmlNewInteger()</tt></a>, <a
|
||||
href='#mxmlNewOpaque'><tt>mxmlNewOpaque()</tt></a>, <a
|
||||
href='#mxmlNewReal'><tt>mxmlNewReal()</tt></a>, <a
|
||||
href='#mxmlNewText'><tt>mxmlNewText()</tt></a> <a
|
||||
href='#mxmlNewTextf'><tt>mxmlNewTextf()</tt></a> <a
|
||||
href='#mxmlNewXML'><tt>mxmlNewXML()</tt></a> functions. Only
|
||||
elements can have child nodes, and the top node must be an
|
||||
element, usually <tt><?xml version="1.0"?></tt>.</p>
|
||||
|
||||
<p>Each node has pointers for the node above (<tt>parent</tt>),
|
||||
<p>Each node has a <tt>user_data</tt> member which allows you to
|
||||
associate application-specific data with each node as needed.</p>
|
||||
|
||||
<p>Node also have pointers for the node above (<tt>parent</tt>),
|
||||
below (<tt>child</tt>), to the left (<tt>prev</tt>), and to the
|
||||
right (<tt>next</tt>) of the current node. If you have an XML
|
||||
file like the following:</p>
|
||||
@ -73,21 +75,20 @@ file like the following:</p>
|
||||
</group>
|
||||
<node>val7</node>
|
||||
<node>val8</node>
|
||||
<node>val9</node>
|
||||
</data>
|
||||
</pre>
|
||||
|
||||
<p>the node tree returned by <tt>mxmlLoadFile()</tt> would look
|
||||
like the following in memory:</p>
|
||||
<p>the node tree for the file would look like the following in
|
||||
memory:</p>
|
||||
|
||||
<pre>
|
||||
?xml
|
||||
|
|
||||
data
|
||||
|
|
||||
node - node - node - group - node - node - node
|
||||
| | | | | | |
|
||||
val1 val2 val3 | val7 val8 val9
|
||||
node - node - node - group - node - node
|
||||
| | | | | |
|
||||
val1 val2 val3 | val7 val8
|
||||
|
|
||||
node - node - node
|
||||
| | |
|
||||
@ -106,7 +107,80 @@ particular node or the entire tree:</p>
|
||||
mxmlDelete(tree);
|
||||
</pre>
|
||||
|
||||
<!-- NEED 15 -->
|
||||
<!-- NEW PAGE -->
|
||||
<h2>Creating XML Documents</h2>
|
||||
|
||||
<p>You can create and update XML documents in memory using the
|
||||
various <tt>mxmlNew</tt> functions. The following code will
|
||||
create the XML document described in the previous section:</p>
|
||||
|
||||
<pre>
|
||||
mxml_node_t *xml; /* <?xml ... ?> */
|
||||
mxml_node_t *data; /* <data> */
|
||||
mxml_node_t *node; /* <node> */
|
||||
mxml_node_t *group; /* <group> */
|
||||
|
||||
xml = mxmlNewXML("1.0");
|
||||
|
||||
data = mxmlNewElement(xml, "data");
|
||||
|
||||
node = mxmlNewElement(data, "node");
|
||||
mxmlNewText(node, 0, "val1");
|
||||
node = mxmlNewElement(data, "node");
|
||||
mxmlNewText(node, 0, "val2");
|
||||
node = mxmlNewElement(data, "node");
|
||||
mxmlNewText(node, 0, "val3");
|
||||
|
||||
group = mxmlNewElement(data, "group");
|
||||
|
||||
node = mxmlNewElement(group, "node");
|
||||
mxmlNewText(node, 0, "val4");
|
||||
node = mxmlNewElement(group, "node");
|
||||
mxmlNewText(node, 0, "val5");
|
||||
node = mxmlNewElement(group, "node");
|
||||
mxmlNewText(node, 0, "val6");
|
||||
|
||||
node = mxmlNewElement(data, "node");
|
||||
mxmlNewText(node, 0, "val7");
|
||||
node = mxmlNewElement(data, "node");
|
||||
mxmlNewText(node, 0, "val8");
|
||||
</pre>
|
||||
|
||||
<p>We start by creating the <tt><?xml version="1.0"?></tt>
|
||||
node common to all XML files using the <a
|
||||
href="#mxmlNewXML"><tt>mxmlNewXML</tt></a> function:</p>
|
||||
|
||||
<pre>
|
||||
xml = mxmlNewXML("1.0");
|
||||
</pre>
|
||||
|
||||
<p>We then create the <tt><data></tt> node used for this
|
||||
document using the <a
|
||||
href="#mxmlNewElement"><tt>mxmlNewElement</tt></a> function. The
|
||||
first argument specifies the parent node (<tt>xml</tt>) while the
|
||||
second specifies the element name (<tt>data</tt>):</p>
|
||||
|
||||
<pre>
|
||||
data = mxmlNewElement(xml, "data");
|
||||
</pre>
|
||||
|
||||
<p>Each <tt><node>...</node></tt> in the file is
|
||||
created using the <tt>mxmlNewElement</tt> and <a
|
||||
href="#mxmlNewText"><tt>mxmlNewText</tt></a> functions. The first
|
||||
argument of <tt>mxmlNewText</tt> specifies the parent node
|
||||
(<tt>node</tt>). 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>
|
||||
node = mxmlNewElement(data, "node");
|
||||
mxmlNewText(node, 0, "val1");
|
||||
</pre>
|
||||
|
||||
<p>The resulting in-memory XML document can then be saved or
|
||||
processed just like one loaded from disk or a string.</p>
|
||||
|
||||
<!-- NEW PAGE -->
|
||||
<h2>Loading XML</h2>
|
||||
|
||||
<p>You load an XML file using the <a
|
||||
@ -115,10 +189,11 @@ function:</p>
|
||||
|
||||
<pre>
|
||||
FILE *fp;
|
||||
<a href='#mxml_node_t'>mxml_node_t</a> *tree;
|
||||
mxml_node_t *tree;
|
||||
|
||||
fp = fopen("filename.xml", "r");
|
||||
tree = <a href='#mxmlLoadFile'>mxmlLoadFile</a>(NULL, fp, MXML_NO_CALLBACK);
|
||||
tree = mxmlLoadFile(NULL, fp,
|
||||
MXML_TEXT_CALLBACK);
|
||||
fclose(fp);
|
||||
</pre>
|
||||
|
||||
@ -133,14 +208,18 @@ opened by <tt>fopen()</tt> or <tt>popen()</tt>. You can also use
|
||||
<tt>stdin</tt> if you are implementing an XML filter
|
||||
program.</p>
|
||||
|
||||
<p>The third argument specifies a callback function which
|
||||
returns the value type of the immediate children for a new
|
||||
element node: <tt>MXML_INTEGER</tt>, <tt>MXML_OPAQUE</tt>,
|
||||
<tt>MXML_REAL</tt>, or <tt>MXML_TEXT</tt>. Load callbacks are
|
||||
described in detail in <a href='#LOAD_CALLBACKS'>Chapter 3</a>.
|
||||
The example code uses the <tt>MXML_NO_CALLBACK</tt> constant
|
||||
which specifies that all data nodes in the document contain
|
||||
whitespace-separated text values.</p>
|
||||
<p>The third argument specifies a callback function which returns
|
||||
the value type of the immediate children for a new element node:
|
||||
<tt>MXML_CUSTOM</tt>, <tt>MXML_IGNORE</tt>,
|
||||
<tt>MXML_INTEGER</tt>, <tt>MXML_OPAQUE</tt>, <tt>MXML_REAL</tt>,
|
||||
or <tt>MXML_TEXT</tt>. Load callbacks are described in detail in
|
||||
<a href='#LOAD_CALLBACKS'>Chapter 3</a>. The example code uses
|
||||
the <tt>MXML_TEXT_CALLBACK</tt> constant which specifies that all
|
||||
data nodes in the document contain whitespace-separated text
|
||||
values. Other standard callbacks include
|
||||
<tt>MXML_IGNORE_CALLBACK</tt>, <tt>MXML_INTEGER_CALLBACK</tt>,
|
||||
<tt>MXML_OPAQUE_CALLBACK</tt>, and
|
||||
<tt>MXML_REAL_CALLBACK</tt>.</p>
|
||||
|
||||
<p>The <a href='#mxmlLoadString'><tt>mxmlLoadString()</tt></a>
|
||||
function loads XML node trees from a string:</p>
|
||||
@ -148,11 +227,11 @@ function loads XML node trees from a string:</p>
|
||||
<!-- NEED 10 -->
|
||||
<pre>
|
||||
char buffer[8192];
|
||||
<a href='#mxml_node_t'>mxml_node_t</a> *tree;
|
||||
mxml_node_t *tree;
|
||||
|
||||
...
|
||||
tree = <a href='#mxmlLoadString'>mxmlLoadString</a>(NULL, buffer,
|
||||
MXML_NO_CALLBACK);
|
||||
tree = mxmlLoadString(NULL, buffer,
|
||||
MXML_TEXT_CALLBACK);
|
||||
</pre>
|
||||
|
||||
<p>The first and third arguments are the same as used for
|
||||
@ -162,6 +241,7 @@ document including the <tt>?xml</tt> element if the parent node
|
||||
is <tt>NULL</tt>.</p>
|
||||
|
||||
|
||||
<!-- NEW PAGE -->
|
||||
<h2>Saving XML</h2>
|
||||
|
||||
<p>You save an XML file using the <a
|
||||
@ -169,10 +249,10 @@ href='#mxmlSaveFile'><tt>mxmlSaveFile()</tt></a> function:</p>
|
||||
|
||||
<pre>
|
||||
FILE *fp;
|
||||
<a href='#mxml_node_t'>mxml_node_t</a> *tree;
|
||||
mxml_node_t *tree;
|
||||
|
||||
fp = fopen("filename.xml", "w");
|
||||
<a href='#mxmlSaveFile'>mxmlSaveFile</a>(tree, fp, MXML_NO_CALLBACK);
|
||||
mxmlSaveFile(tree, fp, MXML_NO_CALLBACK);
|
||||
fclose(fp);
|
||||
</pre>
|
||||
|
||||
@ -186,8 +266,8 @@ by <tt>fopen()</tt> or <tt>popen()</tt>. You can also use
|
||||
program.</p>
|
||||
|
||||
<p>The third argument is the whitespace callback to use when
|
||||
saving the file. Whitespace callbacks are covered in detail in
|
||||
<a href='SAVE_CALLBACKS'>Chapter 3</a>. The example code above
|
||||
saving the file. Whitespace callbacks are covered in detail in <a
|
||||
href='SAVE_CALLBACKS'>Chapter 3</a>. The previous example code
|
||||
uses the <tt>MXML_NO_CALLBACK</tt> constant to specify that no
|
||||
special whitespace handling is required.</p>
|
||||
|
||||
@ -199,14 +279,14 @@ functions save XML node trees to strings:</p>
|
||||
<pre>
|
||||
char buffer[8192];
|
||||
char *ptr;
|
||||
<a href='#mxml_node_t'>mxml_node_t</a> *tree;
|
||||
mxml_node_t *tree;
|
||||
|
||||
...
|
||||
<a href='#mxmlSaveString'>mxmlSaveString</a>(tree, buffer, sizeof(buffer),
|
||||
mxmlSaveString(tree, buffer, sizeof(buffer),
|
||||
MXML_NO_CALLBACK);
|
||||
|
||||
...
|
||||
ptr = <a href='#mxmlSaveAllocString'>mxmlSaveAllocString</a>(tree, MXML_NO_CALLBACK);
|
||||
ptr = mxmlSaveAllocString(tree, MXML_NO_CALLBACK);
|
||||
</pre>
|
||||
|
||||
<p>The first and last arguments are the same as used for
|
||||
@ -216,8 +296,25 @@ a fixed-size buffer, while <tt>mxmlSaveAllocString()</tt>
|
||||
returns a string buffer that was allocated using
|
||||
<tt>malloc()</tt>.</p>
|
||||
|
||||
<h3>Controlling Line Wrapping</h3>
|
||||
|
||||
<h3>Finding and Iterating Nodes</h3>
|
||||
<p>When saving XML documents, Mini-XML normally wraps output
|
||||
lines at column 75 so that the text is readable in terminal
|
||||
windows. The <a
|
||||
href='#mxmlSetWrapMargin'><tt>mxmlSetWrapMargin</tt></a> function
|
||||
overrides the default wrap margin:</p>
|
||||
|
||||
<pre>
|
||||
/* Set the margin to 132 columns */
|
||||
mxmlSetWrapMargin(132);
|
||||
|
||||
/* Disable wrapping */
|
||||
mxmlSetWrapMargin(0);
|
||||
</pre>
|
||||
|
||||
|
||||
<!-- NEW PAGE-->
|
||||
<h2>Finding and Iterating Nodes</h2>
|
||||
|
||||
<p>The <a
|
||||
href='#mxmlWalkPrev'><tt>mxmlWalkPrev()</tt></a>
|
||||
@ -226,11 +323,13 @@ href='#mxmlWalkNext'><tt>mxmlWalkNext()</tt></a>functions
|
||||
can be used to iterate through the XML node tree:</p>
|
||||
|
||||
<pre>
|
||||
<a href='#mxml_node_t'>mxml_node_t</a> *node;
|
||||
mxml_node_t *node;
|
||||
|
||||
node = <a href='#mxmlWalkPrev'>mxmlWalkPrev</a>(current, tree, MXML_DESCEND);
|
||||
node = mxmlWalkPrev(current, tree,
|
||||
MXML_DESCEND);
|
||||
|
||||
node = <a href='#mxmlWalkNext'>mxmlWalkNext</a>(current, tree, MXML_DESCEND);
|
||||
node = mxmlWalkNext(current, tree,
|
||||
MXML_DESCEND);
|
||||
</pre>
|
||||
|
||||
<p>In addition, you can find a named element/node using the <a
|
||||
@ -238,9 +337,9 @@ href='#mxmlFindElement'><tt>mxmlFindElement()</tt></a>
|
||||
function:</p>
|
||||
|
||||
<pre>
|
||||
<a href='#mxml_node_t'>mxml_node_t</a> *node;
|
||||
mxml_node_t *node;
|
||||
|
||||
node = <a href='#mxmlFindElement'>mxmlFindElement</a>(tree, tree, "name",
|
||||
node = mxmlFindElement(tree, tree, "name",
|
||||
"attr", "value",
|
||||
MXML_DESCEND);
|
||||
</pre>
|
||||
@ -249,34 +348,43 @@ function:</p>
|
||||
arguments can be passed as <tt>NULL</tt> to act as wildcards,
|
||||
e.g.:</p>
|
||||
|
||||
<!-- NEED 4 -->
|
||||
<pre>
|
||||
/* Find the first "a" element */
|
||||
node = <a href='#mxmlFindElement'>mxmlFindElement</a>(tree, tree, "a",
|
||||
node = mxmlFindElement(tree, tree, "a",
|
||||
NULL, NULL,
|
||||
MXML_DESCEND);
|
||||
|
||||
</pre>
|
||||
<!-- NEED 5 -->
|
||||
<pre>
|
||||
/* Find the first "a" element with "href"
|
||||
attribute */
|
||||
node = <a href='#mxmlFindElement'>mxmlFindElement</a>(tree, tree, "a",
|
||||
node = mxmlFindElement(tree, tree, "a",
|
||||
"href", NULL,
|
||||
MXML_DESCEND);
|
||||
|
||||
</pre>
|
||||
<!-- NEED 6 -->
|
||||
<pre>
|
||||
/* Find the first "a" element with "href"
|
||||
to a URL */
|
||||
node = <a href='#mxmlFindElement'>mxmlFindElement</a>(tree, tree, "a",
|
||||
node = mxmlFindElement(tree, tree, "a",
|
||||
"href",
|
||||
"http://www.easysw.com/",
|
||||
MXML_DESCEND);
|
||||
|
||||
</pre>
|
||||
<!-- NEED 5 -->
|
||||
<pre>
|
||||
/* Find the first element with a "src"
|
||||
attribute */
|
||||
node = <a href='#mxmlFindElement'>mxmlFindElement</a>(tree, tree, NULL,
|
||||
node = mxmlFindElement(tree, tree, NULL,
|
||||
"src", NULL,
|
||||
MXML_DESCEND);
|
||||
|
||||
</pre>
|
||||
<!-- NEED 5 -->
|
||||
<pre>
|
||||
/* Find the first element with a "src"
|
||||
= "foo.jpg" */
|
||||
node = <a href='#mxmlFindElement'>mxmlFindElement</a>(tree, tree, NULL,
|
||||
node = mxmlFindElement(tree, tree, NULL,
|
||||
"src", "foo.jpg",
|
||||
MXML_DESCEND);
|
||||
</pre>
|
||||
@ -284,13 +392,15 @@ e.g.:</p>
|
||||
<p>You can also iterate with the same function:</p>
|
||||
|
||||
<pre>
|
||||
<a href='#mxml_node_t'>mxml_node_t</a> *node;
|
||||
mxml_node_t *node;
|
||||
|
||||
for (node = <a href='#mxmlFindElement'>mxmlFindElement</a>(tree, tree, "name",
|
||||
for (node = mxmlFindElement(tree, tree,
|
||||
"name",
|
||||
NULL, NULL,
|
||||
MXML_DESCEND);
|
||||
node != NULL;
|
||||
node = <a href='#mxmlFindElement'>mxmlFindElement</a>(node, tree, "name",
|
||||
node = mxmlFindElement(node, tree,
|
||||
"name",
|
||||
NULL, NULL,
|
||||
MXML_DESCEND))
|
||||
{
|
||||
@ -298,6 +408,7 @@ e.g.:</p>
|
||||
}
|
||||
</pre>
|
||||
|
||||
<!-- NEED 10 -->
|
||||
<p>The <tt>MXML_DESCEND</tt> argument can actually be one of
|
||||
three constants:</p>
|
||||
|
||||
@ -309,7 +420,7 @@ three constants:</p>
|
||||
node or top-of-tree is reached. The previous node from
|
||||
"group" would be the "node" element to the left, while
|
||||
the next node from "group" would be the "node" element
|
||||
to the right.</li>
|
||||
to the right.<br><br></li>
|
||||
|
||||
<li><tt>MXML_DESCEND_FIRST</tt> means that it is OK to
|
||||
descend to the first child of a node, but not to descend
|
||||
@ -319,40 +430,19 @@ three constants:</p>
|
||||
in the example above. This mode is only applicable to
|
||||
the search function; the walk functions treat this as
|
||||
<tt>MXML_DESCEND</tt> since every call is a first
|
||||
time.</li>
|
||||
time.<br><br></li>
|
||||
|
||||
<li><tt>MXML_DESCEND</tt> means to keep descending until
|
||||
you hit the bottom of the tree. The previous node from
|
||||
"group" would be the "val3" node and the next node would
|
||||
be the first node element under "group". If you were to
|
||||
walk from the root node "?xml" to the end of the
|
||||
tree with <tt>mxmlWalkNext()</tt>, the order would be:
|
||||
<li><tt>MXML_DESCEND</tt> means to keep descending until
|
||||
you hit the bottom of the tree. The previous node from
|
||||
"group" would be the "val3" node and the next node would
|
||||
be the first node element under "group". If you were to
|
||||
walk from the root node "?xml" to the end of the tree
|
||||
with <tt>mxmlWalkNext()</tt>, the order would be:
|
||||
|
||||
<pre>
|
||||
?xml
|
||||
data
|
||||
node
|
||||
val1
|
||||
node
|
||||
val2
|
||||
node
|
||||
val3
|
||||
group
|
||||
node
|
||||
val4
|
||||
node
|
||||
val5
|
||||
node
|
||||
val6
|
||||
node
|
||||
val7
|
||||
node
|
||||
val8
|
||||
node
|
||||
val9
|
||||
</pre>
|
||||
<p><tt>?xml data node val1 node val2 node val3 group node
|
||||
val4 node val5 node val6 node val7 node val8</tt></p>
|
||||
|
||||
<p>If you started at "val9" and walked using
|
||||
<p>If you started at "val8" and walked using
|
||||
<tt>mxmlWalkPrev()</tt>, the order would be reversed,
|
||||
ending at "?xml".</p></li>
|
||||
|
||||
|
@ -71,6 +71,7 @@
|
||||
<li><a href='#mxmlNewReal'><tt>mxmlNewReal()</tt></a> </li>
|
||||
<li><a href='#mxmlNewText'><tt>mxmlNewText()</tt></a> </li>
|
||||
<li><a href='#mxmlNewTextf'><tt>mxmlNewTextf()</tt></a> </li>
|
||||
<li><a href='#mxmlNewXML'><tt>mxmlNewXML()</tt></a> <span class='info'> Mini-XML 2.3 </span></li>
|
||||
<li><a href='#mxmlRelease'><tt>mxmlRelease()</tt></a> <span class='info'> Mini-XML 2.3 </span></li>
|
||||
<li><a href='#mxmlRemove'><tt>mxmlRemove()</tt></a> </li>
|
||||
<li><a href='#mxmlRetain'><tt>mxmlRetain()</tt></a> <span class='info'> Mini-XML 2.3 </span></li>
|
||||
@ -745,6 +746,29 @@ mxmlNewTextf(
|
||||
<h4>Returns</h4>
|
||||
<p>New node</p>
|
||||
<!-- NEW PAGE -->
|
||||
<h3 class='title'><span class='info'> Mini-XML 2.3 </span><a name='mxmlNewXML'>mxmlNewXML()</a></h3>
|
||||
<h4>Description</h4>
|
||||
<p>Create a new XML document tree.
|
||||
|
||||
The "version" argument specifies the version number to put in the
|
||||
?xml element node. If NULL, version 1.0 is assumed.
|
||||
|
||||
</p>
|
||||
<h4>Syntax</h4>
|
||||
<pre>
|
||||
<a href='#mxml_node_t'>mxml_node_t</a> *
|
||||
mxmlNewXML(
|
||||
const char * version);
|
||||
</pre>
|
||||
<h4>Arguments</h4>
|
||||
<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0'>
|
||||
<thead><tr><th>Name</th><th>Description</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td><tt>version</tt></td><td>Version number to use</td></tr>
|
||||
</tbody></table></div>
|
||||
<h4>Returns</h4>
|
||||
<p>New ?xml node</p>
|
||||
<!-- NEW PAGE -->
|
||||
<h3 class='title'><span class='info'> Mini-XML 2.3 </span><a name='mxmlRelease'>mxmlRelease()</a></h3>
|
||||
<h4>Description</h4>
|
||||
<p>Release a node.
|
||||
|
@ -8,12 +8,14 @@
|
||||
<ul>
|
||||
|
||||
<li>Added two exceptions to the LGPL to support static
|
||||
linking of applications against Mini-XML.</li>
|
||||
linking of applications against Mini-XML</li>
|
||||
|
||||
<li>Added mxmlElementSetAttrf() function (STR #43)</li>
|
||||
<li>Added a mxmlNewXML() function</li>
|
||||
|
||||
<li>Added snprintf() emulation function for test program
|
||||
(STR #32)</li>
|
||||
<li>Added a mxmlElementSetAttrf() function (STR #43)</li>
|
||||
|
||||
<li>Added a snprintf() emulation function for the test
|
||||
program (STR #32)</li>
|
||||
|
||||
<li>Added the _CRT_SECURE_NO_DEPRECATE definition when
|
||||
building on VC++ 2005 (STR #36)</li>
|
||||
@ -21,52 +23,52 @@
|
||||
<li>mxmlLoad*() did not detect missing > characters in
|
||||
elements (STR #41)</li>
|
||||
|
||||
<li>mxmlLoad*() did not detect missing close tags at the end
|
||||
of an XML document (STR #45)</li>
|
||||
<li>mxmlLoad*() did not detect missing close tags at the
|
||||
end of an XML document (STR #45)</li>
|
||||
|
||||
<li>Added user_data and ref_count members to mxml_node_t
|
||||
structure.</li>
|
||||
structure</li>
|
||||
|
||||
<li>Added mxmlReleaseNode() and mxmlRetainNode() APIs for
|
||||
reference-counted nodes.</li>
|
||||
reference-counted nodes</li>
|
||||
|
||||
<li>Added mxmlSetWrapMargin() to control the wrapping of XML
|
||||
output.</li>
|
||||
<li>Added mxmlSetWrapMargin() to control the wrapping of
|
||||
XML output</li>
|
||||
|
||||
<li>Added conditional check for EINTR error code for
|
||||
certain Windows compilers that do not define it (STR
|
||||
#33)</li>
|
||||
|
||||
<li>The mxmldoc program now generates correct HTML 4.0
|
||||
output (previously it generated invalid XHTML...)</li>
|
||||
output - previously it generated invalid XHTML</li>
|
||||
|
||||
<li>The mxmldoc program now supports "@deprecated@,
|
||||
"@private@", and "@since version@" comments.</li>
|
||||
"@private@", and "@since version@" comments</li>
|
||||
|
||||
<li>Fixed function and enumeraion type bugs in
|
||||
mxmldoc.</li>
|
||||
<li>Fixed function and enumeration type bugs in
|
||||
mxmldoc</li>
|
||||
|
||||
<li>Fixed XML schema for mxmldoc.</li>
|
||||
<li>Fixed the XML schema for mxmldoc</li>
|
||||
|
||||
<li>The mxmldoc program now supports --intro, --section,
|
||||
and --title options.</li>
|
||||
and --title options</li>
|
||||
|
||||
<li>The mxmlLoad*() functions could leak a node on an
|
||||
error (STR #27)</li>
|
||||
|
||||
<li>The mxml_vsnprintf() function could get in an infinite
|
||||
loop on a buffer overflow (STR #25)</li>
|
||||
<li>The mxml_vsnprintf() function could get in an
|
||||
infinite loop on a buffer overflow (STR #25)</li>
|
||||
|
||||
<li>Added new mxmlNewCDATA() and mxmlSetCDATA() functions
|
||||
to create and set CDATA nodes, which are really just
|
||||
special element nodes.</li>
|
||||
special element nodes</li>
|
||||
|
||||
<li>Added new MXML_IGNORE type and MXML_IGNORE_CB
|
||||
callback to ignore non-element nodes (i.e.
|
||||
whitespace)</li>
|
||||
callback to ignore non-element nodes, e.g.
|
||||
whitespace</li>
|
||||
|
||||
<li>mxmlLoad*() did not treat custom data as opaque, so
|
||||
whitespace characters would be lost.</li>
|
||||
whitespace characters would be lost</li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
23
mxml-node.c
23
mxml-node.c
@ -27,6 +27,7 @@
|
||||
* mxmlNewReal() - Create a new real number node.
|
||||
* mxmlNewText() - Create a new text fragment node.
|
||||
* mxmlNewTextf() - Create a new formatted text fragment node.
|
||||
* mxmlNewXML() - Create a new XML document tree.
|
||||
* mxmlRelease() - Release a node.
|
||||
* mxmlRemove() - Remove a node from its parent.
|
||||
* mxmlRetain() - Retain a node.
|
||||
@ -655,6 +656,28 @@ mxmlRemove(mxml_node_t *node) /* I - Node to remove */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'mxmlNewXML()' - Create a new XML document tree.
|
||||
*
|
||||
* The "version" argument specifies the version number to put in the
|
||||
* ?xml element node. If NULL, version 1.0 is assumed.
|
||||
*
|
||||
* @since Mini-XML 2.3@
|
||||
*/
|
||||
|
||||
mxml_node_t * /* O - New ?xml node */
|
||||
mxmlNewXML(const char *version) /* I - Version number to use */
|
||||
{
|
||||
char element[1024]; /* Element text */
|
||||
|
||||
|
||||
snprintf(element, sizeof(element), "?xml version=\"%s\"?",
|
||||
version ? version : "1.0");
|
||||
|
||||
return (mxmlNewElement(NULL, element));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'mxmlRelease()' - Release a node.
|
||||
*
|
||||
|
1
mxml.h
1
mxml.h
@ -207,6 +207,7 @@ extern mxml_node_t *mxmlNewTextf(mxml_node_t *parent, int whitespace,
|
||||
__attribute__ ((__format__ (__printf__, 3, 4)))
|
||||
# endif /* __GNUC__ */
|
||||
;
|
||||
extern mxml_node_t *mxmlNewXML(const char *version);
|
||||
extern int mxmlRelease(mxml_node_t *node);
|
||||
extern void mxmlRemove(mxml_node_t *node);
|
||||
extern int mxmlRetain(mxml_node_t *node);
|
||||
|
16
mxml.xml
16
mxml.xml
@ -512,6 +512,22 @@ string must be nul-terminated and is formatted into the new node.</description>
|
||||
<type /> <description>Additional args as needed</description>
|
||||
</argument>
|
||||
</function>
|
||||
<function name="mxmlNewXML">
|
||||
<returnvalue>
|
||||
<type>mxml_node_t *</type>
|
||||
<description>New ?xml node</description>
|
||||
</returnvalue>
|
||||
<description>Create a new XML document tree.
|
||||
|
||||
The "version" argument specifies the version number to put in the
|
||||
?xml element node. If NULL, version 1.0 is assumed.
|
||||
|
||||
@since Mini-XML 2.3@</description>
|
||||
<argument name="version" direction="I">
|
||||
<type>const char *</type>
|
||||
<description>Version number to use</description>
|
||||
</argument>
|
||||
</function>
|
||||
<function name="mxmlRelease">
|
||||
<returnvalue>
|
||||
<type>int</type>
|
||||
|
@ -645,7 +645,7 @@ new_documentation(mxml_node_t **mxmldoc)/* O - mxmldoc node */
|
||||
* Create an empty XML documentation file...
|
||||
*/
|
||||
|
||||
doc = mxmlNewElement(NULL, "?xml version=\"1.0\"?");
|
||||
doc = mxmlNewXML(NULL);
|
||||
|
||||
*mxmldoc = mxmlNewElement(doc, "mxmldoc");
|
||||
|
||||
|
@ -613,7 +613,7 @@ whitespace_cb(mxml_node_t *node, /* I - Element node */
|
||||
else if (where == MXML_WS_AFTER_CLOSE)
|
||||
return ("\n");
|
||||
}
|
||||
else if (!strcmp(name, "?xml"))
|
||||
else if (!strncmp(name, "?xml", 4))
|
||||
{
|
||||
return (NULL);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user