1
0
Fork 0
flightgear/utils/xmlgrep
ehofman b4ab5242ec Change the low level internals of the xml library to reflect the following;
* rewrite the code to always recursively walk the node tree when searching
    for a particular node. this is required for cases where a node with a
    particular name is located deeper in a node with the same name;
    for example -r /configuration/device/reference/device would fail in the
    previous verion
  * rename xmlGetElement to xmlGetNodeNum and add the possibility to request
    the nth node with this name
  * rename xmlGetNumElements to xmlGetNumNodes

The drawback is that this is approach slows down processing the files a bit,
but at least it can now find any xml node in any xml file.
Also, no more function changes are planned from now on.
2008-07-19 12:18:05 +00:00
..
.cvsignore Add an XML grep utility. It's far from complete but it allowed me to test the animation files for the precense of the 'offset' element in the translation animation sections. 2005-09-24 12:31:41 +00:00
ChangeLog Change the low level internals of the xml library to reflect the following; 2008-07-19 12:18:05 +00:00
Makefile.am Erik HOFMAN: faster and better xmlgrep implementation 2008-06-29 13:08:24 +00:00
README * fix a problem caused by removing the last unnecessary alloc 2008-07-01 12:15:46 +00:00
xml.c Change the low level internals of the xml library to reflect the following; 2008-07-19 12:18:05 +00:00
xml.h Change the low level internals of the xml library to reflect the following; 2008-07-19 12:18:05 +00:00
xmlgrep.c Change the low level internals of the xml library to reflect the following; 2008-07-19 12:18:05 +00:00

This library is specially designed for reading xml configuration files and
to be as low on memory management as possible. Modifying or writing xml files
is not planned for the future. In most situations being able to gather data
by reading an xml file is more than enough and the read-only decision
provides a number of advantages over a one-size fits all approach. For isntance
the memory footprint can be kept low and the library can be kept simple.

To achieve these goals the mmap function is used to map the configuration file
to a memory region. The only places where memory is allocated is when creating
a new XML-id, when requesting a string from a node or when a request is made to
copy a node.

Using this library should be pretty simple for most tasks; just open a file,
read every parameter one by one and close the id again.
{
   void *xid;

   xid = xmlOpen("/tmp/file.xml");
   xpos = xmlGetNodeDouble(xid, "/configuration/x-pos");
   ypos = xmlGetNodeDouble(xid, "/configuration/y-pos");
   zpos = xmlGetNodeDouble(xid, "/configuration/z-pos");
   xmlClose(xid);
}

While it is certainly possible to access every node directly by calling the
xmlGetNode(Int/Double/String) functions, when more than one node need to be
gathered from a parent node it is advised to get the id of the parent node
and work from there. This is because the XML-id holds the boundaries of the
(parent)node which limits the searching area resulting in improved searching
speed.
{
   void *xnid;
   char *s;

   xnid = xmlGetNode(id, "/configuration/setup/");
   version = xmlGetNodeDouble(xnid, "version");
   s = xmlGetNodeString(xnid, "author");
   if (s) author = s;
   free(s);
   free(xnid);
}

Overview of the available functions:
 ----------------------------------------------------------------------------- 
#
# Functions to Open and Close the XML file
# e.g.
#   id = xmlOpen("/tmp/file.xml");
#   xmlClose(id);
#
void *xmlOpen(const char *);
void xmlClose(const void *);

#
# Get the Id of a node at the specified path
# e.g.
#    xnid = xmlGetNode(id, "/path/to/specified/node");
#
void *xmlGetNode(const void *, const char *);
void *xmlCopyNode(void *, const char *);

#
# Functions to walk the node tree and process them one by one.
# e.g.
#   xmid = xmlMarkId(id);
#   num = xmlGetNumElements(xmid);
#   for (i=0; i<num; i++) {
#      if (xmlGetNextElement(id, xmid, "element") != 0) {
#         if ((s = xmlGetString(xmid)) != 0) {
#            printf("%s\n", s);
#            free(s);
#         }
#      }
#   }
#   free(xmid);
#
void *xmlMarkId(void *);
unsigned int xmlGetNumElements(void *, const char *);
void *xmlGetNextElement(const void *, void *, const char *);

#
# These functions work on the current node.
# e.g.
#    xnid = xmlGetNode(id, "/path/to/last/node");
#    i = xmlGetInt(xnid);
# or
#    xnid = xmlGetNode(id, "/path/to/specified/node");
#    if (xmlCompareString(xnid, "value") == 0) printf("We have a match!\n");
#
long int xmlGetInt(void *);
double xmlGetDouble(void *);
char *xmlGetString(void *);
int xmlCompareString(const void *, const char *);

#
# These functions work on a specified node path
# e.g.
#    d = xmlGetNodeDouble(id, "/path/to/node");
# or
#    xnid = xmlGetNode(id, "/path/to");
#    i = xmlGetNodeInt(xnid, "node");
#
long int xmlGetNodeInt(void *, const char *);
double xmlGetNodeDouble(void *, const char *);
char *xmlGetNodeString(void *, const char *);
unsigned xmlCopyNodeString(void *, const char *, char *, const unsigned int);
int xmlCompareNodeString(const void *, const char *, const char *);