diff --git a/doc/mxml.3 b/doc/mxml.3 index b54bb57..05504e6 100644 --- a/doc/mxml.3 +++ b/doc/mxml.3 @@ -1,4 +1,4 @@ -.TH mxml 3 "Mini-XML API" "2019-02-20" "Mini-XML API" +.TH mxml 3 "Mini-XML API" "2019-03-01" "Mini-XML API" .SH NAME mxml \- Mini-XML API .SH INCLUDE FILE diff --git a/doc/mxml.epub b/doc/mxml.epub index 1715392..863e9d9 100644 Binary files a/doc/mxml.epub and b/doc/mxml.epub differ diff --git a/doc/mxml.html b/doc/mxml.html index 6ba32bc..e8f407c 100644 --- a/doc/mxml.html +++ b/doc/mxml.html @@ -3,91 +3,62 @@
Michael R Sweet
-Copyright © 2003-2019, All Rights Reserved.
+Michael R Sweet
+Copyright © 2003-2019, All Rights Reserved.
+Mini-XML is a small XML parsing library that you can use to read XML data files or strings in your application without requiring large non-standard libraries. Mini-XML provides the following functionality:
Mini-XML doesn't do validation or other types of processing on the data based upon schema files or other sources of definition information.
-Mini-XML was initially developed for the Gutenprint project to replace the rather large and unwieldy libxml2
library with something substantially smaller and easier-to-use. It all began one morning in June of 2003 when Robert posted the following sentence to the developer's list:
It's bad enough that we require libxml2, but rolling our own XML parser is a bit more than we can handle.
@@ -325,14 +315,14 @@ h3.title {
I took my own challenge and coded furiously for two days to produced the initial public release of Mini-XML, total lines of code: 696. Robert promptly integrated Mini-XML into Gutenprint and removed libxml2.
Thanks to lots of feedback and support from various developers, Mini-XML has evolved since then to provide a more complete XML implementation and now stands at a whopping 4,115 lines of code, compared to 140,410 lines of code for libxml2 version 2.9.1.
-The Mini-XML home page can be found at:
https://www.msweet.orgm/mxml
From here you can download the current version of Mini-XML, the issue tracker, and other resources.
-The Mini-XML library is copyright © 2003-2019 by Michael R Sweet and is provided under the Apache License Version 2.0 with an exception to allow linking against GPL2/LGPL2-only software. See the files "LICENSE" and "NOTICE" for more information.
-Mini-XML provides a single header file which you include:
#include <mxml.h>
@@ -342,7 +332,7 @@ h3.title {
If you have the pkg-config
software installed, you can use it to determine the proper compiler and linker options for your installation:
gcc `pkg-config --cflags mxml` -o myprogram myprogram.c `pkg-config --libs mxml`
- You load an XML file using the mxmlLoadFile
function:
mxml_node_t *
mxmlLoadFile(mxml_node_t *top, FILE *fp,
@@ -365,7 +355,7 @@ mxml_node_t *
mxmlLoadString(mxml_node_t *top, const char *s,
mxml_type_t (*cb)(mxml_node_t *));
- The last argument to the mxmlLoad
functions is a callback function which is used to determine the value type of each data node in an XML document. Mini-XML defines several standard callbacks for simple XML data files:
MXML_INTEGER_CALLBACK
: All data nodes contain whitespace-separated integers.Every piece of information in an XML file is stored in memory in "nodes". Nodes are defined by the mxml_node_t
structure. Each node has a typed value, optional user data, a parent node, sibling nodes (previous and next), and potentially child nodes.
For example, if you have an XML file like the following:
<?xml version="1.0" encoding="utf-8"?>
@@ -437,11 +427,19 @@ val1 val2 val3 | val7 val8
| | |
val4 val5 val6
-where "-" is a pointer to the sibling node and "" is a pointer to the first child or parent node.
+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:
mxml_type_t
mxmlGetType(mxml_node_t *node);
+ MXML_CUSTOM
: A custom value defined by your application,MXML_ELEMENT
: An XML element, CDATA, comment, or processing instruction,MXML_INTEGER
: A whitespace-delimited integer value,MXML_OPAQUE
: An opaque string value that preserves all whitespace,MXML_REAL
: A whitespace-delimited floating point value, orMXML_TEXT
: A whitespace-delimited text (fragment) value.@@ -465,7 +463,7 @@ mxmlGetPrevSibling(mxml_node_t *node);Note: CDATA, comment, and processing directive nodes are currently stored in memory as special elements. This will be changed in a future major release of Mini-XML.
void *
mxmlGetUserData(mxml_node_t *node);
- You can create and update XML documents in memory using the various mxmlNew
functions. The following code will create the XML document described in the previous section:
mxml_node_t *xml; /* <?xml ... ?> */
mxml_node_t *data; /* <data> */
@@ -508,7 +506,7 @@ data = mxmlNewElement(xml, "data");
mxmlNewText(node, 0, "val1");
The resulting in-memory XML document can then be saved or processed just like one loaded from disk or a string.
-You save an XML file using the mxmlSaveFile
function:
int
mxmlSaveFile(mxml_node_t *node, FILE *fp,
@@ -532,7 +530,7 @@ int
mxmlSaveString(mxml_node_t *node, char *buffer, int bufsize,
mxml_save_cb_t cb);
- When saving XML documents, Mini-XML normally wraps output lines at column 75 so that the text is readable in terminal windows. The mxmlSetWrapMargin
function overrides the default wrap margin for the current thread:
void mxmlSetWrapMargin(int column);
@@ -542,7 +540,7 @@ mxmlSaveString(mxml_node_t *node, char *buffer, int bufsize,
while the following code disables wrapping by setting the margin to 0:
mxmlSetWrapMargin(0);
- The last argument to the mxmlSave
functions is a callback function which is used to automatically insert whitespace in an XML document. Your callback function will be called up to four times for each element node with a pointer to the node and a "where" value of MXML_WS_BEFORE_OPEN
, MXML_WS_AFTER_OPEN
, MXML_WS_BEFORE_CLOSE
, or MXML_WS_AFTER_CLOSE
. The callback function should return NULL
if no whitespace should be added or 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:
const char *
@@ -617,14 +615,14 @@ fp = fopen("filename.xml", "w");
mxmlSaveFile(tree, fp, whitespace_cb);
fclose(fp);
- Once you are done with the XML data, use the mxmlDelete
function to recursively free the memory that is used for a particular node or the entire tree:
void
mxmlDelete(mxml_node_t *tree);
You can also use reference counting to manage memory usage. The mxmlRetain
and mxmlRelease
functions increment and decrement a node's use count, respectively. When the use count goes to zero, mxmlRelease
automatically calls mxmlDelete
to actually free the memory used by the node tree. New nodes start with a use count of 1.
Element (MXML_ELEMENT
) nodes are created using the mxmlNewElement
function. Element attributes are set using the mxmlElementSetAttr
and mxmlElementSetAttrf
functions and cleared using the mxmlElementDeleteAttr
function:
mxml_node_t *
mxmlNewElement(mxml_node_t *parent, const char *name);
@@ -658,14 +656,14 @@ mxmlElementGetAttrByIndex(mxml_node_t *node, int idx,
int
mxmlElementGetAttrCount(mxml_node_t *node);
- CDATA (MXML_ELEMENT
) nodes are created using the mxmlNewCDATA
function:
mxml_node_t *mxmlNewCDATA(mxml_node_t *parent, const char *string);
The mxmlGetCDATA
function retrieves the CDATA string pointer for a node:
const char *mxmlGetCDATA(mxml_node_t *node);
- Because comments are currently stored as element nodes, comment (MXML_ELEMENT
) nodes are created using the mxmlNewElement
function by including the surrounding "!--" and "--" characters in the element name, for example:
mxml_node_t *node = mxmlNewElement("!-- This is a comment --");
@@ -673,7 +671,7 @@ mxmlElementGetAttrCount(mxml_node_t *node);
const char *comment = mxmlGetElement(node);
/* returns "!-- This is a comment --" */
- Because processing instructions are currently stored as element nodes, processing instruction (MXML_ELEMENT
) nodes are created using the mxmlNewElement
function including the surrounding "?" characters:
mxml_node_t *node = mxmlNewElement("?xml-stylesheet type=\"text/css\" href=\"style.css\"?");
@@ -681,7 +679,7 @@ mxmlElementGetAttrCount(mxml_node_t *node);
const char *instr = mxmlGetElement(node);
/* returned "?xml-stylesheet type=\"text/css\" href=\"style.css\"?" */
- Integer (MXML_INTEGER
) nodes are created using the mxmlNewInteger
function:
mxml_node_t *
mxmlNewInteger(mxml_node_t *parent, int integer);
@@ -690,7 +688,7 @@ mxmlNewInteger(mxml_node_t *parent, int integer);
int
mxmlGetInteger(mxml_node_t *node);
- Opaque String Nodes
+ Opaque String Nodes
Opaque string (MXML_OPAQUE
) nodes are created using the mxmlNewOpaque
function:
mxml_node_t *
mxmlNewOpaque(mxml_node_t *parent, const char *opaque);
@@ -699,7 +697,7 @@ mxmlNewOpaque(mxml_node_t *parent, const char *opaque);
const char *
mxmlGetOpaque(mxml_node_t *node);
- Text Nodes
+ Text Nodes
Whitespace-delimited text string (MXML_TEXT
) nodes are created using the mxmlNewText
and mxmlNewTextf
functions. Each text node consists of a text string and (leading) whitespace flag value.
mxml_node_t *
mxmlNewText(mxml_node_t *parent, int whitespace,
@@ -713,7 +711,7 @@ mxmlNewTextf(mxml_node_t *parent, int whitespace,
const char *
mxmlGetText(mxml_node_t *node, int *whitespace);
- Real Number Nodes
+ Real Number Nodes
Real number (MXML_REAL
) nodes are created using the mxmlNewReal
function:
mxml_node_t *
mxmlNewReal(mxml_node_t *parent, double real);
@@ -722,9 +720,9 @@ mxmlNewReal(mxml_node_t *parent, double real);
double
mxmlGetReal(mxml_node_t *node);
- Locating Data in an XML Document
+ Locating Data in an XML Document
Mini-XML provides many functions for enumerating, searching, and indexing XML documents.
- Finding Nodes
+ Finding Nodes
The mxmlFindPath
function finds the (first) value node under a specific element using a "path":
mxml_node_t *
mxmlFindPath(mxml_node_t *node, const char *path);
@@ -780,7 +778,7 @@ for (node = mxmlFindElement(tree, tree, "element", NULL,
MXML_DESCEND_FIRST
: start the search with the first child of the node, and then search siblings. You'll normally use this when iterating through direct children of a parent node, e.g. all of the "node" and "group" elements under the "?xml" parent node in the previous example.
MXML_DESCEND
: search child nodes first, then sibling nodes, and then parent nodes.
- Iterating Nodes
+ Iterating Nodes
While the mxmlFindNode
and mxmlFindPath
functions will find a particular element node, sometimes you need to iterate over all nodes. The mxmlWalkNext
and mxmlWalkPrev
functions can be used to iterate through the XML node tree:
mxml_node_t *
mxmlWalkNext(mxml_node_t *node, mxml_node_t *top,
@@ -821,7 +819,7 @@ val7
<node>
val8
- Indexing
+ Indexing
The mxmlIndexNew
function allows you to create an index of nodes for faster searching and enumeration:
mxml_index_t *
mxmlIndexNew(mxml_node_t *node, const char *element,
@@ -864,7 +862,7 @@ mxmlIndexGetCount(mxml_index_t *ind);
void
mxmlIndexDelete(mxml_index_t *ind);
- Custom Data Types
+ Custom Data Types
Mini-XML supports custom data types via per-thread load and save callbacks. Only a single set of callbacks can be active at any time for the current thread, however your callbacks can store additional information in order to support multiple custom data types as needed. The MXML_CUSTOM
node type identifies custom data nodes.
The mxmlGetCustom
function retrieves the custom value pointer for a node.
const void *
@@ -996,7 +994,7 @@ save_custom(mxml_node_t *node)
You register the callback functions using the mxmlSetCustomHandlers
function:
mxmlSetCustomHandlers(load_custom, save_custom);
- SAX (Stream) Loading of Documents
+ SAX (Stream) Loading of Documents
Mini-XML supports an implementation of the Simple API for XML (SAX) which allows you to load and process an XML document as a stream of nodes. Aside from allowing you to process XML documents of any size, the Mini-XML implementation also allows you to retain portions of the document in memory for later processing.
The mxmlSAXLoadFd
, mxmlSAXLoadFile
, and mxmlSAXLoadString
functions provide the SAX loading APIs:
mxml_node_t *