]> git.mxchange.org Git - flightgear.git/commitdiff
* Rename xmlGetNode functions to xmlNodeGet for better consistancy
authorehofman <ehofman>
Thu, 16 Apr 2009 19:03:22 +0000 (19:03 +0000)
committerTim Moore <timoore@redhat.com>
Fri, 1 May 2009 22:44:20 +0000 (00:44 +0200)
  * likewise for xmlCopyNode en xmlCompareNode
  * add xmlAttributeGetDouble, xmlAttributeGetInt, xmlAttributeGetString
    xmlAttributeCopyString and xmlAttributeCompareString functions
  * fix some small bugs and problems along the way
  * add support for filtering on attribute value in xmlgrep

utils/xmlgrep/ChangeLog
utils/xmlgrep/README
utils/xmlgrep/xml.c
utils/xmlgrep/xml.h
utils/xmlgrep/xmlgrep.c

index 73b6864ecf4d428ff20ecb642af59f4491434e56..f4dd02d6a62eb76013a9022fd2aad8dff8d21177 100644 (file)
@@ -1,3 +1,11 @@
+16-04-2008
+  * Rename xmlGetNode functions to xmlNodeGet for better consistancy
+  * likewise for xmlCopyNode en xmlCompareNode
+  * add xmlAttributeGetDouble, xmlAttributeGetInt, xmlAttributeGetString
+    xmlAttributeCopyString and xmlAttributeCompareString functions
+  * fix some small bugs and problems along the way
+  * add support for filtering on attribute value in xmlgrep
+
 21-07-2008
   * change a number of function parameters to const where appropriate
   * fix a problem where the wrong node-name length was returned
@@ -16,7 +24,7 @@
     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 version
+    previous verion
   * rename xmlGetElement to xmlGetNodeNum and add the possibility to request
     the nth node with this name
   * rename xmlGetNumElements to xmlGetNumNodes
@@ -24,7 +32,7 @@
 06-07-2008
   * reorganize the code to be able to skip comment sections
   * depreciate __xmlFindNextElement and use __xmlGetNode instead
-  * xmlGetNextElement now returns char* instead of void* for future use
+  * xmlGetNextElement now returns char* instead of void* for furute use
   * add preliminary support for wildcards in the search path ('*' and '?')
 
 01-07-2008
index a23050bcca3eabf04a131d8471a69e99e36c62c8..74cb6afd9b0b60271aac478f9a0eb2a3fd79a0aa 100644 (file)
@@ -7,7 +7,7 @@ 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, when requesting the node
+a new XML-id, when requesting a string from a node, when requestiong the node
 name or when a request is made to copy a node into a new memory region.
 
 Using this library should be pretty simple for most tasks; just open a file,
@@ -16,14 +16,14 @@ 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");
+   xpos = xmlNodeGetDouble(xid, "/configuration/x-pos");
+   ypos = xmlNodeGetDouble(xid, "/configuration/y-pos");
+   zpos = xmlNodeGetDouble(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
+xmlNodeGet(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 since the XML-id holds the boundaries of the (parent)node
 which limits the searching area resulting in improved searching speed.
@@ -31,9 +31,9 @@ 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");
+   xnid = xmlNodeGet(id, "/configuration/setup/");
+   version = xmlNodeGetDouble(xnid, "version");
+   s = xmlNodeGetString(xnid, "author");
    if (s) author = s;
    free(s);
    free(xnid);
@@ -53,18 +53,18 @@ void xmlClose(const void *);
 #
 # Get the Id of a node at the specified path
 # e.g.
-#    xnid = xmlGetNode(id, "/path/to/specified/node");
+#    xnid = xmlNodeGet(id, "/path/to/specified/node");
 #
-void *xmlGetNode(const void *, const char *);
-void *xmlCopyNode(void *, const char *);
+void *xmlNodeGet(const void *, const char *);
+void *xmlNodeCopy(void *, const char *);
 
 #
 # Functions to walk the node tree and process them one by one.
 # e.g.
 #   xmid = xmlMarkId(id);
-#   num = xmlGetNumNodes(xmid);
+#   num = xmlNodeGetNum(xmid);
 #   for (i=0; i<num; i++) {
-#      if (xmlGetNodeNum(id, xmid, "element", i) != 0) {
+#      if (xmlNodeGetPos(id, xmid, "element", i) != 0) {
 #         if ((s = xmlGetString(xmid)) != 0) {
 #            printf("%s\n", s);
 #            free(s);
@@ -74,22 +74,22 @@ void *xmlCopyNode(void *, const char *);
 #   free(xmid);
 #
 void *xmlMarkId(void *);
-unsigned int xmlGetNumNodes(void *, const char *);
-void *xmlGetNodeNum(const void *, void *, const char *, int);
+unsigned int xmlNodeGetNum(void *, const char *);
+void *xmlNodeGetPos(const void *, void *, const char *, int);
 
 #
 # Get the name of the current node
 #
-char *xmlGetNodeName(void *);
-size_t xmlCopyNodeName(void *, const char *, size_t);
+char *xmlNodeGetName(void *);
+size_t xmlNodeCopyName(void *, const char *, size_t);
 
 #
 # These functions work on the current node.
 # e.g.
-#    xnid = xmlGetNode(id, "/path/to/last/node");
+#    xnid = xmlNodeGet(id, "/path/to/last/node");
 #    i = xmlGetInt(xnid);
 # or
-#    xnid = xmlGetNode(id, "/path/to/specified/node");
+#    xnid = xmlNodeGet(id, "/path/to/specified/node");
 #    if (xmlCompareString(xnid, "value") == 0) printf("We have a match!\n");
 #
 long int xmlGetInt(void *);
@@ -101,13 +101,29 @@ int xmlCompareString(const void *, const char *);
 #
 # These functions work on a specified node path
 # e.g.
-#    d = xmlGetNodeDouble(id, "/path/to/node");
+#    d = xmlNodeGetDouble(id, "/path/to/node");
 # or
-#    xnid = xmlGetNode(id, "/path/to");
-#    i = xmlGetNodeInt(xnid, "node");
+#    xnid = xmlNodeGet(id, "/path/to");
+#    i = xmlNodeGetInt(xnid, "node");
 #
-long int xmlGetNodeInt(void *, const char *);
-double xmlGetNodeDouble(void *, const char *);
-char *xmlGetNodeString(void *, const char *);
-size_t xmlCopyNodeString(void *, const char *, char *, const size_t);
-int xmlCompareNodeString(const void *, const char *, const char *);
+long int xmlNodeGetInt(void *, const char *);
+double xmlNodeGetDouble(void *, const char *);
+char *xmlNodeGetString(void *, const char *);
+size_t xmlNodeCopyString(void *, const char *, char *, const size_t);
+int xmlNodeCompareString(const void *, const char *, const char *);
+
+#
+# These functions work on a specified atribute
+# e.g.
+#    i = xmlAttributeGetInt(id, "n");
+#
+# or
+#    s = xmlNodeGetString(id, "type");
+#    if (s) printf("node is of type '%s'\n", s);
+#    free(s);
+#
+long int xmlAttributeGetInt(const void *, const char *);
+double xmlAttributeGetDouble(const void *, const char *);
+char *xmlAttributeGetString(const void *, const char *);
+size_t xmlAttributeCopyString(const void *, const char *, const char *, size_t);
+int xmlAttributeCompareString(const void *, const char *, const char *);
index e24899e8e6a48cad754b7826e8ce865d70267b82..2c2b962486b998e41ded91c8d3c0f237f2c2c880 100644 (file)
@@ -40,8 +40,8 @@ static SIMPLE_UNMMAP un;
 /*
  * map 'filename' and return a pointer to it.
  */
-void *simple_mmap(int, unsigned int, SIMPLE_UNMMAP *);
-void simple_unmmap(SIMPLE_UNMMAP *);
+static void *simple_mmap(int, size_t, SIMPLE_UNMMAP *);
+static void simple_unmmap(SIMPLE_UNMMAP *);
 
 #define mmap(a,b,c,d,e,f)      simple_mmap((e), (b), &un)
 #define munmap(a,b)            simple_unmmap(&un)
@@ -58,28 +58,28 @@ void simple_unmmap(SIMPLE_UNMMAP *);
 #include <ctype.h>
 #include <string.h>
 #include <strings.h>   /* strncasecmp */
+#ifndef NDEBUG
 #include <stdio.h>
-#include <stdlib.h>
+#endif
 
 
 struct _xml_id
 {
-    char *name;
-    char *start;
     size_t len;
+    char *start;
+    char *name;
     union {
+       size_t name_len;
        int fd;
-       size_t len;
     } node;
 };
 
-static char *__xmlCopyNode(const char *, size_t, const char *);
-static char *__xmlGetNodePath(const char *, size_t *, char **, size_t *);
-static char *__xmlGetNode(const char *, size_t *, char **, size_t *, size_t *);
-static char *__xmlSkipComment(const char *, size_t);
-static char *__xmlSkipInfo(const char *, size_t);
+static char *__xmlNodeCopy(const char *, size_t, const char *);
+static char *__xmlNodeGetPath(const char *, size_t *, char **, size_t *);
+static char *__xmlNodeGet(const char *, size_t *, char **, size_t *, size_t *);
+static char *__xmlCommentSkip(const char *, size_t);
+static char *__xmlInfoSkip(const char *, size_t);
 
-static void *__xml_memmem(const char *, size_t, const char *, size_t);
 static void *__xml_memncasecmp(const char *, size_t *, char **, size_t *);
 
 #define PRINT(a, b, c) { \
@@ -138,7 +138,7 @@ xmlClose(void *id)
 }
 
 void *
-xmlGetNode(const void *id, const char *path)
+xmlNodeGet(const void *id, const char *path)
 {
    struct _xml_id *xsid = 0;
 
@@ -151,7 +151,7 @@ xmlGetNode(const void *id, const char *path)
       node = (char *)path;
       len = xid->len;
       slen = strlen(path);
-      ptr = __xmlGetNodePath(xid->start, &len, &node, &slen);
+      ptr = __xmlNodeGetPath(xid->start, &len, &node, &slen);
       if (ptr)
       {
          xsid = malloc(sizeof(struct _xml_id));
@@ -159,7 +159,7 @@ xmlGetNode(const void *id, const char *path)
          {
              xsid->len = len;
              xsid->start = ptr;
-             xsid->node.len = slen;
+             xsid->node.name_len = slen;
              xsid->name = node;
          }
       }
@@ -169,7 +169,7 @@ xmlGetNode(const void *id, const char *path)
 }
 
 void *
-xmlCopyNode(const void *id, const char *path)
+xmlNodeCopy(const void *id, const char *path)
 {
     struct _xml_id *xsid = 0;
 
@@ -182,7 +182,7 @@ xmlCopyNode(const void *id, const char *path)
         node = (char *)path;
         len = xid->len;
         slen = strlen(path);
-        ptr = __xmlGetNodePath(xid->start, &len, &node, &slen);
+        ptr = __xmlNodeGetPath(xid->start, &len, &node, &slen);
         if (ptr)
         {
             xsid = malloc(sizeof(struct _xml_id) + len);
@@ -192,7 +192,7 @@ xmlCopyNode(const void *id, const char *path)
 
                 xsid->len = len;
                 xsid->start = p;
-                xsid->node.len = slen;
+                xsid->node.name_len = slen;
                 xsid->name = node;
 
                 memcpy(xsid->start, ptr, len);
@@ -204,13 +204,13 @@ xmlCopyNode(const void *id, const char *path)
 }
 
 char *
-xmlGetNodeName(const void *id)
+xmlNodeGetName(const void *id)
 {
     struct _xml_id *xid = (struct _xml_id *)id;
     size_t len;
     char *ret;
 
-    len = xid->node.len;
+    len = xid->node.name_len;
     ret = malloc(len+1);
     if (ret)
     {
@@ -222,7 +222,7 @@ xmlGetNodeName(const void *id)
 }
 
 size_t
-xmlCopyNodeName(const void *id, char *buf, size_t len)
+xmlNodeCopyName(const void *id, char *buf, size_t len)
 {
     struct _xml_id *xid = (struct _xml_id *)id;
     size_t slen = 0;
@@ -230,7 +230,7 @@ xmlCopyNodeName(const void *id, char *buf, size_t len)
     if (buf)
     {
         slen = len-1;
-        if (slen > xid->node.len) slen = xid->node.len;
+        if (slen > xid->node.name_len) slen = xid->node.name_len;
         memcpy(buf, xid->name, slen);
         *(buf + slen) = 0;
     }
@@ -239,7 +239,7 @@ xmlCopyNodeName(const void *id, char *buf, size_t len)
 }
 
 unsigned int
-xmlGetNumNodes(const void *id, const char *path)
+xmlNodeGetNum(const void *id, const char *path)
 {
     struct _xml_id *xid = (struct _xml_id *)id;
     size_t num = 0;
@@ -263,7 +263,7 @@ xmlGetNumNodes(const void *id, const char *path)
            pathname++;
            slen -= pathname-nodename;
            node = pathname;
-           p = __xmlGetNodePath(xid->start, &len, &node, &slen);
+           p = __xmlNodeGetPath(xid->start, &len, &node, &slen);
         }
         else
         {
@@ -274,7 +274,7 @@ xmlGetNumNodes(const void *id, const char *path)
         if (p)
         {
             char *node = nodename;
-            __xmlGetNode(p, &len, &node, &slen, &num);
+            __xmlNodeGet(p, &len, &node, &slen, &num);
         }
     }
 
@@ -282,7 +282,7 @@ xmlGetNumNodes(const void *id, const char *path)
 }
 
 void *
-xmlGetNodeNum(const void *pid, void *id, const char *element, size_t num)
+xmlNodeGetPos(const void *pid, void *id, const char *element, size_t num)
 {
     void *ret = 0;
 
@@ -296,13 +296,13 @@ xmlGetNodeNum(const void *pid, void *id, const char *element, size_t num)
         len = xpid->len;
         slen = strlen(element);
         node = (char *)element;
-        ptr = __xmlGetNode(xpid->start, &len, &node, &slen, &num);
+        ptr = __xmlNodeGet(xpid->start, &len, &node, &slen, &num);
         if (ptr)
         {
              xid->len = len;
              xid->start = ptr;
              xid->name = node;
-             xid->node.len = slen;
+             xid->node.name_len = slen;
              ret = xid;
         }
     }
@@ -344,17 +344,18 @@ xmlGetString(const void *id)
 }
 
 size_t
-xmlCopyString(const void *id, char *buf, size_t len)
+xmlCopyString(const void *id, char *buffer, size_t buflen)
 {
     struct _xml_id *xid = (struct _xml_id *)id;
-    size_t nlen = 0;
+    size_t ret = 0;
 
-    if (xid && xid->len && buf && len)
+    if (xid && xid->len && buffer && buflen)
     {
         char *ps, *pe, *pend;
-        int slen;
+        size_t slen, nlen;
 
-        nlen = len-1;
+        *buffer = '\0';
+        nlen = buflen-1;
         ps = xid->start;
         slen = xid->len;
         pend = ps+slen;
@@ -367,12 +368,14 @@ xmlCopyString(const void *id, char *buf, size_t len)
 
         if (nlen)
         {
-            memcpy(buf, ps, nlen);
-            *(buf+nlen) = 0;
+            if (nlen >= buflen) nlen = buflen-1;
+            memcpy(buffer, ps, nlen);
+            *(buffer+nlen) = 0;
+            ret = nlen;
         }
     }
 
-    return nlen;
+    return ret;
 }
 
 int
@@ -400,14 +403,14 @@ xmlCompareString(const void *id, const char *s)
 }
 
 char *
-xmlGetNodeString(const void *id, const char *path)
+xmlNodeGetString(const void *id, const char *path)
 {
     struct _xml_id *xid = (struct _xml_id *)id;
     char *str = 0;
 
     if (xid && xid->len && path)
     {
-        str = __xmlCopyNode(xid->start, xid->len, path);
+        str = __xmlNodeCopy(xid->start, xid->len, path);
         if (str)
         {
             char *ps, *pe, *pend;
@@ -432,45 +435,45 @@ xmlGetNodeString(const void *id, const char *path)
 }
 
 size_t
-xmlCopyNodeString(const void *id, const char *path, char *buffer, size_t buflen)
+xmlNodeCopyString(const void *id, const char *path, char *buffer, size_t buflen)
 {
     struct _xml_id *xid = (struct _xml_id *)id;
-    size_t len = 0;
+    size_t ret = 0;
 
     if (xid && xid->len && path && buffer && buflen)
     {
         char *str, *node;
-        size_t slen;
+        size_t slen, nlen;
 
         *buffer = '\0';
-        len = xid->len;
+        nlen = xid->len;
         slen = strlen(path);
         node = (char *)path;
-        str = __xmlGetNodePath(xid->start, &len, &node, &slen);
+        str = __xmlNodeGetPath(xid->start, &nlen, &node, &slen);
         if (str)
         {
             char *ps, *pe;
 
             ps = str;
-            pe = ps+len-1;
+            pe = ps+nlen-1;
 
             while ((ps<pe) && isspace(*ps)) ps++;
             while ((pe>ps) && isspace(*pe)) pe--;
 
-            len = (pe-ps)+1;
-            if (len >= buflen) len = buflen-1;
+            nlen = (pe-ps)+1;
+            if (nlen >= buflen) nlen = buflen-1;
 
-            memcpy(buffer, ps, len);
-            str = buffer + len;
-            *str = '\0';
+            memcpy(buffer, ps, nlen);
+            *(buffer + nlen) = '\0';
+            ret = nlen;
         }
     }
 
-    return len;
+    return ret;
 }
 
 int
-xmlCompareNodeString(const void *id, const char *path, const char *s)
+xmlNodeCompareString(const void *id, const char *path, const char *s)
 {
     struct _xml_id *xid = (struct _xml_id *)id;
     int ret = -1;
@@ -478,12 +481,12 @@ xmlCompareNodeString(const void *id, const char *path, const char *s)
     if (xid && xid->len && path && s && (strlen(s) > 0))
     {
         char *node, *str, *ps, *pe;
-        size_t len, slen, i;
+        size_t len, slen;
 
         len = xid->len;
         slen = strlen(path);
         node = (char *)path;
-        str = __xmlGetNodePath(xid->start, &len, &node, &slen);
+        str = __xmlNodeGetPath(xid->start, &len, &node, &slen);
         if (str)
         {
             ps = str;
@@ -517,7 +520,7 @@ xmlGetInt(const void *id)
 }
 
 long int
-xmlGetNodeInt(const void *id, const char *path)
+xmlNodeGetInt(const void *id, const char *path)
 {
     struct _xml_id *xid = (struct _xml_id *)id;
     long int li = 0;
@@ -530,7 +533,7 @@ xmlGetNodeInt(const void *id, const char *path)
         len = xid->len;
         slen = strlen(path);
         node = (char *)path;
-        str = __xmlGetNodePath(xid->start, &len, &node, &slen);
+        str = __xmlNodeGetPath(xid->start, &len, &node, &slen);
         if (str)
         {
             char *end = str+len;
@@ -557,7 +560,7 @@ xmlGetDouble(const void *id)
 }
 
 double
-xmlGetNodeDouble(const void *id, const char *path)
+xmlNodeGetDouble(const void *id, const char *path)
 {
     struct _xml_id *xid = (struct _xml_id *)id;
     double d = 0.0;
@@ -570,7 +573,7 @@ xmlGetNodeDouble(const void *id, const char *path)
         len = xid->len;
         slen = strlen(path);
         node = (char *)path;
-        str = __xmlGetNodePath(xid->start, &len, &node, &slen);
+        str = __xmlNodeGetPath(xid->start, &len, &node, &slen);
         if (str)
         {
             char *end = str+len;
@@ -598,10 +601,265 @@ xmlMarkId(const void *id)
    return (void *)xmid;
 }
 
+double
+xmlAttributeGetDouble(const void *id, const char *name)
+{
+   struct _xml_id *xid = (struct _xml_id *)id;
+   double ret = 0.0;
+
+   if (xid && xid->start && xid->len && xid->node.name_len)
+   {
+       char *p, *end, *new = 0;
+
+       assert(xid->start > xid->name);
+
+       p = xid->name + xid->node.name_len;
+       end = xid->start-1;
+
+       while ((p<end) && isspace(*p)) p++;
+       while (p<end)
+       {
+          size_t elementlen = strlen(name);
+          size_t restlen = end-p;
+          char *element = (char *)name;
+
+          new = __xml_memncasecmp(p, &restlen, &element, &elementlen);
+          if (new)
+          {
+             restlen = end-p;
+             new = memchr(p, '=', restlen);
+             if (new)
+             {
+                new++;
+                if (*new == '"') new++;
+                restlen -= (new-p);
+                end = new+restlen;
+                ret = strtod(new, &end);
+             }
+             break;
+          }
+
+          while ((p<end) && !isspace(*p)) p++;
+          if (p<end)
+             while ((p<end) && isspace(*p)) p++;
+       }
+   }
+
+   return ret;
+}
+
+long int
+xmlAttributeGetInt(const void *id, const char *name)
+{
+   struct _xml_id *xid = (struct _xml_id *)id;
+   long int ret = 0;
+
+   if (xid && xid->start && xid->len && xid->node.name_len)
+   {
+       char *p, *end, *new = 0;
+
+       assert(xid->start > xid->name);
+
+       p = xid->name + xid->node.name_len;
+       end = xid->start-1;
+
+       while ((p<end) && isspace(*p)) p++;
+       while (p<end)
+       {
+          size_t elementlen = strlen(name);
+          size_t restlen = end-p;
+          char *element = (char *)name;
+
+          new = __xml_memncasecmp(p, &restlen, &element, &elementlen);
+          if (new)
+          {
+             restlen = end-p;
+             new = memchr(p, '=', restlen);
+             if (new)
+             {
+                new++;
+                if (*new == '"') new++;
+                restlen -= (new-p);
+                end = new+restlen;
+                ret = strtol(new, &end, 10);
+             }
+             break;
+          }
+
+          while ((p<end) && !isspace(*p)) p++;
+          if (p<end)
+             while ((p<end) && isspace(*p)) p++;
+       }
+   }
+
+   return ret;
+}
+
+char *
+xmlAttributeGetString(const void *id, const char *name)
+{
+   struct _xml_id *xid = (struct _xml_id *)id;
+   char *ret = 0;
+
+   if (xid && xid->start && xid->len && xid->node.name_len)
+   {
+       char *p, *end, *new = 0;
+
+       assert(xid->start > xid->name);
+
+       p = xid->name + xid->node.name_len;
+       end = xid->start-1;
+
+       while ((p<end) && isspace(*p)) p++;
+       while (p<end)
+       {
+          size_t elementlen = strlen(name);
+          size_t restlen = end-p;
+          char *element = (char *)name;
+
+          new = __xml_memncasecmp(p, &restlen, &element, &elementlen);
+          if (new)
+          {
+             restlen = end-p;
+             new = memchr(p, '=', restlen);
+             if (new)
+             {
+                new++;
+                if (*new == '"') new++;
+                p = new;
+                while ((p<end) && (*p != '"') && (*p != ' ')) p++;
+                if (p<end)
+                {
+                   ret = calloc(1, p-new);
+                   memcpy(ret, new, (p-new));
+                }
+             }
+             break;
+          }
+
+          while ((p<end) && !isspace(*p)) p++;
+          if (p<end)
+             while ((p<end) && isspace(*p)) p++;
+       }
+   }
+
+   return ret;
+}
+
+size_t
+xmlAttributeCopyString(const void *id, const char *name,
+                                       char *buffer, size_t buflen)
+{
+   struct _xml_id *xid = (struct _xml_id *)id;
+   size_t ret = 0;
+
+   if (xid && xid->start && xid->len && xid->node.name_len
+       && buffer && buflen)
+   {
+       char *ps, *pe;
+
+       *buffer = '\0';
+       ps = xid->name + xid->node.name_len + 1;
+       pe = xid->start - 1;
+
+       assert((int)(pe-ps) > 0);
+
+       while ((ps<pe) && isspace(*ps)) ps++;
+       while (ps<pe)
+       {
+          size_t slen = strlen(name);
+          size_t restlen = pe-ps;
+
+          if ((restlen >= slen) && (strncasecmp(ps, name, slen) == 0))
+          {
+             char *new;
+
+             restlen = pe-ps;
+             new = memchr(ps, '=', restlen);
+             if (new)
+             {
+                new++;
+                if (*new == '"') new++;
+                ps = new;
+                while ((ps<pe) && (*ps != '"') && (*ps != ' ')) ps++;
+                if (ps<pe)
+                {
+                   restlen = ps-new;
+                   if (restlen >= buflen) restlen = buflen-1;
+                   memcpy(buffer, new, restlen);
+                   *(buffer+restlen) = 0;
+                   ret = restlen;
+                }
+             }
+             break;
+          }
+
+          while ((ps<pe) && !isspace(*ps)) ps++;
+          if (ps<pe)
+             while ((ps<pe) && isspace(*ps)) ps++;
+       }
+   }
+
+   return ret;
+}
+
+int
+xmlAttributeCompareString(const void *id, const char *name, const char *s)
+{
+   struct _xml_id *xid = (struct _xml_id *)id;
+   int ret = -1;
+
+   if (xid && xid->start && xid->len && xid->node.name_len
+       && s && strlen(s))
+   {
+      char *ps, *pe;
+
+       ps = xid->name + xid->node.name_len + 1;
+       pe = xid->start - 1;
+
+       assert((int)(pe-ps) > 0);
+
+       while ((ps<pe) && isspace(*ps)) ps++;
+       while (ps<pe)
+       {
+          size_t slen = strlen(name);
+          size_t restlen = pe-ps;
+
+          if ((restlen >= slen) && (strncasecmp(ps, name, slen) == 0))
+          {
+             char *new;
+
+             restlen = pe-ps;
+             new = memchr(ps, '=', restlen);
+             if (new)
+             {
+                new++;
+                if (*new == '"') new++;
+                ps = new;
+                while ((ps<pe) && (*ps != '"') && (*ps != ' ')) ps++;
+                if (ps<pe)
+                {
+                   int alen = ps-new;
+                   ret = strncasecmp(new, s, alen);
+                }
+             }
+             break;
+          }
+
+          while ((ps<pe) && !isspace(*ps)) ps++;
+          if (ps<pe)
+             while ((ps<pe) && isspace(*ps)) ps++;
+       }
+   }
+
+   return ret;
+}
+
+
 /* -------------------------------------------------------------------------- */
 
 static char *
-__xmlCopyNode(const char *start, size_t len, const char *path)
+__xmlNodeCopy(const char *start, size_t len, const char *path)
 {
    char *node, *p, *ret = 0;
    size_t rlen, slen;
@@ -609,7 +867,7 @@ __xmlCopyNode(const char *start, size_t len, const char *path)
    rlen = len;
    slen = strlen(path);
    node = (char *)path;
-   p = __xmlGetNodePath(start, &rlen, &node, &slen);
+   p = __xmlNodeGetPath(start, &rlen, &node, &slen);
    if (p && rlen)
    {
       ret = calloc(1, rlen+1);
@@ -620,7 +878,7 @@ __xmlCopyNode(const char *start, size_t len, const char *path)
 }
 
 char *
-__xmlGetNodePath(const char *start, size_t *len, char **name, size_t *plen)
+__xmlNodeGetPath(const char *start, size_t *len, char **name, size_t *plen)
 {
     char *node;
     char *ret = 0;
@@ -649,11 +907,11 @@ __xmlGetNodePath(const char *start, size_t *len, char **name, size_t *plen)
         else plen = path++ - node;
 
         num = 0;
-        ret = __xmlGetNode(start, len, &node, &plen, &num);
+        ret = __xmlNodeGet(start, len, &node, &plen, &num);
         if (ret && path)
         {
            plen = slen - (path - *name);
-           ret = __xmlGetNodePath(ret, len, &path, &plen);
+           ret = __xmlNodeGetPath(ret, len, &path, &plen);
         }
 
         *name = path;
@@ -663,13 +921,13 @@ __xmlGetNodePath(const char *start, size_t *len, char **name, size_t *plen)
 }
 
 char *
-__xmlGetNode(const char *start, size_t *len, char **name, size_t *rlen, size_t *nodenum)
+__xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *nodenum)
 {
     char *new, *cur, *ne, *ret = 0;
+    char *element, *start_tag=0;
     size_t restlen, elementlen;
     size_t retlen = 0;
     int found, num;
-    char *element;
 
     assert (start != 0);
     assert (len != 0);
@@ -701,7 +959,7 @@ __xmlGetNode(const char *start, size_t *len, char **name, size_t *rlen, size_t *
 
         if (*cur == '!')
         {
-            new = __xmlSkipComment(cur, restlen);
+            new = __xmlCommentSkip(cur, restlen);
             if (!new) return 0;
             restlen -= new-cur;
             cur = new;
@@ -709,7 +967,7 @@ __xmlGetNode(const char *start, size_t *len, char **name, size_t *rlen, size_t *
         }
         else if (*cur == '?')
         {
-            new = __xmlSkipInfo(cur, restlen);
+            new = __xmlInfoSkip(cur, restlen);
             if (!new) return 0;
 
             restlen -= new-cur;
@@ -723,7 +981,12 @@ __xmlGetNode(const char *start, size_t *len, char **name, size_t *rlen, size_t *
         if (new)
         {
             retlen = elementlen;
-            if (found == num ) ret = new+1;
+            if (found == num )
+            {
+              ret = new+1;
+              start_tag = element;
+            }
+            else start_tag = 0;
         }
         else
         {
@@ -746,7 +1009,7 @@ __xmlGetNode(const char *start, size_t *len, char **name, size_t *rlen, size_t *
             size_t nlen = 1;
             size_t pos = -1;
 
-            new = __xmlGetNode(cur, &slen, &node, &nlen, &pos);
+            new = __xmlNodeGet(cur, &slen, &node, &nlen, &pos);
             if (!new)
             {
                 if (slen == restlen) return 0;
@@ -767,8 +1030,12 @@ __xmlGetNode(const char *start, size_t *len, char **name, size_t *rlen, size_t *
         {
             if (!strncasecmp(new+2, element, elementlen))
             {
-                if (found == num) *len = new-ret;
-                *name = element;
+                if (found == num) 
+                {
+                   assert(start_tag != 0);
+                   *len = new-ret;
+                   *name = start_tag;
+                }
                 found++;
             }
 
@@ -788,7 +1055,7 @@ __xmlGetNode(const char *start, size_t *len, char **name, size_t *rlen, size_t *
 }
 
 char *
-__xmlSkipComment(const char *start, size_t len)
+__xmlCommentSkip(const char *start, size_t len)
 {
     char *cur, *new;
 
@@ -825,7 +1092,7 @@ __xmlSkipComment(const char *start, size_t len)
 }
 
 char *
-__xmlSkipInfo(const char *start, size_t len)
+__xmlInfoSkip(const char *start, size_t len)
 {
     char *cur, *new;
 
@@ -848,43 +1115,6 @@ __xmlSkipInfo(const char *start, size_t len)
 }
 
 
-void *
-__xml_memmem(const char *haystack, size_t haystacklen,
-             const char *needle, size_t needlelen)
-{
-    void *rptr = 0;
-
-    if (haystack && needle && (needlelen > 0) && (haystacklen >= needlelen))
-    {
-        char *ns, *hs, *ptr;
-
-        hs = (char *)haystack;
-        ns = (char *)needle;
-        do
-        {
-            ptr = memchr(hs, *ns, haystacklen);
-            if (ptr)
-            {
-                haystacklen -= (ptr - hs);
-
-                if (haystacklen < needlelen) break;
-                if (memcmp(ptr, needle, needlelen) == 0)
-                {
-                   rptr = ptr;
-                   break;
-                }
-
-                hs = ptr+1;
-            }
-            else break;
-        }
-        while (haystacklen > needlelen);
-    }
-
-    return rptr;
-}
-
-
 #define NOCASECMP(a,b)  ( ((a)^(b)) & 0xdf )
 void *
 __xml_memncasecmp(const char *haystack, size_t *haystacklen,
@@ -952,7 +1182,7 @@ __xml_memncasecmp(const char *haystack, size_t *haystacklen,
  */
 
 void *
-simple_mmap(int fd, unsigned int length, SIMPLE_UNMMAP *un)
+simple_mmap(int fd, size_t length, SIMPLE_UNMMAP *un)
 {
     HANDLE f;
     HANDLE m;
@@ -971,8 +1201,6 @@ simple_mmap(int fd, unsigned int length, SIMPLE_UNMMAP *un)
         return NULL;
     }
 
-    if (n) *n = GetFileSize(f, NULL);
-
     if (un)
     {
         un->m = m;
index 874fc659b8888e15b7e9dbf35d0f4a788f33a0f6..b02296554dfc1ed50aa0f6a5775b596d06c2b0f1 100644 (file)
@@ -29,7 +29,7 @@
 #define __XML_CONFIG 1
 
 /**
- * Open an XML file for processing
+ * Open an XML file for processing.
  *
  * @param fname path to the file 
  * @return XML-id which is used for further processing
@@ -37,7 +37,7 @@
 void *xmlOpen(const char *);
 
 /**
- * Close the XML file after which no further processing is possible
+ * Close the XML file after which no further processing is possible.
  *
  * @param xid XML-id
  */
@@ -47,22 +47,22 @@ void xmlClose(void *);
 /**
  * Locate a subsection of the xml tree for further processing.
  * This adds processing speed since the reuired nodes will only be searched
- * in the subsection
+ * in the subsection.
  *
  * The memory allocated for the XML-subsection-id has to be freed by the
- * calling process
+ * calling process.
  *
  * @param xid XML-id
  * @param node path to the node containing the subsection
  * @return XML-subsection-id for further processing
  */
-void *xmlGetNode(const void *, const char *);
+void *xmlNodeGet(const void *, const char *);
 
 /**
  * Copy a subsection of the xml tree for further processing.
  * This is useful when it's required to process a section of the XML code
  * after the file has been closed. The drawback is the added memory
- * requirements
+ * requirements.
  *
  * The memory allocated for the XML-subsection-id has to be freed by the
  * calling process.
@@ -71,41 +71,56 @@ void *xmlGetNode(const void *, const char *);
  * @param node path to the node containing the subsection
  * @return XML-subsection-id for further processing
  */
-void *xmlCopyNode(const void *, const char *);
+void *xmlNodeCopy(const void *, const char *);
 
 
 /**
  * Return the name of this node.
- * The returned string has to be freed by the calling process
+ * The returned string has to be freed by the calling process.
  *
  * @param xid XML-id
  * @return a newly alocated string containing the node name
  */
-char *xmlGetNodeName(const void *);
+char *xmlNodeGetName(const void *);
 
 /**
- * Copy the name of this node in a pre-allocated buffer
+ * Copy the name of this node in a pre-allocated buffer.
  *
  * @param xid XML-id
  * @param buffer the buffer to copy the string to
  * @param buflen length of the destination buffer
  * @return the length of the node name
  */
-size_t xmlCopyNodeName(const void *, char *, size_t);
+size_t xmlNodeCopyName(const void *, char *, size_t);
+
 
+/**
+ * Create a marker XML-id that starts out with the same settings as the
+ * refference XML-id.
+ *
+ * Marker id's are required when xmlNodeGetNum() and xmlNodeGetPos() are used
+ * to walk a number of nodes. The xmlNodeGetPos function adjusts the contents
+ * of the provided XML-id to keep track of it's position within the xml section.
+ * The returned XML-id is limited to the boundaries of the requested XML tag
+ * and has to be freed by the calling process.
+ *
+ * @param xid reference XML-id
+ * @return a copy of the reference XML-id
+ */
+void *xmlMarkId(const void *);
 
 /**
- * Get the number of nodes with the same name from a specified xml path
+ * Get the number of nodes with the same name from a specified xml path.
  *
  * @param xid XML-id
  * @param path path to the xml node
  * @return the number count of the nodename
  */
-unsigned int xmlGetNumNodes(const void *, const char *);
+unsigned int xmlNodeGetNum(const void *, const char *);
 
 /**
  * Get the nth occurrence of node in the parent node.
- * The return value should neevr be altered or freed by the caller
+ * The return value should never be altered or freed by the caller.
  *
  * @param pid XML-id of the parent node of this node
  * @param xid XML-id
@@ -113,12 +128,12 @@ unsigned int xmlGetNumNodes(const void *, const char *);
  * @param num specify which occurence to return
  * @return XML-subsection-id for further processing or NULL if unsuccessful
  */
-void *xmlGetNodeNum(const void *, void *, const char *, int);
+void *xmlNodeGetPos(const void *, void *, const char *, int);
 
 
 /**
  * Get a string of characters from the current node.
- * The returned string has to be freed by the calling process
+ * The returned string has to be freed by the calling process.
  *
  * @param xid XML-id
  * @return a newly alocated string containing the contents of the node
@@ -129,7 +144,7 @@ char *xmlGetString(const void *);
  * Get a string of characters from the current node.
  * This function has the advantage of not allocating its own return buffer,
  * keeping the memory management to an absolute minimum but the disadvantage
- * is that it's unreliable in multithread environments
+ * is that it's unreliable in multithread environments.
  *
  * @param xid XML-id
  * @param buffer the buffer to copy the string to
@@ -140,7 +155,7 @@ size_t xmlCopyString(const void *, char *, size_t);
 
 /**
  * Compare the value of this node to a reference string.
- * Comparing is done in a case insensitive way
+ * Comparing is done in a case insensitive way.
  *
  * @param xid XML-id
  * @param str the string to compare to
@@ -152,19 +167,19 @@ int xmlCompareString(const void *, const char *);
 
 /**
  * Get a string of characters from a specified xml path.
- * The returned string has to be freed by the calling process
+ * The returned string has to be freed by the calling process.
  *
  * @param xid XML-id
  * @param path path to the xml node
  * @return a newly alocated string containing the contents of the node
  */
-char *xmlGetNodeString(const void *, const char *);
+char *xmlNodeGetString(const void *, const char *);
 
 /**
  * Get a string of characters from a specified xml path.
  * This function has the advantage of not allocating its own return buffer,
  * keeping the memory management to an absolute minimum but the disadvantage
- * is that it's unreliable in multithread environments
+ * is that it's unreliable in multithread environments.
  *
  * @param xid XML-id
  * @param path path to the xml node
@@ -172,11 +187,11 @@ char *xmlGetNodeString(const void *, const char *);
  * @param buflen length of the destination buffer
  * @return the length of the string
  */
-size_t xmlCopyNodeString(const void *, const char *, char *, size_t);
+size_t xmlNodeCopyString(const void *, const char *, char *, size_t);
 
 /**
  * Compare the value of a node to a reference string.
- * Comparing is done in a case insensitive way
+ * Comparing is done in a case insensitive way.
  *
  * @param xid XML-id
  * @param path path to the xml node to compare to
@@ -185,11 +200,46 @@ size_t xmlCopyNodeString(const void *, const char *, char *, size_t);
  * of the node is found, respectively, to be less than, to match, or be greater
  * than str
  */
-int xmlCompareNodeString(const void *, const char *, const char *);
+int xmlNodeCompareString(const void *, const char *, const char *);
 
+/**
+ * Get a string of characters from a named attribute.
+ * The returned string has to be freed by the calling process.
+ *
+ * @param xid XML-id
+ * @param name name of the attribute to acquire
+ * @return the contents of the node converted to an integer value
+ */
+char *xmlAttributeGetString(const void *, const char *);
 
 /**
- * Get the integer value from the current node
+ * Get a string of characters from a named attribute.
+ * This function has the advantage of not allocating its own return buffer,
+ * keeping the memory management to an absolute minimum but the disadvantage
+ * is that it's unreliable in multithread environments.
+ *
+ * @param xid XML-id
+ * @param name name of the attribute to acquire.
+ * @param buffer the buffer to copy the string to
+ * @param buflen length of the destination buffer
+ * @return the length of the string
+size_t xmlAttributeCopyString(const void *, const char *, const char *, size_t);
+
+/**
+ * Compare the value of an attribute to a reference string.
+ * Comparing is done in a case insensitive way.
+ *
+ * @param xid XML-id
+ * @param name name of the attribute to acquire.
+ * @param str the string to compare to
+ * @return an integer less than, equal to, ro greater than zero if the value
+ * of the node is found, respectively, to be less than, to match, or be greater
+ * than str
+int xmlAttributeCompareString(const void *, const char *, const char *);
+
+
+/**
+ * Get the integer value from the current node/
  *
  * @param xid XML-id
  * @return the contents of the node converted to an integer value
@@ -197,17 +247,26 @@ int xmlCompareNodeString(const void *, const char *, const char *);
 long int xmlGetInt(const void *);
 
 /**
- * Get an integer value from a specified xml path
+ * Get an integer value from a specified xml path.
  *
  * @param xid XML-id
  * @param path path to the xml node
  * @return the contents of the node converted to an integer value
  */
-long int xmlGetNodeInt(const void *, const char *);
+long int xmlNodeGetInt(const void *, const char *);
+
+/**
+ * Get the integer value from the named attribute.
+ *
+ * @param xid XML-id
+ * @param name name of the attribute to acquire
+ * @return the contents of the node converted to an integer value
+ */
+long int xmlAttributeGetInt(const void *, const char *);
 
 
 /**
- * Get the double value from the curent node
+ * Get the double value from the curent node/
  *
  * @param xid XML-id
  * @return the contents of the node converted to a double value
@@ -215,24 +274,23 @@ long int xmlGetNodeInt(const void *, const char *);
 double xmlGetDouble(const void *);
 
 /**
- * Get a double value from a specified xml path
+ * Get a double value from a specified xml path/
  *
  * @param xid XML-id
  * @param path path to the xml node
  * @return the contents of the node converted to a double value
  */
-double xmlGetNodeDouble(const void *, const char *);
+double xmlNodeGetDouble(const void *, const char *);
 
 
 /**
- * Create a marker XML-id that starts out with the same settings as the
- * refference XML-id.
- * The returned XML-id has to be freed by the calling process
+ * Get the double value from the named attribute.
  *
- * @param xid reference XML-id
- * @return a copy of the reference XML-id
+ * @param xid XML-id
+ * @param name name of the attribute to acquire
+ * @return the contents of the node converted to an integer value
  */
-void *xmlMarkId(const void *);
+double xmlAttributeGetDouble(const void *, const char *);
 
 #endif /* __XML_CONFIG */
 
index 90a55e4395b9989d5c982decf00741c73e4fd3a3..fe4782e0fd607639284c85496bf0996391bca228 100644 (file)
@@ -1,7 +1,9 @@
 #include <stdio.h>
-#include <strings.h>
-#include <stdlib.h>
+
+#define _GNU_SOURCE
 #include <string.h>
+#include <strings.h>
+#include <assert.h>
 
 #include "xml.h"
 
@@ -13,6 +15,7 @@ static char *_element = 0;
 static char *_value = 0;
 static char *_root = 0;
 static char *_print = 0;
+static char *_attribute = 0;
 static int print_filenames = 0;
 
 static void free_and_exit(int i);
@@ -29,30 +32,35 @@ show_help ()
     printf("usage: xmlgrep [options] [file ...]\n\n");
     printf("Options:\n");
     printf("\t-h\t\tshow this help message\n");
+    printf("\t-a <string>\tprint this attribute as the output\n");
     printf("\t-e <id>\t\tshow sections that contain this element\n");
     printf("\t-p <id>\t\tprint this element as the output\n");
     printf("\t-r <path>\tspecify the XML search root\n");
-    printf("\t-v <string>\tshow sections where one of the elements has this ");
-    printf("value\n\n");
+    printf("\t-v <string>\tfilter sections that contain this vale\n\n");
     printf(" To print the contents of the 'type' element of the XML section ");
-    printf("that begins\n at '/printer/output' one would use the following ");
-    printf("syntax:\n\n\txmlgrep -r /printer/output -p type sample.xml\n\n");
+    printf("that begins\n at '/printer/output' use the following command:\n\n");
+    printf("\txmlgrep -r /printer/output -p type sample.xml\n\n");
+    printf(" To filter 'output' elements under '/printer' that have attribute");
+    printf(" 'n' set to '1'\n use the following command:\n\n");
+    printf("\txmlgrep -r /printer -p output -a n -v 1 sample.xml\n\n");
     printf(" To filter out sections that contain the 'driver' element with ");
-    printf("'generic' as\n it's value one would issue the following command:");
+    printf("'generic' as\n it's value use the following command:");
     printf("\n\n\txmlgrep -r /printer/output -e driver -v generic sample.xml");
     printf("\n\n");
     free_and_exit(0);
 }
 
 void
-free_and_exit(int i)
+free_and_exit(int ret)
 {
     if (_root && _root != _static_root) free(_root);
     if (_element && _element != _static_element) free(_element);
     if (_value) free(_value);
     if (_print) free(_print);
+    if (_attribute) free(_attribute);
     if (_filenames)
     {
+        unsigned int i;
         for (i=0; i < _fcount; i++)
         {
             if (_filenames[i])
@@ -64,17 +72,18 @@ free_and_exit(int i)
         free(_filenames);
     }
  
-    exit(i);
+    exit(ret);
 }
 
 int
 parse_option(char **args, int n, int max)
 {
     char *opt, *arg = 0;
-    int sz;
+    unsigned int alen = 0;
+    unsigned int olen;
 
     opt = args[n];
-    if (opt[0] == '-' && opt[1] == '-')
+    if (strncmp(opt, "--", 2) == 0)
         opt++;
 
     if ((arg = strchr(opt, '=')) != NULL)
@@ -90,36 +99,52 @@ parse_option(char **args, int n, int max)
 #endif
     }
 
-    sz = strlen(opt);
-    if (strncmp(opt, "-help", sz) == 0)
+    olen = strlen(opt);
+    if (strncmp(opt, "-help", olen) == 0)
     {
         show_help();
     }
-    else if (strncmp(opt, "-root", sz) == 0)
+    else if (strncmp(opt, "-root", olen) == 0)
+    {
+        if (arg == 0) SHOW_NOVAL(opt);
+        alen = strlen(arg)+1;
+        _root = malloc(alen);
+        memcpy(_root, arg, alen);
+        return 2;
+    }
+    else if (strncmp(opt, "-element", olen) == 0)
     {
         if (arg == 0) SHOW_NOVAL(opt);
-        _root = strdup(arg);
+        alen = strlen(arg)+1;
+        _element = malloc(alen);
+        memcpy(_element, arg, alen);
         return 2;
     }
-    else if (strncmp(opt, "-element", sz) == 0)
+    else if (strncmp(opt, "-value", olen) == 0)
     {
         if (arg == 0) SHOW_NOVAL(opt);
-        _element = strdup(arg);
+        alen = strlen(arg)+1;
+        _value = malloc(alen);
+        memcpy(_value, arg, alen);
         return 2;
     }
-    else if (strncmp(opt, "-value", sz) == 0)
+    else if (strncmp(opt, "-print", olen) == 0)
     {
         if (arg == 0) SHOW_NOVAL(opt);
-        _value = strdup(arg);
+        alen = strlen(arg)+1;
+        _print = malloc(alen);
+        memcpy(_print, arg, alen);
         return 2;
     }
-    else if (strncmp(opt, "-print", sz) == 0)
+    else if (strncmp(opt, "-attribute", olen) == 0)
     {
         if (arg == 0) SHOW_NOVAL(opt);
-        _print = strdup(arg);
+        alen = strlen(arg)+1;
+        _attribute = malloc(alen);
+        memcpy(_attribute, arg, alen);
         return 2;
     }
-    else if (strncmp(opt, "-list-filenames", sz) == 0)
+    else if (strncmp(opt, "-list-filenames", olen) == 0)
     { /* undocumented test argument */
         print_filenames = 1;
         return 1;
@@ -147,7 +172,9 @@ parse_option(char **args, int n, int max)
            _filenames = ptr;
         }
 
-        _filenames[pos] = strdup(opt);
+        alen = strlen(opt)+1;
+        _filenames[pos] = malloc(alen);
+        memcpy(_filenames[pos], opt, alen);
     }
 
     return 1;
@@ -162,30 +189,42 @@ void walk_the_tree(size_t num, void *xid, char *tree)
         void *xmid = xmlMarkId(xid);
         if (xmid && _print)
         {
-            no_elements = xmlGetNumNodes(xid, _print);
+            no_elements = xmlNodeGetNum(xid, _print);
             for (i=0; i<no_elements; i++)
             {
-                if (xmlGetNodeNum(xid, xmid, _print, i) != 0)
+                if (xmlNodeGetPos(xid, xmid, _print, i) != 0)
                 {
-                    char value[64];
+                    char value[1024];
 
-                    xmlCopyString(xmid, (char *)&value, 64);
-                    printf("%s: <%s>%s</%s>\n",
-                           _filenames[num], _print, value, _print);
+                    xmlCopyString(xmid, (char *)&value, 1024);
+                    if (_value && _attribute)
+                    {
+                       if (!xmlAttributeCompareString(xmid, _attribute, _value))
+                       {
+                          printf("%s: <%s %s=\"%s\">%s</%s>\n",
+                                 _filenames[num], _print, _attribute, _value,
+                                                  value, _print);
+                       }
+                    }
+                    else
+                    {
+                       printf("%s: <%s>%s</%s>\n",
+                              _filenames[num], _print, value, _print);
+                    }
                 }
             }
             free(xmid);
         }
         else if (xmid && _value)
         {
-            no_elements = xmlGetNumNodes(xmid, _element);
+            no_elements = xmlNodeGetNum(xmid, _element);
             for (i=0; i<no_elements; i++)
             {
-                if (xmlGetNodeNum(xid, xmid, _element, i) != 0)
+                if (xmlNodeGetPos(xid, xmid, _element, i) != 0)
                 {
                     char nodename[64];
 
-                    xmlCopyNodeName(xmid, (char *)&nodename, 64);
+                    xmlNodeCopyName(xmid, (char *)&nodename, 64);
                     if (xmlCompareString(xmid, _value) == 0)
                     {
                         printf("%s: <%s>%s</%s>\n",
@@ -199,16 +238,16 @@ void walk_the_tree(size_t num, void *xid, char *tree)
         {
             char parentname[64];
 
-            xmlCopyNodeName(xid, (char *)&parentname, 64);
+            xmlNodeCopyName(xid, (char *)&parentname, 64);
 
-            no_elements = xmlGetNumNodes(xmid, _element);
+            no_elements = xmlNodeGetNum(xmid, _element);
             for (i=0; i<no_elements; i++)
             {
-                if (xmlGetNodeNum(xid, xmid, _element, i) != 0)
+                if (xmlNodeGetPos(xid, xmid, _element, i) != 0)
                 {
                     char nodename[64];
 
-                    xmlCopyNodeName(xmid, (char *)&nodename, 64);
+                    xmlNodeCopyName(xmid, (char *)&nodename, 64);
                     if (strncasecmp((char *)&nodename, _element, 64) == 0)
                     {
                         char value[64];
@@ -235,16 +274,22 @@ void walk_the_tree(size_t num, void *xid, char *tree)
         xmid = xmlMarkId(xid);
         if (xmid)
         {
-            if (next) *next++ = 0;
+            if (next)
+            {
+               *next++ = 0;
+            }
 
-            no_elements = xmlGetNumNodes(xid, elem);
+            no_elements = xmlNodeGetNum(xid, elem);
             for (i=0; i<no_elements; i++)
             {
-                if (xmlGetNodeNum(xid, xmid, elem, i) != 0)
+                if (xmlNodeGetPos(xid, xmid, elem, i) != 0)
                     walk_the_tree(num, xmid, next);
             }
 
-            if (next) *--next = '/';
+            if (next)
+            {
+               *--next = '/';
+            }
 
             free(xmid);
         }
@@ -275,7 +320,7 @@ void grep_file(unsigned num)
 int
 main (int argc, char **argv)
 {
-    int i;
+    unsigned int i;
 
     if (argc == 1)
         show_help();