2024-03-20 16:12:47 +00:00
|
|
|
Mini-XML - Tiny XML Parsing Library v4
|
|
|
|
======================================
|
2021-10-26 19:48:02 +00:00
|
|
|
|
|
|
|
![Version](https://img.shields.io/github/v/release/michaelrsweet/mxml?include_prereleases)
|
|
|
|
![Apache 2.0](https://img.shields.io/github/license/michaelrsweet/mxml)
|
|
|
|
![Build](https://github.com/michaelrsweet/mxml/workflows/Build/badge.svg)
|
|
|
|
[![Coverity Scan Status](https://img.shields.io/coverity/scan/23959.svg)](https://scan.coverity.com/projects/michaelrsweet-mxml)
|
2024-02-27 20:04:27 +00:00
|
|
|
|
2017-03-22 19:23:27 +00:00
|
|
|
|
|
|
|
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.
|
2024-03-20 16:12:47 +00:00
|
|
|
Mini-XML only requires a "make" program and a C99 compatible compiler - GCC
|
|
|
|
works, as do most vendors' C compilers.
|
2017-03-22 19:23:27 +00:00
|
|
|
|
|
|
|
Mini-XML provides the following functionality:
|
|
|
|
|
|
|
|
- Reading of UTF-8 and UTF-16 and writing of UTF-8 encoded XML files and
|
|
|
|
strings.
|
|
|
|
- Data is stored in a linked-list tree structure, preserving the XML data
|
|
|
|
hierarchy.
|
|
|
|
- SAX (streamed) reading of XML files and strings to minimize memory usage.
|
|
|
|
- Supports arbitrary element names, attributes, and attribute values with no
|
|
|
|
preset limits, just available memory.
|
2024-03-20 16:12:47 +00:00
|
|
|
- Supports integer, real, opaque, text, and custom data types in "leaf" nodes.
|
2017-03-22 19:23:27 +00:00
|
|
|
- Functions for creating and managing trees of data.
|
|
|
|
- "Find" and "walk" functions for easily locating and navigating trees of data.
|
2024-03-19 17:18:43 +00:00
|
|
|
- Support for custom string memory management functions to implement string
|
|
|
|
pools and other schemes for reducing memory usage.
|
2017-03-22 19:23:27 +00:00
|
|
|
|
|
|
|
Mini-XML doesn't do validation or other types of processing on the data
|
|
|
|
based upon schema files or other sources of definition information.
|
|
|
|
|
|
|
|
|
2019-07-08 18:19:09 +00:00
|
|
|
Building Mini-XML
|
|
|
|
-----------------
|
2017-03-22 19:23:27 +00:00
|
|
|
|
|
|
|
Mini-XML comes with an autoconf-based configure script; just type the
|
|
|
|
following command to get things going:
|
|
|
|
|
|
|
|
./configure
|
|
|
|
|
|
|
|
The default install prefix is `/usr/local`, which can be overridden using the
|
|
|
|
`--prefix` option:
|
|
|
|
|
|
|
|
./configure --prefix=/foo
|
|
|
|
|
|
|
|
Other configure options can be found using the `--help` option:
|
|
|
|
|
|
|
|
./configure --help
|
|
|
|
|
|
|
|
Once you have configured the software, type `make` to do the build and run
|
|
|
|
the test program to verify that things are working, as follows:
|
|
|
|
|
|
|
|
make
|
|
|
|
|
|
|
|
If you are using Mini-XML under Microsoft Windows with Visual C++, use the
|
|
|
|
included project files in the `vcnet` subdirectory to build the library
|
|
|
|
instead. Note: The static library on Windows is NOT thread-safe.
|
|
|
|
|
|
|
|
|
2024-02-27 20:04:27 +00:00
|
|
|
Installing Mini-XML
|
|
|
|
-------------------
|
2017-03-22 19:23:27 +00:00
|
|
|
|
|
|
|
The `install` target will install Mini-XML in the lib and include
|
|
|
|
directories:
|
|
|
|
|
2024-02-27 20:04:27 +00:00
|
|
|
sudo make install
|
2017-03-22 19:23:27 +00:00
|
|
|
|
|
|
|
Once you have installed it, use the `-lmxml` option to link your application
|
|
|
|
against it.
|
|
|
|
|
|
|
|
|
2019-07-08 18:19:09 +00:00
|
|
|
Documentation
|
|
|
|
-------------
|
2017-03-22 19:23:27 +00:00
|
|
|
|
|
|
|
The documentation is available in the `doc` subdirectory in the files
|
2019-03-02 02:56:03 +00:00
|
|
|
`mxml.html` (HTML) and `mxml.epub` (EPUB). You can also look at the
|
|
|
|
`testmxml.c` source file for examples of using Mini-XML.
|
2017-03-22 19:23:27 +00:00
|
|
|
|
|
|
|
Mini-XML provides a single header file which you include:
|
|
|
|
|
|
|
|
#include <mxml.h>
|
|
|
|
|
2024-03-20 15:32:06 +00:00
|
|
|
Nodes (elements, comments, declarations, integers, opaque strings, processing
|
|
|
|
instructions, real numbers, and text strings) are represented by `mxml_node_t`
|
|
|
|
pointers. New nodes can be created using the mxmlNewXxx functions. The top
|
|
|
|
node must be the `<?xml ...?>` processing instruction.
|
2017-03-22 19:23:27 +00:00
|
|
|
|
2024-03-17 02:31:17 +00:00
|
|
|
You load an XML file using the mxmlLoadFilename function:
|
2017-03-22 19:23:27 +00:00
|
|
|
|
|
|
|
mxml_node_t *tree;
|
|
|
|
|
2024-03-20 15:32:06 +00:00
|
|
|
tree = mxmlLoadFilename(/*top*/NULL, /*options*/NULL,
|
|
|
|
"example.xml");
|
2017-03-22 19:23:27 +00:00
|
|
|
|
2024-03-17 02:31:17 +00:00
|
|
|
Similarly, you save an XML file using the mxmlSaveFilename function:
|
2017-03-22 19:23:27 +00:00
|
|
|
|
|
|
|
mxml_node_t *tree;
|
|
|
|
|
2024-03-20 15:32:06 +00:00
|
|
|
mxmlSaveFilename(tree, /*options*/NULL,
|
|
|
|
"filename.xml");
|
2017-03-22 19:23:27 +00:00
|
|
|
|
2024-03-17 02:31:17 +00:00
|
|
|
There are variations of these functions for loading from or saving to file
|
|
|
|
descriptors, `FILE` pointers, strings, and IO callbacks.
|
2017-03-22 19:23:27 +00:00
|
|
|
|
2024-03-17 02:31:17 +00:00
|
|
|
You can find a named element/node using the mxmlFindElement function:
|
2017-03-22 19:23:27 +00:00
|
|
|
|
|
|
|
mxml_node_t *node = mxmlFindElement(tree, tree, "name", "attr",
|
2024-03-20 15:32:06 +00:00
|
|
|
"value", MXML_DESCEND_ALL);
|
2017-03-22 19:23:27 +00:00
|
|
|
|
|
|
|
The `name`, `attr`, and `value` arguments can be passed as `NULL` to act as
|
|
|
|
wildcards, e.g.:
|
|
|
|
|
|
|
|
/* Find the first "a" element */
|
2024-03-20 15:32:06 +00:00
|
|
|
node = mxmlFindElement(tree, tree, "a", NULL, NULL, MXML_DESCEND_ALL);
|
2017-03-22 19:23:27 +00:00
|
|
|
|
|
|
|
/* Find the first "a" element with "href" attribute */
|
2024-03-20 15:32:06 +00:00
|
|
|
node = mxmlFindElement(tree, tree, "a", "href", NULL, MXML_DESCEND_ALL);
|
2017-03-22 19:23:27 +00:00
|
|
|
|
|
|
|
/* Find the first "a" element with "href" to a URL */
|
|
|
|
node = mxmlFindElement(tree, tree, "a", "href",
|
2024-03-20 15:32:06 +00:00
|
|
|
"https://www.msweet.org/mxml", MXML_DESCEND_ALL);
|
2017-03-22 19:23:27 +00:00
|
|
|
|
|
|
|
/* Find the first element with a "src" attribute*/
|
2024-03-20 15:32:06 +00:00
|
|
|
node = mxmlFindElement(tree, tree, NULL, "src", NULL, MXML_DESCEND_ALL);
|
2017-03-22 19:23:27 +00:00
|
|
|
|
|
|
|
/* Find the first element with a "src" = "foo.jpg" */
|
|
|
|
node = mxmlFindElement(tree, tree, NULL, "src", "foo.jpg",
|
2024-03-20 15:32:06 +00:00
|
|
|
MXML_DESCEND_ALL);
|
2017-03-22 19:23:27 +00:00
|
|
|
|
|
|
|
You can also iterate with the same function:
|
|
|
|
|
|
|
|
mxml_node_t *node;
|
|
|
|
|
|
|
|
for (node = mxmlFindElement(tree, tree, "name", NULL, NULL,
|
2024-03-20 15:32:06 +00:00
|
|
|
MXML_DESCEND_ALL);
|
2017-03-22 19:23:27 +00:00
|
|
|
node != NULL;
|
|
|
|
node = mxmlFindElement(node, tree, "name", NULL, NULL,
|
2024-03-20 15:32:06 +00:00
|
|
|
MXML_DESCEND_ALL))
|
2017-03-22 19:23:27 +00:00
|
|
|
{
|
|
|
|
... do something ...
|
|
|
|
}
|
|
|
|
|
2024-03-17 02:31:17 +00:00
|
|
|
The mxmlFindPath function finds the (first) value node under a specific
|
2017-03-22 19:23:27 +00:00
|
|
|
element using an XPath:
|
|
|
|
|
|
|
|
mxml_node_t *value = mxmlFindPath(tree, "path/to/*/foo/bar");
|
|
|
|
|
2024-03-17 02:31:17 +00:00
|
|
|
The mxmlGetInteger, mxmlGetOpaque, mxmlGetReal, and mxmlGetText functions
|
|
|
|
retrieve the corresponding value from a node:
|
2017-03-22 19:23:27 +00:00
|
|
|
|
|
|
|
mxml_node_t *node;
|
|
|
|
|
|
|
|
int intvalue = mxmlGetInteger(node);
|
|
|
|
|
|
|
|
const char *opaquevalue = mxmlGetOpaque(node);
|
|
|
|
|
|
|
|
double realvalue = mxmlGetReal(node);
|
|
|
|
|
2024-03-20 15:32:06 +00:00
|
|
|
bool whitespacevalue;
|
2017-03-22 19:23:27 +00:00
|
|
|
const char *textvalue = mxmlGetText(node, &whitespacevalue);
|
|
|
|
|
2024-03-17 02:31:17 +00:00
|
|
|
Finally, 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:
|
2017-03-22 19:23:27 +00:00
|
|
|
|
|
|
|
mxmlDelete(tree);
|
|
|
|
|
|
|
|
|
2019-07-08 18:19:09 +00:00
|
|
|
Getting Help And Reporting Problems
|
|
|
|
-----------------------------------
|
2017-03-22 19:23:27 +00:00
|
|
|
|
2019-03-02 02:56:03 +00:00
|
|
|
The [Mini-XML project page](https://www.msweet.org/mxml) provides access to the
|
|
|
|
current version of this software, documentation, and Github issue tracking page.
|
2017-03-22 19:23:27 +00:00
|
|
|
|
|
|
|
|
2019-07-08 18:19:09 +00:00
|
|
|
Legal Stuff
|
|
|
|
-----------
|
2017-03-22 19:23:27 +00:00
|
|
|
|
2024-02-27 20:04:27 +00:00
|
|
|
Copyright © 2003-2024 by Michael R Sweet
|
2019-01-05 01:44:51 +00:00
|
|
|
|
|
|
|
The Mini-XML library is licensed under the Apache License Version 2.0 with an
|
2020-08-18 13:13:49 +00:00
|
|
|
*optional* exception to allow linking against GPL2/LGPL2-only software. See the
|
|
|
|
files "LICENSE" and "NOTICE" for more information.
|
|
|
|
|
|
|
|
> Note: The exception listed in the NOTICE file only applies when linking
|
|
|
|
> against GPL2/LGPL2-only software. Some Apache License purists have objected
|
2024-03-17 02:31:17 +00:00
|
|
|
> to linking Apache Licensed code against Mini-XML with these exceptions on the
|
2020-08-18 13:13:49 +00:00
|
|
|
> grounds that it makes Mini-XML somehow incompatible with the Apache License.
|
|
|
|
> For that reason, people wishing to retain their Apache License purity may
|
|
|
|
> omit the exception from their copy of Mini-XML.
|
2024-03-17 12:13:44 +00:00
|
|
|
>
|
2020-08-18 13:13:49 +00:00
|
|
|
> Note 2: IANAL, but I am beginning to dislike them!
|