📄 mxml.html
字号:
Library General Public License for more details.</P><HR NOSHADE><H1 align="right"><A name="INSTALL"><IMG align="right" alt="1" height="100"hspace="10" src="1.gif" width="100"></A>Building, Installing, and Packaging Mini-XML</H1><P>This chapter describes how to build, install, and package Mini-XML on your system from the source archive. You will need an ANSI/ISO-C compatible compiler to build Mini-XML - GCC works, as do most vendors' C compilers. If you are building Mini-XML on Windows, we recommend using the Visual C++ environment with the supplied solution file. For other operating systems, you'll need a POSIX-compatible shell and <TT>make</TT> program in addition to the C compiler.</P><H2><A NAME="2_1">Compiling Mini-XML</A></H2><P>Mini-XML comes with both an autoconf-based configure script and a Visual C++ solution that can be used to compile the library and associated tools.</P><H3><A NAME="2_1_1">Compiling with Visual C++</A></H3><P>Open the<VAR> mxml.sln</VAR> solution in the<VAR> vcnet</VAR> folder. Choose the desired build configuration, "Debug" (the default) or "Release", and then choose<VAR> Build Solution</VAR> from the<VAR> Build</VAR> menu.</P><H3><A NAME="2_1_2">Compiling with Command-Line Tools</A></H3><P>Type the following command to configure the Mini-XML source code for your system:</P><PRE> <KBD>./configure ENTER</KBD></PRE><P>The default install prefix is<VAR> /usr/local</VAR>, which can be overridden using the <KBD>--prefix</KBD> option:</P><PRE> <KBD>./configure --prefix=/foo ENTER</KBD></PRE><P>Other configure options can be found using the <KBD>--help</KBD> option:</P><PRE> <KBD>./configure --help ENTER</KBD></PRE><P>Once you have configured the software, use the <TT>make(1)</TT> program to do the build and run the test program to verify that things are working, as follows:</P><PRE> <KBD>make ENTER</KBD></PRE><H2><A NAME="2_2">Installing Mini-XML</A></H2><P>If you are using Visual C++, copy the<VAR> mxml.lib</VAR> and and<VAR> mxml.h</VAR> files to the Visual C++<VAR> lib</VAR> and<VAR> include<VAR> directories, respectively.</VAR></VAR></P><P>Otherwise, use the <TT>make</TT> command with the <KBD>install</KBD> target to install Mini-XML in the configured directories:</P><PRE> <KBD>make install ENTER</KBD></PRE><H2><A NAME="2_3">Creating Mini-XML Packages</A></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.easysw.com/epm/">http://www.easysw.com/epm/</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><HR NOSHADE><H1 align="right"><A name="BASICS"><IMG align="right" alt="2" height="100"hspace="10" src="2.gif" width="100"></A>Getting Started with Mini-XML</H1><P>This chapter describes how to write programs that use Mini-XML to access data in an XML file. Mini-XML provides the following functionality:</P><UL><LI>Functions for creating and managing XML documents in memory.</LI><LI>Reading of UTF-8 and UTF-16 encoded XML files and strings.</LI><LI>Writing of UTF-8 encoded XML files and strings.</LI><LI>Support for arbitrary element names, attributes, and attribute values with no preset limits, just available memory.</LI><LI>Support for integer, real, opaque ("cdata"), and text data types in "leaf" nodes.</LI><LI>"Find", "index", and "walk" functions for easily accessing data in an XML document.</LI></UL><P>Mini-XML doesn't do validation or other types of processing on the data based upon schema files or other sources of definition information, nor does it support character entities other than those required by the XML specification.</P><H2><A NAME="3_1">The Basics</A></H2><P>Mini-XML provides a single header file which you include:</P><PRE> #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></PRE><P>If you have the <TT>pkg-config(1)</TT> software installed, 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></PRE><H2><A NAME="3_2">Nodes</A></H2><P>Every piece of information in an XML file (elements, text, numbers) is stored in memory in "nodes". Nodes are defined by the <A href="#mxml_node_t"><TT>mxml_node_t</TT></A> structure. The <A href="#mxml_type_t"><TT>type</TT></A> member defines the node type (element, integer, opaque, real, or text) which determines which value you want to look at in the <A href="#mxml_value_t"><TT>value</TT></A> union.</P><!-- NEED 10 --><CENTER><TABLE border="1" cellpadding="5" cellspacing="0" summary="Mini-XML Node Value Members"width="80%"><CAPTION align="bottom"><I> Table 2-1: Mini-XML Node Value Members</I></CAPTION><TR bgcolor="#cccccc"><TH>Value</TH><TH>Type</TH><TH>Node member</TH></TR><TR><TD>Custom</TD><TD><TT>void *</TT></TD><TD><TT>node->value.custom.data</TT></TD></TR><TR><TD>Element</TD><TD><TT>char *</TT></TD><TD><TT>node->value.element.name</TT></TD></TR><TR><TD>Integer</TD><TD><TT>int</TT></TD><TD><TT>node->value.integer</TT></TD></TR><TR><TD>Opaque (string)</TD><TD><TT>char *</TT></TD><TD><TT>node->value.opaque</TT></TD></TR><TR><TD>Real</TD><TD><TT>double</TT></TD><TD><TT>node->value.real</TT></TD></TR><TR><TD>Text</TD><TD><TT>char *</TT></TD><TD><TT>node->value.text.string</TT></TD></TR></TABLE></CENTER><P>Each node also has a <TT>user_data</TT> member which allows you to associate application-specific data with each node as needed.</P><P>New nodes are 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>, <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 the <TT><?xml version="1.0"?></TT> node created by <TT>mxmlNewXML()</TT>.</P><P>Nodes have pointers to the node above (<TT>parent</TT>), below (<TT>child</TT>), left (<TT>prev</TT>), and right (<TT>next</TT>) of the current node. If you have an XML file like the following:</P><PRE> <?xml version="1.0"?> <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 | 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 next node and "|" is a pointer to the first child node.</P><P>Once you are done with the XML data, use the <A href="#mxmlDelete"><TT>mxmlDelete</TT></A> function to recursively free the memory that is used for a particular node or the entire tree:</P><PRE> mxmlDelete(tree);</PRE><!-- NEW PAGE --><H2><A NAME="3_3">Creating XML Documents</A></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><A NAME="3_4">Loading XML</A></H2><P>You load an XML file using the <A href="#mxmlLoadFile"><TT>mxmlLoadFile</TT></A> function:</P><PRE> FILE *fp; mxml_node_t *tree; fp = fopen("filename.xml", "r"); tree = mxmlLoadFile(NULL, fp, MXML_TEXT_CALLBACK); fclose(fp);</PRE><P>The first argument specifies an existing XML parent node, if any. Normally you will pass <TT>NULL</TT> for this argument unless you are combining multiple XML sources. The XML file must contain a complete XML document including the <TT>?xml</TT> element if the parent node is <TT>NULL</TT>.</P><P>The second argument specifies the stdio file to read from, as 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_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><!-- NEED 10 --><PRE> char buffer[8192]; mxml_node_t *tree; ... tree = mxmlLoadString(NULL, buffer, MXML_TEXT_CALLBACK);</PRE><P>The first and third arguments are the same as used for <TT>mxmlLoadFile()</TT>. The second argument specifies the string or character buffer to load and must be a complete XML document including the <TT>?xml</TT> element if the parent node is <TT>NULL</TT>.</P><!-- NEW PAGE --><H2><A NAME="3_5">Saving XML</A></H2><P>You save an XML file using the <A href="#mxmlSaveFile"><TT>mxmlSaveFile</TT></A> function:</P><PRE> FILE *fp; mxml_node_t *tree; 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 normally be a pointer to the top-level <TT>?xml</TT> node in your XML document.</P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -