Save work on docos.

This commit is contained in:
Michael R Sweet 2024-03-10 10:23:51 -04:00
parent 9e22b3ef64
commit a9aea16f3a
No known key found for this signature in database
GPG Key ID: BE67C75EC81F3244
4 changed files with 69 additions and 98 deletions

View File

@ -45,13 +45,13 @@ I then replied with:
> 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.
I took my own challenge and coded furiously for two days to produced the initial
I took my own challenge and coded furiously for two days to produce the initial
public release of Mini-XML, total lines of code: 696. Robert promptly
integrated Mini-XML into Gutenprint and removed libxml2.
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 3,839 lines of code, compared to 175,808 lines of code for libxml2
at a whopping 3,875 lines of code, compared to 175,808 lines of code for libxml2
version 2.11.7.
@ -62,6 +62,9 @@ The Mini-XML home page can be found at <https://www.msweet.org/mxml>. From
there you can download the current version of Mini-XML, access the issue
tracker, and find other resources.
Mini-XML v4 has a slightly different API than prior releases. See the
[Migrating from Mini-XML v3.x](@) chapter for details.
Legal Stuff
-----------
@ -90,17 +93,20 @@ proper compiler and linker options for your installation:
gcc `pkg-config --cflags mxml4` -o myprogram myprogram.c `pkg-config --libs mxml4`
> Note: The library name "mxml4" is a configure-time option. If you use the
> `--disable-libmxml4-prefix` configure option the library is named "mxml".
Loading an XML File
-------------------
You load an XML file using the `mxmlLoadFile` function:
You load an XML file using the [mxmlLoadFile](@@) function:
```c
mxml_node_t *
mxmlLoadFile(mxml_node_t *top, FILE *fp,
mxml_load_cb_t load_cb, void *load_cbdata,
mxml_sax_cb_t sax_cb, void *sax_cbdata);
mxmlLoadFilename(mxml_node_t *top, const char *filename,
mxml_load_cb_t load_cb, void *load_cbdata,
mxml_sax_cb_t sax_cb, void *sax_cbdata);
```
The `load_cb` argument specifies a function that assigns child (value) node
@ -110,18 +116,16 @@ nodes. For example, to load the XML file "filename.xml" containing literal
strings you can use:
```c
FILE *fp;
mxml_node_t *tree;
mxml_type_t type = MXML_TYPE_OPAQUE;
fp = fopen("filename.xml", "r");
tree = mxmlLoadFile(/*top*/NULL, fp, /*load_cb*/NULL, &type,
/*sax_cb*/NULL, /*sax_cbdata*/NULL);
fclose(fp);
tree = mxmlLoadFilename(/*top*/NULL, "filename.xml",
/*load_cb*/NULL, /*load_cbdata*/&type,
/*sax_cb*/NULL, /*sax_cbdata*/NULL);
```
Mini-XML also provides functions to load from a named file, a file descriptor,
or string:
Mini-XML also provides functions to load from a `FILE` pointer, a file
descriptor, or string:
```c
mxml_node_t *
@ -130,9 +134,9 @@ mxmlLoadFd(mxml_node_t *top, int fd,
mxml_sax_cb_t sax_cb, void *sax_cbdata);
mxml_node_t *
mxmlLoadFilename(mxml_node_t *top, const char *filename,
mxml_load_cb_t load_cb, void *load_cbdata,
mxml_sax_cb_t sax_cb, void *sax_cbdata);
mxmlLoadFile(mxml_node_t *top, FILE *fp,
mxml_load_cb_t load_cb, void *load_cbdata,
mxml_sax_cb_t sax_cb, void *sax_cbdata);
mxml_node_t *
mxmlLoadString(mxml_node_t *top, const char *s,
@ -143,18 +147,19 @@ mxmlLoadString(mxml_node_t *top, const char *s,
### Load Callbacks
The `load_xxx` arguments to the `mxmlLoad` functions are a callback function and
a data pointer which are used to determine the value type of each data node in
an XML document. The default (`NULL`) callback expects the `load_cbdata`
argument to be a pointer to a `mxml_type_t` variable - if `NULL` it returns the
`MXML_TYPE_TEXT` type.
The `load_xxx` arguments to the mxmlLoadXxx functions are a callback function
and a data pointer which are used to determine the value type of each data node
in an XML document. The default (`NULL`) callback expects the `load_cbdata`
argument to be a pointer to a `mxml_type_t` variable that contains the desired
value node type - if `NULL`, it uses the `MXML_TYPE_TEXT` (whitespace-separated
text) type.
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:
You can provide your own callback function 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:
`MXML_TYPE_CUSTOM`, `MXML_TYPE_INTEGER`, `MXML_TYPE_OPAQUE`, `MXML_TYPE_REAL`,
or `MXML_TYPE_TEXT`. The function is called *after* the element and its
attributes have been read, so you can look at the element name, attributes, and
attributes have been read so you can look at the element name, attributes, and
attribute values to determine the proper value type to return.
The following callback function looks for an attribute named "type" or the
@ -162,7 +167,7 @@ element name to determine the value type for its child nodes:
```c
mxml_type_t
type_cb(void *cbdata, mxml_node_t *node)
my_load_cb(void *cbdata, mxml_node_t *node)
{
const char *type;
@ -174,6 +179,8 @@ type_cb(void *cbdata, mxml_node_t *node)
type = mxmlElementGetAttr(node, "type");
if (type == NULL)
type = mxmlGetElement(node);
if (type == NULL)
type = "text";
if (!strcmp(type, "integer"))
return (MXML_TYPE_INTEGER);
@ -186,18 +193,15 @@ type_cb(void *cbdata, mxml_node_t *node)
}
```
To use this callback function, simply use the name when you call any of the load
To use this callback function, simply specify it when you call any of the load
functions:
```c
FILE *fp;
mxml_node_t *tree;
fp = fopen("filename.xml", "r");
tree = mxmlLoadFile(/*top*/NULL, fp,
type_cb, /*load_cbdata*/NULL,
/*sax_cb*/NULL, /*sax_cbata*/NULL);
fclose(fp);
tree = mxmlLoadFilename(/*top*/NULL, "filename.xml",
my_load_cb, /*load_cbdata*/NULL,
/*sax_cb*/NULL, /*sax_cbdata*/NULL);
```
@ -242,7 +246,7 @@ the node tree for the file would look like the following in memory:
where "-" is a pointer to the sibling node and "|" is a pointer to the first
child or parent node.
The `mxmlGetType` function gets the type of a node:
The [mxmlGetType](@@) function gets the type of a node:
```c
mxml_type_t
@ -261,10 +265,10 @@ mxmlGetType(mxml_node_t *node);
- `MXML_TYPE_REAL` : A whitespace-delimited floating point value, or
- `MXML_TYPE_TEXT` : A whitespace-delimited text (fragment) value.
The parent and sibling nodes are accessed using the `mxmlGetParent`,
`mxmlGetNextSibling`, and `mxmlGetPreviousSibling` functions, while the children
of an element node are accessed using the `mxmlGetFirstChild` or
`mxmlGetLastChild` functions:
The parent and sibling nodes are accessed using the [mxmlGetParent](@@),
[mxmlGetNextSibling](@@), and [mxmlGetPreviousSibling](@@) functions, while the
children of an element node are accessed using the [mxmlGetFirstChild](@@) or
[mxmlGetLastChild](@@) functions:
```c
mxml_node_t *
@ -283,8 +287,8 @@ mxml_node_t *
mxmlGetPrevSibling(mxml_node_t *node);
```
The `mxmlGetUserData` function gets any user (application) data associated with
the node:
The [mxmlGetUserData](@@) function gets any user (application) data associated
with the node:
```c
void *

View File

@ -1,4 +1,4 @@
.TH mxml 3 "Mini-XML API" "2024-03-06" "Mini-XML API"
.TH mxml 3 "Mini-XML API" "2024-03-07" "Mini-XML API"
.SH NAME
mxml \- Mini-XML API
.SH INCLUDE FILE
@ -1315,22 +1315,6 @@ bool mxmlSetCustom (
.fi
.PP
The node is not changed if it (or its first child) is not a custom node.
.SS mxmlSetCustomCallbacks
Set the handling functions for custom data.
.PP
.nf
void mxmlSetCustomCallbacks (
mxml_custom_load_cb_t load_cb,
mxml_custom_save_cb_t save_cb,
void *cbdata
);
.fi
.PP
The load function accepts a node pointer and a data string and must
return 0 on success and non-zero on error.
.PP
The save function accepts a node pointer and must return a malloc'd
string on success and \fBNULL\fR on error.
.SS mxmlSetDeclaration
Set a comment to a literal string.
.PP
@ -1380,15 +1364,6 @@ bool mxmlSetElement (
.fi
.PP
The node is not changed if it is not an element node.
.SS mxmlSetErrorCallback
Set the error message callback.
.PP
.nf
void mxmlSetErrorCallback (
mxml_error_cb_t cb,
void *cbdata
);
.fi
.SS mxmlSetInteger
Set the value of an integer node.
.PP
@ -1591,6 +1566,18 @@ SAX event type.
.nf
typedef enum mxml_sax_event_e mxml_sax_event_t;
.fi
.SS mxml_strcopy_cb_t
String copy/allocation callback
.PP
.nf
typedef char *(*)(void *cbdata const char *s) mxml_strcopy_cb_t;
.fi
.SS mxml_strfree_cb_t
String free callback
.PP
.nf
typedef void(*)(void *cbdata char *s) mxml_strfree_cb_t;
.fi
.SS mxml_type_t
The XML node type.
.PP

Binary file not shown.

View File

@ -356,13 +356,11 @@ span.string {
<li><a href="#mxmlSetComment">mxmlSetComment</a></li>
<li><a href="#mxmlSetCommentf">mxmlSetCommentf</a></li>
<li><a href="#mxmlSetCustom">mxmlSetCustom</a></li>
<li><a href="#mxmlSetCustomCallbacks">mxmlSetCustomCallbacks</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>
@ -389,6 +387,8 @@ span.string {
<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_strcopy_cb_t">mxml_strcopy_cb_t</a></li>
<li><a href="#mxml_strfree_cb_t">mxml_strfree_cb_t</a></li>
<li><a href="#mxml_type_t">mxml_type_t</a></li>
<li><a href="#mxml_write_cb_t">mxml_write_cb_t</a></li>
<li><a href="#mxml_ws_t">mxml_ws_t</a></li>
@ -2600,25 +2600,6 @@ bool mxmlSetCustom(<a href="#mxml_node_t">mxml_node_t</a> *node, void *data, <a
<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="mxmlSetCustomCallbacks">mxmlSetCustomCallbacks</a></h3>
<p class="description">Set the handling functions for custom data.</p>
<p class="code">
void mxmlSetCustomCallbacks(<a href="#mxml_custom_load_cb_t">mxml_custom_load_cb_t</a> load_cb, <a href="#mxml_custom_save_cb_t">mxml_custom_save_cb_t</a> save_cb, void *cbdata);</p>
<h4 class="parameters">Parameters</h4>
<table class="list"><tbody>
<tr><th>load_cb</th>
<td class="description">Load callback function</td></tr>
<tr><th>save_cb</th>
<td class="description">Save callback function</td></tr>
<tr><th>cbdata</th>
<td class="description">Callback data</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">
@ -2690,17 +2671,6 @@ bool mxmlSetElement(<a href="#mxml_node_t">mxml_node_t</a> *node, const char *na
<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, void *cbdata);</p>
<h4 class="parameters">Parameters</h4>
<table class="list"><tbody>
<tr><th>cb</th>
<td class="description">Error callback function</td></tr>
<tr><th>cbdata</th>
<td class="description">Error callback data</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">
@ -2932,6 +2902,16 @@ typedef bool (*mxml_sax_cb_t)(void *cbdata <a href="#mxml_node_t">mxml_node_t</a
<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_strcopy_cb_t">mxml_strcopy_cb_t</a></h3>
<p class="description">String copy/allocation callback</p>
<p class="code">
typedef char *(*mxml_strcopy_cb_t)(void *cbdata const char *s);
</p>
<h3 class="typedef"><a id="mxml_strfree_cb_t">mxml_strfree_cb_t</a></h3>
<p class="description">String free callback</p>
<p class="code">
typedef void (*mxml_strfree_cb_t)(void *cbdata char *s);
</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">