mirror of
https://github.com/michaelrsweet/mxml.git
synced 2024-11-24 11:25:30 +00:00
Update documentation for mxmldoc changes and use MXML_OPAQUE_CALLBACK for example (Issue #190)
This commit is contained in:
parent
911f74e0d0
commit
e19d38b5a7
@ -82,7 +82,7 @@ You load an XML file using the `mxmlLoadFile()` function:
|
||||
mxml_node_t *tree;
|
||||
|
||||
fp = fopen("filename.xml", "r");
|
||||
tree = mxmlLoadFile(NULL, fp, MXML_NO_CALLBACK);
|
||||
tree = mxmlLoadFile(NULL, fp, MXML_OPAQUE_CALLBACK);
|
||||
fclose(fp);
|
||||
|
||||
Similarly, you save an XML file using the `mxmlSaveFile()` function:
|
||||
@ -102,7 +102,7 @@ functions load XML node trees from and save XML node trees to strings:
|
||||
mxml_node_t *tree;
|
||||
|
||||
...
|
||||
tree = mxmlLoadString(NULL, buffer, MXML_NO_CALLBACK);
|
||||
tree = mxmlLoadString(NULL, buffer, MXML_OPAQUE_CALLBACK);
|
||||
|
||||
...
|
||||
mxmlSaveString(tree, buffer, sizeof(buffer), MXML_NO_CALLBACK);
|
||||
|
@ -51,41 +51,41 @@ type to return.</p>
|
||||
child nodes:</p>
|
||||
|
||||
<pre>
|
||||
mxml_type_t
|
||||
type_cb(mxml_node_t *node)
|
||||
{
|
||||
const char *type;
|
||||
mxml_type_t
|
||||
type_cb(mxml_node_t *node)
|
||||
{
|
||||
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...
|
||||
*/
|
||||
|
||||
type = mxmlElementGetAttr(node, "type");
|
||||
if (type == NULL)
|
||||
type = mxmlGetElement(node);
|
||||
type = mxmlElementGetAttr(node, "type");
|
||||
if (type == NULL)
|
||||
type = mxmlGetElement(node);
|
||||
|
||||
if (!strcmp(type, "integer"))
|
||||
return (MXML_INTEGER);
|
||||
else if (!strcmp(type, "opaque"))
|
||||
return (MXML_OPAQUE);
|
||||
else if (!strcmp(type, "real"))
|
||||
return (MXML_REAL);
|
||||
else
|
||||
return (MXML_TEXT);
|
||||
}
|
||||
if (!strcmp(type, "integer"))
|
||||
return (MXML_INTEGER);
|
||||
else if (!strcmp(type, "opaque"))
|
||||
return (MXML_OPAQUE);
|
||||
else if (!strcmp(type, "real"))
|
||||
return (MXML_REAL);
|
||||
else
|
||||
return (MXML_TEXT);
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>To use this callback function, simply use the name when you
|
||||
call any of the load functions:</p>
|
||||
|
||||
<pre>
|
||||
FILE *fp;
|
||||
mxml_node_t *tree;
|
||||
FILE *fp;
|
||||
mxml_node_t *tree;
|
||||
|
||||
fp = fopen("filename.xml", "r");
|
||||
tree = mxmlLoadFile(NULL, fp, <b>type_cb</b>);
|
||||
fclose(fp);
|
||||
fp = fopen("filename.xml", "r");
|
||||
tree = mxmlLoadFile(NULL, fp, <b>type_cb</b>);
|
||||
fclose(fp);
|
||||
</pre>
|
||||
|
||||
|
||||
@ -112,85 +112,85 @@ whitespace to XHTML output to make it more readable in a standard
|
||||
text editor:</p>
|
||||
|
||||
<pre>
|
||||
const char *
|
||||
whitespace_cb(mxml_node_t *node,
|
||||
int where)
|
||||
{
|
||||
const char *name;
|
||||
const char *
|
||||
whitespace_cb(mxml_node_t *node,
|
||||
int where)
|
||||
{
|
||||
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 = mxmlGetElement(node);
|
||||
name = mxmlGetElement(node);
|
||||
|
||||
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...
|
||||
*/
|
||||
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...
|
||||
*/
|
||||
|
||||
if (where == MXML_WS_BEFORE_OPEN ||
|
||||
where == MXML_WS_AFTER_CLOSE)
|
||||
return ("\n");
|
||||
}
|
||||
else if (!strcmp(name, "dl") ||
|
||||
!strcmp(name, "ol") ||
|
||||
!strcmp(name, "ul"))
|
||||
{
|
||||
/*
|
||||
* Put a newline before and after list
|
||||
* elements...
|
||||
*/
|
||||
if (where == MXML_WS_BEFORE_OPEN ||
|
||||
where == MXML_WS_AFTER_CLOSE)
|
||||
return ("\n");
|
||||
}
|
||||
else if (!strcmp(name, "dl") ||
|
||||
!strcmp(name, "ol") ||
|
||||
!strcmp(name, "ul"))
|
||||
{
|
||||
/*
|
||||
* Put a newline before and after list
|
||||
* elements...
|
||||
*/
|
||||
|
||||
return ("\n");
|
||||
}
|
||||
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...
|
||||
*/
|
||||
return ("\n");
|
||||
}
|
||||
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...
|
||||
*/
|
||||
|
||||
if (where == MXML_WS_BEFORE_OPEN)
|
||||
return ("\t");
|
||||
else if (where == MXML_WS_AFTER_CLOSE)
|
||||
return ("\n");
|
||||
}
|
||||
if (where == MXML_WS_BEFORE_OPEN)
|
||||
return ("\t");
|
||||
else if (where == MXML_WS_AFTER_CLOSE)
|
||||
return ("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Return NULL for no added whitespace...
|
||||
*/
|
||||
/*
|
||||
* Return NULL for no added whitespace...
|
||||
*/
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>To use this callback function, simply use the name when you
|
||||
call any of the save functions:</p>
|
||||
|
||||
<pre>
|
||||
FILE *fp;
|
||||
mxml_node_t *tree;
|
||||
FILE *fp;
|
||||
mxml_node_t *tree;
|
||||
|
||||
fp = fopen("filename.xml", "w");
|
||||
mxmlSaveFile(tree, fp, <b>whitespace_cb</b>);
|
||||
fclose(fp);
|
||||
fp = fopen("filename.xml", "w");
|
||||
mxmlSaveFile(tree, fp, <b>whitespace_cb</b>);
|
||||
fclose(fp);
|
||||
</pre>
|
||||
|
||||
|
||||
@ -212,97 +212,97 @@ date/time type whose value is encoded as "yyyy-mm-ddThh:mm:ssZ"
|
||||
following:</p>
|
||||
|
||||
<pre>
|
||||
typedef struct
|
||||
{
|
||||
unsigned year, /* Year */
|
||||
month, /* Month */
|
||||
day, /* Day */
|
||||
hour, /* Hour */
|
||||
minute, /* Minute */
|
||||
second; /* Second */
|
||||
time_t unix; /* UNIX time */
|
||||
} iso_date_time_t;
|
||||
typedef struct
|
||||
{
|
||||
unsigned year, /* Year */
|
||||
month, /* Month */
|
||||
day, /* Day */
|
||||
hour, /* Hour */
|
||||
minute, /* Minute */
|
||||
second; /* Second */
|
||||
time_t unix; /* UNIX time */
|
||||
} iso_date_time_t;
|
||||
|
||||
int
|
||||
load_custom(mxml_node_t *node,
|
||||
const char *data)
|
||||
{
|
||||
iso_date_time_t *dt;
|
||||
struct tm tmdata;
|
||||
int
|
||||
load_custom(mxml_node_t *node,
|
||||
const char *data)
|
||||
{
|
||||
iso_date_time_t *dt;
|
||||
struct tm tmdata;
|
||||
|
||||
/*
|
||||
* Allocate data structure...
|
||||
*/
|
||||
/*
|
||||
* Allocate data structure...
|
||||
*/
|
||||
|
||||
dt = calloc(1, sizeof(iso_date_time_t));
|
||||
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)
|
||||
{
|
||||
/*
|
||||
* Unable to read numbers, free the data
|
||||
* structure and return an error...
|
||||
*/
|
||||
if (sscanf(data, "%u-%u-%uT%u:%u:%uZ",
|
||||
&(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...
|
||||
*/
|
||||
|
||||
free(dt);
|
||||
free(dt);
|
||||
|
||||
return (-1);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Range check values...
|
||||
*/
|
||||
/*
|
||||
* Range check values...
|
||||
*/
|
||||
|
||||
if (dt->month < 1 || dt->month > 12 ||
|
||||
dt->day < 1 || dt->day > 31 ||
|
||||
dt->hour < 0 || dt->hour > 23 ||
|
||||
dt->minute < 0 || dt->minute > 59 ||
|
||||
dt->second < 0 || dt->second > 59)
|
||||
{
|
||||
/*
|
||||
* Date information is out of range...
|
||||
*/
|
||||
if (dt->month < 1 || dt->month > 12 ||
|
||||
dt->day < 1 || dt->day > 31 ||
|
||||
dt->hour < 0 || dt->hour > 23 ||
|
||||
dt->minute < 0 || dt->minute > 59 ||
|
||||
dt->second < 0 || dt->second > 59)
|
||||
{
|
||||
/*
|
||||
* Date information is out of range...
|
||||
*/
|
||||
|
||||
free(dt);
|
||||
free(dt);
|
||||
|
||||
return (-1);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert ISO time to UNIX time in
|
||||
* seconds...
|
||||
*/
|
||||
/*
|
||||
* Convert ISO time to UNIX time in
|
||||
* seconds...
|
||||
*/
|
||||
|
||||
tmdata.tm_year = dt->year - 1900;
|
||||
tmdata.tm_mon = dt->month - 1;
|
||||
tmdata.tm_day = dt->day;
|
||||
tmdata.tm_hour = dt->hour;
|
||||
tmdata.tm_min = dt->minute;
|
||||
tmdata.tm_sec = dt->second;
|
||||
tmdata.tm_year = dt->year - 1900;
|
||||
tmdata.tm_mon = dt->month - 1;
|
||||
tmdata.tm_day = dt->day;
|
||||
tmdata.tm_hour = dt->hour;
|
||||
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...
|
||||
*/
|
||||
|
||||
mxmlSetCustom(node, data, destroy);
|
||||
mxmlSetCustom(node, data, destroy);
|
||||
|
||||
/*
|
||||
* Return with no errors...
|
||||
*/
|
||||
/*
|
||||
* Return with no errors...
|
||||
*/
|
||||
|
||||
return (0);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>The function itself can return 0 on success or -1 if it is
|
||||
@ -318,22 +318,22 @@ allocated string containing the custom data value. The following
|
||||
save callback could be used for our ISO date/time type:</p>
|
||||
|
||||
<pre>
|
||||
char *
|
||||
save_custom(mxml_node_t *node)
|
||||
{
|
||||
char data[255];
|
||||
iso_date_time_t *dt;
|
||||
char *
|
||||
save_custom(mxml_node_t *node)
|
||||
{
|
||||
char data[255];
|
||||
iso_date_time_t *dt;
|
||||
|
||||
|
||||
dt = (iso_date_time_t *)mxmlGetCustom(node);
|
||||
dt = (iso_date_time_t *)mxmlGetCustom(node);
|
||||
|
||||
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));
|
||||
}
|
||||
return (strdup(data));
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>You register the callback functions using the <a
|
||||
@ -341,8 +341,8 @@ href='#mxmlSetCustomHandlers'><tt>mxmlSetCustomHandlers()</tt></a>
|
||||
function:</p>
|
||||
|
||||
<pre>
|
||||
mxmlSetCustomHandlers(<b>load_custom</b>,
|
||||
<b>save_custom</b>);
|
||||
mxmlSetCustomHandlers(<b>load_custom</b>,
|
||||
<b>save_custom</b>);
|
||||
</pre>
|
||||
|
||||
|
||||
@ -366,9 +366,9 @@ example, use the following function call to change a text node
|
||||
to contain the text "new" with leading whitespace:</p>
|
||||
|
||||
<pre>
|
||||
mxml_node_t *node;
|
||||
mxml_node_t *node;
|
||||
|
||||
mxmlSetText(node, 1, "new");
|
||||
mxmlSetText(node, 1, "new");
|
||||
</pre>
|
||||
|
||||
|
||||
@ -382,10 +382,10 @@ function call to create a new text node containing a constructed
|
||||
filename:</p>
|
||||
|
||||
<pre>
|
||||
mxml_node_t</a> *node;
|
||||
mxml_node_t</a> *node;
|
||||
|
||||
node = mxmlNewTextf(node, 1, "%s/%s",
|
||||
path, filename);
|
||||
node = mxmlNewTextf(node, 1, "%s/%s",
|
||||
path, filename);
|
||||
</pre>
|
||||
|
||||
|
||||
@ -408,11 +408,11 @@ structures. The <a href='#mxmlIndexNew'><tt>mxmlIndexNew()</tt></a> function
|
||||
creates a new index:</p>
|
||||
|
||||
<pre>
|
||||
mxml_node_t *tree;
|
||||
mxml_index_t *ind;
|
||||
mxml_node_t *tree;
|
||||
mxml_index_t *ind;
|
||||
|
||||
ind = mxmlIndexNew(tree, "element",
|
||||
"attribute");
|
||||
ind = mxmlIndexNew(tree, "element",
|
||||
"attribute");
|
||||
</pre>
|
||||
|
||||
<p>The first argument is the XML node tree to index. Normally this
|
||||
@ -441,14 +441,14 @@ function enumerates each of the nodes in the index and can be
|
||||
used in a loop as follows:</p>
|
||||
|
||||
<pre>
|
||||
mxml_node_t *node;
|
||||
mxml_node_t *node;
|
||||
|
||||
mxmlIndexReset(ind);
|
||||
mxmlIndexReset(ind);
|
||||
|
||||
while ((node = mxmlIndexEnum(ind)) != NULL)
|
||||
{
|
||||
// do something with node
|
||||
}
|
||||
while ((node = mxmlIndexEnum(ind)) != NULL)
|
||||
{
|
||||
// do something with node
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>The <a href='#mxmlIndexFind'><tt>mxmlIndexFind()</tt></a>
|
||||
@ -457,16 +457,16 @@ attribute value in the index. It can be used to find all
|
||||
matching elements in an index, as follows:</p>
|
||||
|
||||
<pre>
|
||||
mxml_node_t *node;
|
||||
mxml_node_t *node;
|
||||
|
||||
mxmlIndexReset(ind);
|
||||
mxmlIndexReset(ind);
|
||||
|
||||
while ((node = mxmlIndexFind(ind, "element",
|
||||
"attr-value"))
|
||||
!= NULL)
|
||||
{
|
||||
// do something with node
|
||||
}
|
||||
while ((node = mxmlIndexFind(ind, "element",
|
||||
"attr-value"))
|
||||
!= NULL)
|
||||
{
|
||||
// do something with node
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>The second and third arguments represent the element name and
|
||||
@ -480,7 +480,7 @@ is equivalent to calling <tt>mxmlIndexEnum</tt>.</p>
|
||||
function:</p>
|
||||
|
||||
<pre>
|
||||
mxmlIndexDelete(ind);
|
||||
mxmlIndexDelete(ind);
|
||||
</pre>
|
||||
|
||||
<h2>SAX (Stream) Loading of Documents</h2>
|
||||
@ -502,13 +502,13 @@ process each node as it is read.</p>
|
||||
a user data pointer you supply:</p>
|
||||
|
||||
<pre>
|
||||
void
|
||||
sax_cb(mxml_node_t *node,
|
||||
mxml_sax_event_t event,
|
||||
void *data)
|
||||
{
|
||||
... do something ...
|
||||
}
|
||||
void
|
||||
sax_cb(mxml_node_t *node,
|
||||
mxml_sax_event_t event,
|
||||
void *data)
|
||||
{
|
||||
... do something ...
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>The event will be one of the following:</p>
|
||||
@ -537,14 +537,14 @@ the following SAX callback will retain all nodes, effectively
|
||||
simulating a normal in-memory load:</p>
|
||||
|
||||
<pre>
|
||||
void
|
||||
sax_cb(mxml_node_t *node,
|
||||
mxml_sax_event_t event,
|
||||
void *data)
|
||||
{
|
||||
if (event != MXML_SAX_ELEMENT_CLOSE)
|
||||
mxmlRetain(node);
|
||||
}
|
||||
void
|
||||
sax_cb(mxml_node_t *node,
|
||||
mxml_sax_event_t event,
|
||||
void *data)
|
||||
{
|
||||
if (event != MXML_SAX_ELEMENT_CLOSE)
|
||||
mxmlRetain(node);
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>More typically the SAX callback will only retain a small portion
|
||||
@ -555,46 +555,46 @@ directives like <tt><?xml ... ?></tt> and <tt><!DOCTYPE ... ></tt>
|
||||
|
||||
<!-- NEED 10 -->
|
||||
<pre>
|
||||
void
|
||||
sax_cb(mxml_node_t *node,
|
||||
mxml_sax_event_t event,
|
||||
void *data)
|
||||
void
|
||||
sax_cb(mxml_node_t *node,
|
||||
mxml_sax_event_t event,
|
||||
void *data)
|
||||
{
|
||||
if (event == MXML_SAX_ELEMENT_OPEN)
|
||||
{
|
||||
/*
|
||||
* Retain headings and titles...
|
||||
*/
|
||||
|
||||
char *name = mxmlGetElement(node);
|
||||
|
||||
if (!strcmp(name, "html") ||
|
||||
!strcmp(name, "head") ||
|
||||
!strcmp(name, "title") ||
|
||||
!strcmp(name, "body") ||
|
||||
!strcmp(name, "h1") ||
|
||||
!strcmp(name, "h2") ||
|
||||
!strcmp(name, "h3") ||
|
||||
!strcmp(name, "h4") ||
|
||||
!strcmp(name, "h5") ||
|
||||
!strcmp(name, "h6"))
|
||||
mxmlRetain(node);
|
||||
}
|
||||
else if (event == MXML_SAX_DIRECTIVE)
|
||||
mxmlRetain(node);
|
||||
else if (event == MXML_SAX_DATA)
|
||||
{
|
||||
if (mxmlGetRefCount(mxmlGetParent(node)) > 1)
|
||||
{
|
||||
if (event == MXML_SAX_ELEMENT_OPEN)
|
||||
{
|
||||
/*
|
||||
* Retain headings and titles...
|
||||
*/
|
||||
/*
|
||||
* If the parent was retained, then retain
|
||||
* this data node as well.
|
||||
*/
|
||||
|
||||
char *name = mxmlGetElement(node);
|
||||
|
||||
if (!strcmp(name, "html") ||
|
||||
!strcmp(name, "head") ||
|
||||
!strcmp(name, "title") ||
|
||||
!strcmp(name, "body") ||
|
||||
!strcmp(name, "h1") ||
|
||||
!strcmp(name, "h2") ||
|
||||
!strcmp(name, "h3") ||
|
||||
!strcmp(name, "h4") ||
|
||||
!strcmp(name, "h5") ||
|
||||
!strcmp(name, "h6"))
|
||||
mxmlRetain(node);
|
||||
}
|
||||
else if (event == MXML_SAX_DIRECTIVE)
|
||||
mxmlRetain(node);
|
||||
else if (event == MXML_SAX_DATA)
|
||||
{
|
||||
if (mxmlGetRefCount(mxmlGetParent(node)) > 1)
|
||||
{
|
||||
/*
|
||||
* If the parent was retained, then retain
|
||||
* this data node as well.
|
||||
*/
|
||||
|
||||
mxmlRetain(node);
|
||||
}
|
||||
}
|
||||
mxmlRetain(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>The resulting skeleton document tree can then be searched just
|
||||
@ -603,30 +603,30 @@ a filter that reads an XHTML document from stdin and then shows the
|
||||
title and headings in the document would look like:</p>
|
||||
|
||||
<pre>
|
||||
mxml_node_t *doc, *title, *body, *heading;
|
||||
mxml_node_t *doc, *title, *body, *heading;
|
||||
|
||||
doc = mxmlSAXLoadFd(NULL, 0,
|
||||
MXML_TEXT_CALLBACK,
|
||||
<b>sax_cb</b>, NULL);
|
||||
doc = mxmlSAXLoadFd(NULL, 0,
|
||||
MXML_TEXT_CALLBACK,
|
||||
<b>sax_cb</b>, NULL);
|
||||
|
||||
title = mxmlFindElement(doc, doc, "title",
|
||||
NULL, NULL,
|
||||
MXML_DESCEND);
|
||||
title = mxmlFindElement(doc, doc, "title",
|
||||
NULL, NULL,
|
||||
MXML_DESCEND);
|
||||
|
||||
if (title)
|
||||
print_children(title);
|
||||
if (title)
|
||||
print_children(title);
|
||||
|
||||
body = mxmlFindElement(doc, doc, "body",
|
||||
NULL, NULL,
|
||||
MXML_DESCEND);
|
||||
body = mxmlFindElement(doc, doc, "body",
|
||||
NULL, NULL,
|
||||
MXML_DESCEND);
|
||||
|
||||
if (body)
|
||||
{
|
||||
for (heading = mxmlGetFirstChild(body);
|
||||
heading;
|
||||
heading = mxmlGetNextSibling(heading))
|
||||
print_children(heading);
|
||||
}
|
||||
if (body)
|
||||
{
|
||||
for (heading = mxmlGetFirstChild(body);
|
||||
heading;
|
||||
heading = mxmlGetNextSibling(heading))
|
||||
print_children(heading);
|
||||
}
|
||||
</pre>
|
||||
|
||||
</body>
|
||||
|
288
doc/basics.html
288
doc/basics.html
@ -26,14 +26,14 @@ functionality:</p>
|
||||
<p>Mini-XML provides a single header file which you include:</p>
|
||||
|
||||
<pre>
|
||||
#include <mxml.h>
|
||||
#include <mxml.h>
|
||||
</pre>
|
||||
|
||||
<p>The Mini-XML library is included with your program using the
|
||||
<kbd>-lmxml</kbd> option:</p>
|
||||
|
||||
<pre>
|
||||
<kbd>gcc -o myprogram myprogram.c -lmxml ENTER</kbd>
|
||||
<kbd>gcc -o myprogram myprogram.c -lmxml ENTER</kbd>
|
||||
</pre>
|
||||
|
||||
<p>If you have the <tt>pkg-config(1)</tt> software installed,
|
||||
@ -41,8 +41,8 @@ you can use it to determine the proper compiler and linker options
|
||||
for your installation:</p>
|
||||
|
||||
<pre>
|
||||
<kbd>pkg-config --cflags mxml ENTER</kbd>
|
||||
<kbd>pkg-config --libs mxml ENTER</kbd>
|
||||
<kbd>pkg-config --cflags mxml ENTER</kbd>
|
||||
<kbd>pkg-config --libs mxml ENTER</kbd>
|
||||
</pre>
|
||||
|
||||
<h2>Nodes</h2>
|
||||
@ -55,35 +55,35 @@ sibling nodes (previous and next), and potentially child nodes.</p>
|
||||
<p>For example, if you have an XML file like the following:</p>
|
||||
|
||||
<pre>
|
||||
<?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>
|
||||
<?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>
|
||||
</pre>
|
||||
|
||||
<p>the node tree for the file would look like the following in memory:</p>
|
||||
|
||||
<pre>
|
||||
?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
|
||||
?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
|
||||
</pre>
|
||||
|
||||
<p>where "-" is a pointer to the sibling node and "|" is a pointer
|
||||
@ -154,22 +154,22 @@ first and last child nodes for the element, respectively.</p>
|
||||
<a href="#mxmlGetInteger"><tt>mxmlGetInteger</tt></a> function retrieves the
|
||||
integer value for a node.</p>
|
||||
|
||||
<h3>Opaque Nodes</h3>
|
||||
<h3>Opaque String Nodes</h3>
|
||||
|
||||
<p>Opaque (<tt>MXML_OPAQUE</tt>) nodes are created using the
|
||||
<p>Opaque string (<tt>MXML_OPAQUE</tt>) nodes are created using the
|
||||
<a href="#mxmlNewOpaque"><tt>mxmlNewOpaque</tt></a> function. The
|
||||
<a href="#mxmlGetOpaque"><tt>mxmlGetOpaque</tt></a> function retrieves the
|
||||
opaque string pointer for a node. Opaque nodes are like string nodes but
|
||||
preserve all whitespace between nodes.</p>
|
||||
|
||||
<h3>Text Nodes</h3>
|
||||
<h3>Text String Nodes</h3>
|
||||
|
||||
<p>Text (<tt>MXML_TEXT</tt>) nodes are created using the
|
||||
<p>Text string (<tt>MXML_TEXT</tt>) nodes are created using the
|
||||
<a href="#mxmlNewText"><tt>mxmlNewText</tt></a> and
|
||||
<a href="#mxmlNewTextf"><tt>mxmlNewTextf</tt></a> functions. Each text node
|
||||
consists of a text string and (leading) whitespace value - the
|
||||
consists of a single word string and (leading) whitespace value - the
|
||||
<a href="#mxmlGetText"><tt>mxmlGetText</tt></a> function retrieves the
|
||||
text string pointer and whitespace value for a node.</p>
|
||||
string pointer and whitespace value for a node.</p>
|
||||
|
||||
<!-- NEED 12 -->
|
||||
<h3>Processing Instruction Nodes</h3>
|
||||
@ -216,35 +216,35 @@ 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> */
|
||||
mxml_node_t *xml; /* <?xml ... ?> */
|
||||
mxml_node_t *data; /* <data> */
|
||||
mxml_node_t *node; /* <node> */
|
||||
mxml_node_t *group; /* <group> */
|
||||
|
||||
xml = mxmlNewXML("1.0");
|
||||
xml = mxmlNewXML("1.0");
|
||||
|
||||
data = mxmlNewElement(xml, "data");
|
||||
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");
|
||||
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");
|
||||
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(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");
|
||||
node = mxmlNewElement(data, "node");
|
||||
mxmlNewText(node, 0, "val7");
|
||||
node = mxmlNewElement(data, "node");
|
||||
mxmlNewText(node, 0, "val8");
|
||||
</pre>
|
||||
|
||||
<!-- NEED 6 -->
|
||||
@ -252,7 +252,7 @@ create the XML document described in the previous section:</p>
|
||||
<a href="#mxmlNewXML"><tt>mxmlNewXML</tt></a> function:</p>
|
||||
|
||||
<pre>
|
||||
xml = mxmlNewXML("1.0");
|
||||
xml = mxmlNewXML("1.0");
|
||||
</pre>
|
||||
|
||||
<p>We then create the <tt><data></tt> node used for this document using
|
||||
@ -261,7 +261,7 @@ argument specifies the parent node (<tt>xml</tt>) while the second specifies the
|
||||
element name (<tt>data</tt>):</p>
|
||||
|
||||
<pre>
|
||||
data = mxmlNewElement(xml, "data");
|
||||
data = mxmlNewElement(xml, "data");
|
||||
</pre>
|
||||
|
||||
<p>Each <tt><node>...</node></tt> in the file is created using the
|
||||
@ -272,8 +272,8 @@ 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");
|
||||
node = mxmlNewElement(data, "node");
|
||||
mxmlNewText(node, 0, "val1");
|
||||
</pre>
|
||||
|
||||
<p>The resulting in-memory XML document can then be saved or processed just like
|
||||
@ -287,13 +287,13 @@ href='#mxmlLoadFile'><tt>mxmlLoadFile</tt></a>
|
||||
function:</p>
|
||||
|
||||
<pre>
|
||||
FILE *fp;
|
||||
mxml_node_t *tree;
|
||||
FILE *fp;
|
||||
mxml_node_t *tree;
|
||||
|
||||
fp = fopen("filename.xml", "r");
|
||||
tree = mxmlLoadFile(NULL, fp,
|
||||
MXML_TEXT_CALLBACK);
|
||||
fclose(fp);
|
||||
fp = fopen("filename.xml", "r");
|
||||
tree = mxmlLoadFile(NULL, fp,
|
||||
MXML_OPAQUE_CALLBACK);
|
||||
fclose(fp);
|
||||
</pre>
|
||||
|
||||
<p>The first argument specifies an existing XML parent node, if
|
||||
@ -313,24 +313,24 @@ 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_TEXT_CALLBACK</tt> constant which specifies that all
|
||||
data nodes in the document contain whitespace-separated text
|
||||
values. Other standard callbacks include
|
||||
the <tt>MXML_OPAQUE_CALLBACK</tt> constant which specifies that all
|
||||
data nodes in the document contain opaque string values with whitespace
|
||||
preserved. 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>
|
||||
<tt>MXML_REAL_CALLBACK</tt>, and
|
||||
<tt>MXML_TEXT_CALLBACK</tt>.</p>
|
||||
|
||||
<p>The <a href='#mxmlLoadString'><tt>mxmlLoadString</tt></a>
|
||||
function loads XML node trees from a string:</p>
|
||||
|
||||
<!-- NEED 10 -->
|
||||
<pre>
|
||||
char buffer[8192];
|
||||
mxml_node_t *tree;
|
||||
char buffer[8192];
|
||||
mxml_node_t *tree;
|
||||
|
||||
...
|
||||
tree = mxmlLoadString(NULL, buffer,
|
||||
MXML_TEXT_CALLBACK);
|
||||
...
|
||||
tree = mxmlLoadString(NULL, buffer,
|
||||
MXML_OPAQUE_CALLBACK);
|
||||
</pre>
|
||||
|
||||
<p>The first and third arguments are the same as used for
|
||||
@ -347,12 +347,12 @@ is <tt>NULL</tt>.</p>
|
||||
href='#mxmlSaveFile'><tt>mxmlSaveFile</tt></a> function:</p>
|
||||
|
||||
<pre>
|
||||
FILE *fp;
|
||||
mxml_node_t *tree;
|
||||
FILE *fp;
|
||||
mxml_node_t *tree;
|
||||
|
||||
fp = fopen("filename.xml", "w");
|
||||
mxmlSaveFile(tree, fp, MXML_NO_CALLBACK);
|
||||
fclose(fp);
|
||||
fp = fopen("filename.xml", "w");
|
||||
mxmlSaveFile(tree, fp, MXML_NO_CALLBACK);
|
||||
fclose(fp);
|
||||
</pre>
|
||||
|
||||
<p>The first argument is the XML node tree to save. It should
|
||||
@ -376,16 +376,16 @@ and <a href='#mxmlSaveString'><tt>mxmlSaveString</tt></a>
|
||||
functions save XML node trees to strings:</p>
|
||||
|
||||
<pre>
|
||||
char buffer[8192];
|
||||
char *ptr;
|
||||
mxml_node_t *tree;
|
||||
char buffer[8192];
|
||||
char *ptr;
|
||||
mxml_node_t *tree;
|
||||
|
||||
...
|
||||
mxmlSaveString(tree, buffer, sizeof(buffer),
|
||||
MXML_NO_CALLBACK);
|
||||
...
|
||||
mxmlSaveString(tree, buffer, sizeof(buffer),
|
||||
MXML_NO_CALLBACK);
|
||||
|
||||
...
|
||||
ptr = mxmlSaveAllocString(tree, MXML_NO_CALLBACK);
|
||||
...
|
||||
ptr = mxmlSaveAllocString(tree, MXML_NO_CALLBACK);
|
||||
</pre>
|
||||
|
||||
<p>The first and last arguments are the same as used for
|
||||
@ -405,11 +405,11 @@ href='#mxmlSetWrapMargin'><tt>mxmlSetWrapMargin</tt></a> function
|
||||
overrides the default wrap margin:</p>
|
||||
|
||||
<pre>
|
||||
/* Set the margin to 132 columns */
|
||||
mxmlSetWrapMargin(132);
|
||||
/* Set the margin to 132 columns */
|
||||
mxmlSetWrapMargin(132);
|
||||
|
||||
/* Disable wrapping */
|
||||
mxmlSetWrapMargin(0);
|
||||
/* Disable wrapping */
|
||||
mxmlSetWrapMargin(0);
|
||||
</pre>
|
||||
|
||||
<h2>Memory Management</h2>
|
||||
@ -420,7 +420,7 @@ free the memory that is used for a particular node or the entire
|
||||
tree:</p>
|
||||
|
||||
<pre>
|
||||
mxmlDelete(tree);
|
||||
mxmlDelete(tree);
|
||||
</pre>
|
||||
|
||||
<p>You can also use reference counting to manage memory usage. The
|
||||
@ -442,13 +442,13 @@ href='#mxmlWalkNext'><tt>mxmlWalkNext</tt></a>functions
|
||||
can be used to iterate through the XML node tree:</p>
|
||||
|
||||
<pre>
|
||||
mxml_node_t *node;
|
||||
mxml_node_t *node;
|
||||
|
||||
node = mxmlWalkPrev(current, tree,
|
||||
MXML_DESCEND);
|
||||
node = mxmlWalkPrev(current, tree,
|
||||
MXML_DESCEND);
|
||||
|
||||
node = mxmlWalkNext(current, tree,
|
||||
MXML_DESCEND);
|
||||
node = mxmlWalkNext(current, tree,
|
||||
MXML_DESCEND);
|
||||
</pre>
|
||||
|
||||
<p>In addition, you can find a named element/node using the <a
|
||||
@ -456,11 +456,11 @@ href='#mxmlFindElement'><tt>mxmlFindElement</tt></a>
|
||||
function:</p>
|
||||
|
||||
<pre>
|
||||
mxml_node_t *node;
|
||||
mxml_node_t *node;
|
||||
|
||||
node = mxmlFindElement(tree, tree, "name",
|
||||
"attr", "value",
|
||||
MXML_DESCEND);
|
||||
node = mxmlFindElement(tree, tree, "name",
|
||||
"attr", "value",
|
||||
MXML_DESCEND);
|
||||
</pre>
|
||||
|
||||
<p>The <tt>name</tt>, <tt>attr</tt>, and <tt>value</tt>
|
||||
@ -469,62 +469,62 @@ e.g.:</p>
|
||||
|
||||
<!-- NEED 4 -->
|
||||
<pre>
|
||||
/* Find the first "a" element */
|
||||
node = mxmlFindElement(tree, tree, "a",
|
||||
NULL, NULL,
|
||||
MXML_DESCEND);
|
||||
/* Find the first "a" element */
|
||||
node = mxmlFindElement(tree, tree, "a",
|
||||
NULL, NULL,
|
||||
MXML_DESCEND);
|
||||
</pre>
|
||||
<!-- NEED 5 -->
|
||||
<pre>
|
||||
/* Find the first "a" element with "href"
|
||||
attribute */
|
||||
node = mxmlFindElement(tree, tree, "a",
|
||||
"href", NULL,
|
||||
MXML_DESCEND);
|
||||
/* Find the first "a" element with "href"
|
||||
attribute */
|
||||
node = mxmlFindElement(tree, tree, "a",
|
||||
"href", NULL,
|
||||
MXML_DESCEND);
|
||||
</pre>
|
||||
<!-- NEED 6 -->
|
||||
<pre>
|
||||
/* Find the first "a" element with "href"
|
||||
to a URL */
|
||||
node = mxmlFindElement(tree, tree, "a",
|
||||
"href",
|
||||
"http://www.easysw.com/",
|
||||
MXML_DESCEND);
|
||||
/* Find the first "a" element with "href"
|
||||
to a URL */
|
||||
node = mxmlFindElement(tree, tree, "a",
|
||||
"href",
|
||||
"http://www.example.com/",
|
||||
MXML_DESCEND);
|
||||
</pre>
|
||||
<!-- NEED 5 -->
|
||||
<pre>
|
||||
/* Find the first element with a "src"
|
||||
attribute */
|
||||
node = mxmlFindElement(tree, tree, NULL,
|
||||
"src", NULL,
|
||||
MXML_DESCEND);
|
||||
/* Find the first element with a "src"
|
||||
attribute */
|
||||
node = mxmlFindElement(tree, tree, NULL,
|
||||
"src", NULL,
|
||||
MXML_DESCEND);
|
||||
</pre>
|
||||
<!-- NEED 5 -->
|
||||
<pre>
|
||||
/* Find the first element with a "src"
|
||||
= "foo.jpg" */
|
||||
node = mxmlFindElement(tree, tree, NULL,
|
||||
"src", "foo.jpg",
|
||||
MXML_DESCEND);
|
||||
/* Find the first element with a "src"
|
||||
= "foo.jpg" */
|
||||
node = mxmlFindElement(tree, tree, NULL,
|
||||
"src", "foo.jpg",
|
||||
MXML_DESCEND);
|
||||
</pre>
|
||||
|
||||
<p>You can also iterate with the same function:</p>
|
||||
|
||||
<pre>
|
||||
mxml_node_t *node;
|
||||
mxml_node_t *node;
|
||||
|
||||
for (node = mxmlFindElement(tree, tree,
|
||||
"name",
|
||||
NULL, NULL,
|
||||
MXML_DESCEND);
|
||||
node != NULL;
|
||||
node = mxmlFindElement(node, tree,
|
||||
"name",
|
||||
NULL, NULL,
|
||||
MXML_DESCEND))
|
||||
{
|
||||
... do something ...
|
||||
}
|
||||
for (node = mxmlFindElement(tree, tree,
|
||||
"name",
|
||||
NULL, NULL,
|
||||
MXML_DESCEND);
|
||||
node != NULL;
|
||||
node = mxmlFindElement(node, tree,
|
||||
"name",
|
||||
NULL, NULL,
|
||||
MXML_DESCEND))
|
||||
{
|
||||
... do something ...
|
||||
}
|
||||
</pre>
|
||||
|
||||
<!-- NEED 10 -->
|
||||
@ -577,9 +577,9 @@ three constants:</p>
|
||||
href='#mxmlFindValue'><tt>mxmlFindPath</tt></a>, for example:
|
||||
|
||||
<pre>
|
||||
mxml_node_t *value;
|
||||
mxml_node_t *value;
|
||||
|
||||
value = mxmlFindPath(tree, "path/to/*/foo/bar");
|
||||
value = mxmlFindPath(tree, "path/to/*/foo/bar");
|
||||
</pre>
|
||||
|
||||
<p>The second argument is a "path" to the parent node. Each component of the
|
||||
|
@ -73,46 +73,5 @@ directories:</p>
|
||||
</pre>
|
||||
|
||||
|
||||
<h2>Creating Mini-XML Packages</h2>
|
||||
|
||||
<p>Mini-XML includes two files that can be used to create binary
|
||||
packages. The first file is <var>mxml.spec</var> which is used
|
||||
by the <tt>rpmbuild(8)</tt> software to create Red Hat Package
|
||||
Manager ("RPM") packages which are commonly used on Linux. Since
|
||||
<tt>rpmbuild</tt> wants to compile the software on its own, you
|
||||
can provide it with the Mini-XML tar file to build the
|
||||
package:</p>
|
||||
|
||||
<pre>
|
||||
<kbd>rpmbuild -ta mxml-<i>version</i>.tar.gz ENTER</kbd>
|
||||
</pre>
|
||||
|
||||
<p>The second file is <var>mxml.list</var> which is used by the
|
||||
<tt>epm(1)</tt> program to create software packages in a variety
|
||||
of formats. The <tt>epm</tt> program is available from the
|
||||
following URL:</p>
|
||||
|
||||
<pre>
|
||||
<a href="http://www.epmhome.org/">http://www.epmhome.org/</a>
|
||||
</pre>
|
||||
|
||||
<p>Use the <tt>make</tt> command with the <kbd>epm</kbd> target
|
||||
to create portable and native packages for your system:</p>
|
||||
|
||||
<pre>
|
||||
<kbd>make epm ENTER</kbd>
|
||||
</pre>
|
||||
|
||||
<p>The packages are stored in a subdirectory named
|
||||
<var>dist</var> for your convenience. The portable packages
|
||||
utilize scripts and tar files to install the software on the
|
||||
target system. After extracting the package archive, use the
|
||||
<var>mxml.install</var> script to install the software.</p>
|
||||
|
||||
<p>The native packages will be in the local OS's native format:
|
||||
RPM for Red Hat Linux, DPKG for Debian Linux, PKG for Solaris,
|
||||
and so forth. Use the corresponding commands to install the
|
||||
native packages.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
1302
doc/mxml.html
1302
doc/mxml.html
File diff suppressed because it is too large
Load Diff
24
doc/mxml.man
24
doc/mxml.man
@ -578,6 +578,12 @@ const char * mxmlGetText (
|
||||
.PP
|
||||
\fBNULL\fR is returned if the node (or its first child) is not a text node.
|
||||
The "whitespace" argument can be \fBNULL\fR.
|
||||
.PP
|
||||
Note: Text nodes consist of whitespace-delimited words. You will only get
|
||||
single words of text when reading an XML file with \fBMXML_TEXT\fR nodes.
|
||||
If you want the entire string between elements in the XML file, you MUST read
|
||||
the XML file with \fBMXML_OPAQUE\fR nodes and get the resulting strings
|
||||
using the \fImxmlGetOpaque\fR function instead.
|
||||
|
||||
|
||||
.SS mxmlGetType
|
||||
@ -693,6 +699,12 @@ function returns the value type that should be used for child nodes.
|
||||
The constants \fBMXML_INTEGER_CALLBACK\fR, \fBMXML_OPAQUE_CALLBACK\fR,
|
||||
\fBMXML_REAL_CALLBACK\fR, and \fBMXML_TEXT_CALLBACK\fR are defined for
|
||||
loading child (data) nodes of the specified type.
|
||||
.PP
|
||||
Note: The most common programming error when using the Mini-XML library is
|
||||
to load an XML file using the \fBMXML_TEXT_CALLBACK\fR, which returns inline
|
||||
text as a series of whitespace-delimited words, instead of using the
|
||||
\fBMXML_OPAQUE_CALLBACK\fR which returns the inline text as a single string
|
||||
(including whitespace).
|
||||
.SS mxmlLoadFile
|
||||
Load a file into an XML node tree.
|
||||
.PP
|
||||
@ -711,6 +723,12 @@ function returns the value type that should be used for child nodes.
|
||||
The constants \fBMXML_INTEGER_CALLBACK\fR, \fBMXML_OPAQUE_CALLBACK\fR,
|
||||
\fBMXML_REAL_CALLBACK\fR, and \fBMXML_TEXT_CALLBACK\fR are defined for
|
||||
loading child (data) nodes of the specified type.
|
||||
.PP
|
||||
Note: The most common programming error when using the Mini-XML library is
|
||||
to load an XML file using the \fBMXML_TEXT_CALLBACK\fR, which returns inline
|
||||
text as a series of whitespace-delimited words, instead of using the
|
||||
\fBMXML_OPAQUE_CALLBACK\fR which returns the inline text as a single string
|
||||
(including whitespace).
|
||||
.SS mxmlLoadString
|
||||
Load a string into an XML node tree.
|
||||
.PP
|
||||
@ -729,6 +747,12 @@ function returns the value type that should be used for child nodes.
|
||||
The constants \fBMXML_INTEGER_CALLBACK\fR, \fBMXML_OPAQUE_CALLBACK\fR,
|
||||
\fBMXML_REAL_CALLBACK\fR, and \fBMXML_TEXT_CALLBACK\fR are defined for
|
||||
loading child (data) nodes of the specified type.
|
||||
.PP
|
||||
Note: The most common programming error when using the Mini-XML library is
|
||||
to load an XML file using the \fBMXML_TEXT_CALLBACK\fR, which returns inline
|
||||
text as a series of whitespace-delimited words, instead of using the
|
||||
\fBMXML_OPAQUE_CALLBACK\fR which returns the inline text as a single string
|
||||
(including whitespace).
|
||||
.SS mxmlNewCDATA
|
||||
Create a new CDATA node.
|
||||
.PP
|
||||
|
BIN
doc/mxml.pdf
BIN
doc/mxml.pdf
Binary file not shown.
100
doc/mxmldoc.html
100
doc/mxmldoc.html
@ -26,7 +26,7 @@ header files in the current directory and produce a HTML
|
||||
documentation file called <var>filename.html</var>:</p>
|
||||
|
||||
<pre>
|
||||
<kbd>mxmldoc *.h *.c >filename.html ENTER</kbd>
|
||||
<kbd>mxmldoc *.h *.c >filename.html ENTER</kbd>
|
||||
</pre>
|
||||
|
||||
<p>You can also specify an XML file to create which contains all of
|
||||
@ -35,21 +35,21 @@ command creates an XML file called <var>filename.xml</var> in
|
||||
addition to the HTML file:</p>
|
||||
|
||||
<pre>
|
||||
<kbd>mxmldoc filename.xml *.h *.c >filename.html ENTER</kbd>
|
||||
<kbd>mxmldoc filename.xml *.h *.c >filename.html ENTER</kbd>
|
||||
</pre>
|
||||
|
||||
<p>The <tt>--no-output</tt> option disables the normal HTML
|
||||
output:</p>
|
||||
|
||||
<pre>
|
||||
<kbd>mxmldoc --no-output filename.xml *.h *.c ENTER</kbd>
|
||||
<kbd>mxmldoc --no-output filename.xml *.h *.c ENTER</kbd>
|
||||
</pre>
|
||||
|
||||
<p>You can then run <tt>mxmldoc</tt> again with the XML file alone
|
||||
to generate the HTML documentation:</p>
|
||||
|
||||
<pre>
|
||||
<kbd>mxmldoc filename.xml >filename.html ENTER</kbd>
|
||||
<kbd>mxmldoc filename.xml >filename.html ENTER</kbd>
|
||||
</pre>
|
||||
|
||||
<h3>Creating Man Pages</h3>
|
||||
@ -58,11 +58,11 @@ to generate the HTML documentation:</p>
|
||||
create a man page instead of HTML documentation, for example:</p>
|
||||
|
||||
<pre>
|
||||
<kbd>mxmldoc --man filename filename.xml \
|
||||
>filename.man ENTER</kbd>
|
||||
<kbd>mxmldoc --man filename filename.xml \
|
||||
>filename.man ENTER</kbd>
|
||||
|
||||
<kbd>mxmldoc --man filename *.h *.c \
|
||||
>filename.man ENTER</kbd>
|
||||
<kbd>mxmldoc --man filename *.h *.c \
|
||||
>filename.man ENTER</kbd>
|
||||
</pre>
|
||||
|
||||
<h3>Creating EPUB Books</h3>
|
||||
@ -71,24 +71,10 @@ create a man page instead of HTML documentation, for example:</p>
|
||||
create an EPUB book containing the HTML documentation, for example:</p>
|
||||
|
||||
<pre>
|
||||
<kbd>mxmldoc --epub foo.epub *.h *.c foo.xml ENTER</kbd>
|
||||
<kbd>mxmldoc --epub foo.epub *.h *.c foo.xml ENTER</kbd>
|
||||
</pre>
|
||||
|
||||
|
||||
<h3>Creating Xcode Documentation Sets</h3>
|
||||
|
||||
<p>The <tt>--docset directory.docset</tt> option tells <tt>mxmldoc</tt> to
|
||||
create an Xcode documentation set containing the HTML documentation, for
|
||||
example:</p>
|
||||
|
||||
<pre>
|
||||
<kbd>mxmldoc --docset foo.docset *.h *.c foo.xml ENTER</kbd>
|
||||
</pre>
|
||||
|
||||
<p>Xcode documentation sets can only be built on macOS with Xcode 3.0 or
|
||||
higher installed.</p>
|
||||
|
||||
|
||||
<h2>Commenting Your Code</h2>
|
||||
|
||||
<p>As noted previously, <tt>mxmldoc</tt> looks for in-line comments
|
||||
@ -107,47 +93,47 @@ example, the following code excerpt defines a key/value structure
|
||||
and a function that creates a new instance of that structure:</p>
|
||||
|
||||
<pre>
|
||||
/* A key/value pair. This is used with the
|
||||
dictionary structure. */
|
||||
/* A key/value pair. This is used with the
|
||||
dictionary structure. */
|
||||
|
||||
struct keyval
|
||||
{
|
||||
char *key; /* Key string */
|
||||
char *val; /* Value string */
|
||||
};
|
||||
struct keyval
|
||||
{
|
||||
char *key; /* Key string */
|
||||
char *val; /* Value string */
|
||||
};
|
||||
|
||||
/* Create a new key/value pair. */
|
||||
/* Create a new key/value pair. */
|
||||
|
||||
struct keyval * /* New key/value pair */
|
||||
new_keyval(
|
||||
const char *key, /* Key string */
|
||||
const char *val) /* Value string */
|
||||
{
|
||||
...
|
||||
}
|
||||
struct keyval * /* New key/value pair */
|
||||
new_keyval(
|
||||
const char *key, /* Key string */
|
||||
const char *val) /* Value string */
|
||||
{
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p><tt>Mxmldoc</tt> also knows to remove extra asterisks (*) from
|
||||
the comment string, so the comment string:</p>
|
||||
|
||||
<pre>
|
||||
/*
|
||||
* Compute the value of PI.
|
||||
*
|
||||
* The function connects to an Internet server
|
||||
* that streams audio of mathematical monks
|
||||
* chanting the first 100 digits of PI.
|
||||
*/
|
||||
/*
|
||||
* Compute the value of PI.
|
||||
*
|
||||
* The function connects to an Internet server
|
||||
* that streams audio of mathematical monks
|
||||
* chanting the first 100 digits of PI.
|
||||
*/
|
||||
</pre>
|
||||
|
||||
<p>will be shown as:</p>
|
||||
|
||||
<pre>
|
||||
Compute the value of PI.
|
||||
Compute the value of PI.
|
||||
|
||||
The function connects to an Internet server
|
||||
that streams audio of mathematical monks
|
||||
chanting the first 100 digits of PI.
|
||||
The function connects to an Internet server
|
||||
that streams audio of mathematical monks
|
||||
chanting the first 100 digits of PI.
|
||||
</pre>
|
||||
|
||||
<p><a name="ATDIRECTIVES">Comments</a> can also include the
|
||||
@ -159,9 +145,9 @@ following special <tt>@name ...@</tt> directive strings:</p>
|
||||
discourage its use</li>
|
||||
|
||||
<li><tt>@exclude format[,...,format]@</tt> - excludes the item from the
|
||||
documentation in the specified formats: "all" for all formats, "docset"
|
||||
for Xcode documentation sets, "epub" for EPUB books, "html" for HTML
|
||||
output, and "man" for man page output</li>
|
||||
documentation in the specified formats: "all" for all formats, "epub"
|
||||
for EPUB books, "html" for HTML output, and "man" for man page
|
||||
output</li>
|
||||
|
||||
<li><tt>@private@</tt> - flags the item as private so it
|
||||
will not be included in the documentation</li>
|
||||
@ -183,9 +169,9 @@ and introduction text for the generated documentation. The
|
||||
documentation. The title string is usually put in quotes:</p>
|
||||
|
||||
<pre>
|
||||
<kbd>mxmldoc filename.xml \
|
||||
--title "My Famous Documentation" \
|
||||
>filename.html ENTER</kbd>
|
||||
<kbd>mxmldoc filename.xml \
|
||||
--title "My Famous Documentation" \
|
||||
>filename.html ENTER</kbd>
|
||||
</pre>
|
||||
|
||||
<p>The <tt>--section name</tt> option specifies the section for
|
||||
@ -193,7 +179,7 @@ the documentation. For HTML documentation, the name is placed in
|
||||
a HTML comment such as:</p>
|
||||
|
||||
<pre>
|
||||
<!-- SECTION: name -->
|
||||
<!-- SECTION: name -->
|
||||
</pre>
|
||||
|
||||
<p>For man pages, the section name is usually just a number ("3"),
|
||||
@ -201,7 +187,7 @@ or a number followed by a vendor name ("3acme"). The section name is
|
||||
used in the <tt>.TH</tt> directive in the man page:</p>
|
||||
|
||||
<pre>
|
||||
.TH mylibrary 3acme "My Title" ...
|
||||
.TH mylibrary 3acme "My Title" ...
|
||||
</pre>
|
||||
|
||||
<p>The default section name for man page output is "3". There is no
|
||||
|
@ -703,7 +703,13 @@ const char *mxmlGetText(<a href="#mxml_node_t">mxml_node_t</a> *node, int *white
|
||||
<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>.
|
||||
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_TEXT</code> nodes.
|
||||
If you want the entire string between elements in the XML file, you MUST read
|
||||
the XML file with <code>MXML_OPAQUE</code> nodes and get the resulting strings
|
||||
using the <a href="#mxmlGetOpaque"><code>mxmlGetOpaque</code></a> function instead.
|
||||
|
||||
</p>
|
||||
<h3 class="function"><span class="info"> Mini-XML 2.7 </span><a id="mxmlGetType">mxmlGetType</a></h3>
|
||||
@ -845,7 +851,13 @@ single parent node like <?xml> 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_OPAQUE_CALLBACK</code>,
|
||||
<code>MXML_REAL_CALLBACK</code>, and <code>MXML_TEXT_CALLBACK</code> are defined for
|
||||
loading child (data) nodes of the specified type.</p>
|
||||
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">
|
||||
@ -868,7 +880,13 @@ single parent node like <?xml> 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_OPAQUE_CALLBACK</code>,
|
||||
<code>MXML_REAL_CALLBACK</code>, and <code>MXML_TEXT_CALLBACK</code> are defined for
|
||||
loading child (data) nodes of the specified type.</p>
|
||||
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">
|
||||
@ -891,7 +909,13 @@ single parent node like <?xml> 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_OPAQUE_CALLBACK</code>,
|
||||
<code>MXML_REAL_CALLBACK</code>, and <code>MXML_TEXT_CALLBACK</code> are defined for
|
||||
loading child (data) nodes of the specified type.</p>
|
||||
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"><span class="info"> Mini-XML 2.3 </span><a id="mxmlNewCDATA">mxmlNewCDATA</a></h3>
|
||||
<p class="description">Create a new CDATA node.</p>
|
||||
<p class="code">
|
||||
|
Loading…
Reference in New Issue
Block a user