From e19d38b5a75c1048e0f2de353c169dfe36233805 Mon Sep 17 00:00:00 2001 From: Michael R Sweet Date: Mon, 2 Jul 2018 20:58:30 -0400 Subject: [PATCH] Update documentation for mxmldoc changes and use MXML_OPAQUE_CALLBACK for example (Issue #190) --- README.md | 4 +- doc/advanced.html | 612 ++++++++++---------- doc/basics.html | 302 +++++----- doc/install.html | 41 -- doc/mxml.html | 1382 ++++++++++++++++++++++---------------------- doc/mxml.man | 24 + doc/mxml.pdf | Bin 564636 -> 511803 bytes doc/mxmldoc.html | 106 ++-- doc/reference.html | 32 +- 9 files changed, 1240 insertions(+), 1263 deletions(-) diff --git a/README.md b/README.md index ec1cf8a..9f18239 100644 --- a/README.md +++ b/README.md @@ -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); diff --git a/doc/advanced.html b/doc/advanced.html index 0456386..a68d210 100644 --- a/doc/advanced.html +++ b/doc/advanced.html @@ -51,41 +51,41 @@ type to return.

child nodes:

-    mxml_type_t
-    type_cb(mxml_node_t *node)
-    {
-      const char *type;
-
-     /*
-      * You can lookup attributes and/or use the
-      * element name, hierarchy, etc...
-      */
-
-      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);
-    }
+mxml_type_t
+type_cb(mxml_node_t *node)
+{
+  const char *type;
+
+ /*
+  * You can lookup attributes and/or use the
+  * element name, hierarchy, etc...
+  */
+
+  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);
+}
 

To use this callback function, simply use the name when you call any of the load functions:

-    FILE *fp;
-    mxml_node_t *tree;
+FILE *fp;
+mxml_node_t *tree;
 
-    fp = fopen("filename.xml", "r");
-    tree = mxmlLoadFile(NULL, fp, type_cb);
-    fclose(fp);
+fp = fopen("filename.xml", "r");
+tree = mxmlLoadFile(NULL, fp, type_cb);
+fclose(fp);
 
@@ -112,85 +112,85 @@ whitespace to XHTML output to make it more readable in a standard text editor:

-    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...
-      */
-
-      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 (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...
-	*/
-
-	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);
-    }
+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...
+  */
+
+  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 (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...
+    */
+
+    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);
+}
 

To use this callback function, simply use the name when you call any of the save functions:

-    FILE *fp;
-    mxml_node_t *tree;
+FILE *fp;
+mxml_node_t *tree;
 
-    fp = fopen("filename.xml", "w");
-    mxmlSaveFile(tree, fp, whitespace_cb);
-    fclose(fp);
+fp = fopen("filename.xml", "w");
+mxmlSaveFile(tree, fp, whitespace_cb);
+fclose(fp);
 
@@ -212,97 +212,97 @@ date/time type whose value is encoded as "yyyy-mm-ddThh:mm:ssZ" following:

-    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;
-
-     /*
-      * Allocate data structure...
-      */
-
-      dt = calloc(1, sizeof(iso_date_time_t));
-
-     /*
-      * 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...
-        */
-
-        free(dt);
-
-        return (-1);
-      }
-
-     /*
-      * 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...
-        */
-
-        free(dt);
-
-        return (-1);
-      }
-
-     /*
-      * 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;
-
-      dt->unix = gmtime(&tmdata);
-
-     /*
-      * Assign custom node data and destroy
-      * function pointers...
-      */
-
-      mxmlSetCustom(node, data, destroy);
-
-     /*
-      * Return with no errors...
-      */
-
-      return (0);
-    }
+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;
+
+ /*
+  * Allocate data structure...
+  */
+
+  dt = calloc(1, sizeof(iso_date_time_t));
+
+ /*
+  * 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...
+    */
+
+    free(dt);
+
+    return (-1);
+  }
+
+ /*
+  * 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...
+    */
+
+    free(dt);
+
+    return (-1);
+  }
+
+ /*
+  * 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;
+
+  dt->unix = gmtime(&tmdata);
+
+ /*
+  * Assign custom node data and destroy
+  * function pointers...
+  */
+
+  mxmlSetCustom(node, data, destroy);
+
+ /*
+  * Return with no errors...
+  */
+
+  return (0);
+}
 

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:

-    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));
+}
 

You register the callback functions using the mxmlSetCustomHandlers() function:

-    mxmlSetCustomHandlers(load_custom,
-                          save_custom);
+mxmlSetCustomHandlers(load_custom,
+                      save_custom);
 
@@ -366,9 +366,9 @@ example, use the following function call to change a text node to contain the text "new" with leading whitespace:

-    mxml_node_t *node;
+mxml_node_t *node;
 
-    mxmlSetText(node, 1, "new");
+mxmlSetText(node, 1, "new");
 
@@ -382,10 +382,10 @@ function call to create a new text node containing a constructed filename:

-    mxml_node_t *node;
+mxml_node_t *node;
 
-    node = mxmlNewTextf(node, 1, "%s/%s",
-                        path, filename);
+node = mxmlNewTextf(node, 1, "%s/%s",
+                    path, filename);
 
@@ -408,11 +408,11 @@ structures. The mxmlIndexNew() function creates a new index:

-    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");
 

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:

-    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
+}
 

The mxmlIndexFind() @@ -457,16 +457,16 @@ attribute value in the index. It can be used to find all matching elements in an index, as follows:

-    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
+}
 

The second and third arguments represent the element name and @@ -480,7 +480,7 @@ is equivalent to calling mxmlIndexEnum.

function:

-    mxmlIndexDelete(ind);
+mxmlIndexDelete(ind);
 

SAX (Stream) Loading of Documents

@@ -502,13 +502,13 @@ process each node as it is read.

a user data pointer you supply:

-    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 ...
+}
 

The event will be one of the following:

@@ -537,14 +537,14 @@ the following SAX callback will retain all nodes, effectively simulating a normal in-memory load:

-    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);
+}
 

More typically the SAX callback will only retain a small portion @@ -555,46 +555,46 @@ directives like <?xml ... ?> and <!DOCTYPE ... >

-    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...
-        */
-
-        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);
-        }
-      }
+     /*
+      * If the parent was retained, then retain
+      * this data node as well.
+      */
+
+      mxmlRetain(node);
     }
+  }
+}
 

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:

-    mxml_node_t *doc, *title, *body, *heading;
-
-    doc = mxmlSAXLoadFd(NULL, 0,
-                        MXML_TEXT_CALLBACK,
-                        sax_cb, NULL);
-
-    title = mxmlFindElement(doc, doc, "title",
-                            NULL, NULL,
-                            MXML_DESCEND);
-
-    if (title)
-      print_children(title);
-
-    body = mxmlFindElement(doc, doc, "body",
-                           NULL, NULL,
-                           MXML_DESCEND);
-
-    if (body)
-    {
-      for (heading = mxmlGetFirstChild(body);
-           heading;
-           heading = mxmlGetNextSibling(heading))
-        print_children(heading);
-    }
+mxml_node_t *doc, *title, *body, *heading;
+
+doc = mxmlSAXLoadFd(NULL, 0,
+                    MXML_TEXT_CALLBACK,
+                    sax_cb, NULL);
+
+title = mxmlFindElement(doc, doc, "title",
+                        NULL, NULL,
+                        MXML_DESCEND);
+
+if (title)
+  print_children(title);
+
+body = mxmlFindElement(doc, doc, "body",
+                       NULL, NULL,
+                       MXML_DESCEND);
+
+if (body)
+{
+  for (heading = mxmlGetFirstChild(body);
+       heading;
+       heading = mxmlGetNextSibling(heading))
+    print_children(heading);
+}
 
diff --git a/doc/basics.html b/doc/basics.html index 1b705fc..056b4f4 100644 --- a/doc/basics.html +++ b/doc/basics.html @@ -26,14 +26,14 @@ functionality:

Mini-XML provides a single header file which you include:

-    #include <mxml.h>
+#include <mxml.h>
 

The Mini-XML library is included with your program using the -lmxml option:

-    gcc -o myprogram myprogram.c -lmxml ENTER
+gcc -o myprogram myprogram.c -lmxml ENTER
 

If you have the pkg-config(1) software installed, @@ -41,8 +41,8 @@ you can use it to determine the proper compiler and linker options for your installation:

-    pkg-config --cflags mxml ENTER
-    pkg-config --libs mxml ENTER
+pkg-config --cflags mxml ENTER
+pkg-config --libs mxml ENTER
 

Nodes

@@ -55,35 +55,35 @@ 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"?>
-    <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>
 

the node tree for the file would look like the following in memory:

-    ?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
 

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.

mxmlGetInteger function retrieves the integer value for a node.

-

Opaque Nodes

+

Opaque String Nodes

-

Opaque (MXML_OPAQUE) nodes are created using the +

Opaque string (MXML_OPAQUE) nodes are created using the mxmlNewOpaque function. The mxmlGetOpaque function retrieves the opaque string pointer for a node. Opaque nodes are like string nodes but preserve all whitespace between nodes.

-

Text Nodes

+

Text String Nodes

-

Text (MXML_TEXT) nodes are created using the +

Text string (MXML_TEXT) nodes are created using the mxmlNewText and mxmlNewTextf 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 mxmlGetText function retrieves the -text string pointer and whitespace value for a node.

+string pointer and whitespace value for a node.

Processing Instruction Nodes

@@ -216,35 +216,35 @@ 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> */
-    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");
+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");
 
@@ -252,7 +252,7 @@ create the XML document described in the previous section:

mxmlNewXML function:

-    xml = mxmlNewXML("1.0");
+xml = mxmlNewXML("1.0");
 

We then create the <data> node used for this document using @@ -261,7 +261,7 @@ argument specifies the parent node (xml) while the second specifies the element name (data):

-    data = mxmlNewElement(xml, "data");
+data = mxmlNewElement(xml, "data");
 

Each <node>...</node> 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:

-    node = mxmlNewElement(data, "node");
-    mxmlNewText(node, 0, "val1");
+node = mxmlNewElement(data, "node");
+mxmlNewText(node, 0, "val1");
 

The resulting in-memory XML document can then be saved or processed just like @@ -287,13 +287,13 @@ href='#mxmlLoadFile'>mxmlLoadFile function:

-    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);
 

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: MXML_INTEGER, MXML_OPAQUE, MXML_REAL, or MXML_TEXT. Load callbacks are described in detail in Chapter 3. The example code uses -the MXML_TEXT_CALLBACK constant which specifies that all -data nodes in the document contain whitespace-separated text -values. Other standard callbacks include +the MXML_OPAQUE_CALLBACK constant which specifies that all +data nodes in the document contain opaque string values with whitespace +preserved. Other standard callbacks include MXML_IGNORE_CALLBACK, MXML_INTEGER_CALLBACK, -MXML_OPAQUE_CALLBACK, and -MXML_REAL_CALLBACK.

+MXML_REAL_CALLBACK, and +MXML_TEXT_CALLBACK.

The mxmlLoadString function loads XML node trees from a string:

-    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);
 

The first and third arguments are the same as used for @@ -347,12 +347,12 @@ is NULL.

href='#mxmlSaveFile'>mxmlSaveFile function:

-    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);
 

The first argument is the XML node tree to save. It should @@ -376,16 +376,16 @@ and mxmlSaveString functions save XML node trees to strings:

-    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);
 

The first and last arguments are the same as used for @@ -405,11 +405,11 @@ href='#mxmlSetWrapMargin'>mxmlSetWrapMargin function overrides the default wrap margin:

-    /* Set the margin to 132 columns */
-    mxmlSetWrapMargin(132);
+/* Set the margin to 132 columns */
+mxmlSetWrapMargin(132);
 
-    /* Disable wrapping */
-    mxmlSetWrapMargin(0);
+/* Disable wrapping */
+mxmlSetWrapMargin(0);
 

Memory Management

@@ -420,7 +420,7 @@ free the memory that is used for a particular node or the entire tree:

-    mxmlDelete(tree);
+mxmlDelete(tree);
 

You can also use reference counting to manage memory usage. The @@ -442,13 +442,13 @@ href='#mxmlWalkNext'>mxmlWalkNextfunctions can be used to iterate through the XML node tree:

-    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);
 

In addition, you can find a named element/node using the mxmlFindElement function:

-    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);
 

The name, attr, and value @@ -469,62 +469,62 @@ e.g.:

-    /* 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);
 
-    /* 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);
 
-    /* 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);
 
-    /* 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);
 
-    /* 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);
 

You can also iterate with the same function:

-    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 ...
-    }
+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 ...
+}
 
@@ -577,9 +577,9 @@ three constants:

href='#mxmlFindValue'>mxmlFindPath, for example:
-    mxml_node_t *value;
+mxml_node_t *value;
 
-    value = mxmlFindPath(tree, "path/to/*/foo/bar");
+value = mxmlFindPath(tree, "path/to/*/foo/bar");
 

The second argument is a "path" to the parent node. Each component of the diff --git a/doc/install.html b/doc/install.html index 5f7c876..401f0ae 100644 --- a/doc/install.html +++ b/doc/install.html @@ -73,46 +73,5 @@ directories:

-

Creating Mini-XML Packages

- -

Mini-XML includes two files that can be used to create binary -packages. The first file is mxml.spec which is used -by the rpmbuild(8) software to create Red Hat Package -Manager ("RPM") packages which are commonly used on Linux. Since -rpmbuild wants to compile the software on its own, you -can provide it with the Mini-XML tar file to build the -package:

- -
-    rpmbuild -ta mxml-version.tar.gz ENTER
-
- -

The second file is mxml.list which is used by the -epm(1) program to create software packages in a variety -of formats. The epm program is available from the -following URL:

- -
-    http://www.epmhome.org/
-
- -

Use the make command with the epm target -to create portable and native packages for your system:

- -
-    make epm ENTER
-
- -

The packages are stored in a subdirectory named -dist 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 -mxml.install script to install the software.

- -

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.

- diff --git a/doc/mxml.html b/doc/mxml.html index ae5f3ad..44c1d00 100644 --- a/doc/mxml.html +++ b/doc/mxml.html @@ -1,9 +1,9 @@ -Mini-XML Programmers Manual, Version 2.11 +Mini-XML Programmers Manual, Version 2.12 - +