work on figuring more stuff out--may want to revert this commit
[pspp] / parse-xml.c
index 9304e8b0dcc5f0e4dac0de070ade6ae058318e7c..0c00abd908a57678cfae6f47db31b45df5cd1f66 100644 (file)
@@ -3,6 +3,32 @@
 #include <libxml/parser.h>
 #include <libxml/tree.h>
 
+static void
+print_parents(xmlNode *node)
+{
+  for (; node; node = node->next)
+    {
+      if (node->type == XML_ELEMENT_NODE)
+        {
+          for (xmlNode *child = node->children; child; child = child->next)
+            {
+              if (child->type == XML_ELEMENT_NODE)
+                  printf ("%s %s\n", node->name, child->name);
+              else if (child->type == XML_TEXT_NODE)
+                printf ("%s <text>\n", node->name);
+              else if (child->type == XML_CDATA_SECTION_NODE)
+                printf ("%s <cdata>\n", node->name);
+              else if (child->type == XML_COMMENT_NODE)
+                printf ("%s <comment>\n", node->name);
+              else
+                printf ("%s <%d>\n", node->name, child->type);
+            }
+        }
+
+      print_parents (node->children);
+    }
+}
+
 static void
 print_containment (xmlNode *node)
 {
@@ -10,33 +36,62 @@ print_containment (xmlNode *node)
     {
       if (node->type == XML_ELEMENT_NODE)
         {
-          printf ("%s", node->name);
+          const char *child_names[5000];
+          int child_name_cnt[5000];
+          int n_names = 0;
           for (xmlNode *child = node->children; child; child = child->next)
             {
-              putchar (' ');
+              const char *name;
+
               if (child->type == XML_ELEMENT_NODE)
                 {
-                  printf ("%s", child->name);
-
-                  int n = 0;
-                  while (child->next
-                         && child->next->type == XML_ELEMENT_NODE
-                         && !strcmp((char *) child->name, (char *) child->next->name))
+                  name = (char *) child->name;
+                  if (!strcmp((char *) node->name, "derivedVariable")
+                      && !strcmp((char *) name, "extension"))
                     {
-                      child = child->next;
-                      n++;
+                      char *p;
+                      asprintf(&p, "%s/%s", 
+                               (char *) xmlGetProp (child, (xmlChar *) "from"),
+                               (char *) xmlGetProp (child, (xmlChar *) "helpId"));
+                      name = p;
                     }
-                  if (n > 0)
-                    putchar ('+');
                 }
               else if (child->type == XML_TEXT_NODE)
-                printf ("<text>");
+                name = "<text>";
               else if (child->type == XML_CDATA_SECTION_NODE)
-                printf ("<cdata>");
+                name = "<cdata>";
+              else if (child->type == XML_COMMENT_NODE)
+                {
+                  name = "<comment>";
+                  //printf ("comment %s\n", (char *) child->content);
+                  continue;
+                }
               else
-                printf ("<%d>", child->type);
+                name = "<other>";
+
+#if 0
+              for (int i = 0; i < n_names; i++)
+                if (!strcmp(name, child_names[i]))
+                  {
+                    child_name_cnt[i]++;
+                    goto next;
+                  }
+#endif
+              child_names[n_names] = name;
+              child_name_cnt[n_names] = 1;
+              n_names++;
+
+              //next:;
             }
-          putchar ('\n');
+
+          printf ("%s", node->name);
+          for (int i = 0; i < n_names; i++)
+            {
+              printf (" %s", child_names[i]);
+              if (child_name_cnt[i] > 1)
+                printf ("+");
+            }
+          printf ("\n");
         }
 
       print_containment (node->children);
@@ -62,6 +117,14 @@ print_labels (xmlNode *node)
     }
 }
 
+static int
+compare_strings(const void *a_, const void *b_)
+{
+  const void *const *ap = a_;
+  const void *const *bp = b_;
+  return strcmp (*ap, *bp);
+}
+
 static void
 print_attributes (xmlNode * a_node)
 {
@@ -69,9 +132,19 @@ print_attributes (xmlNode * a_node)
     {
       if (node->type == XML_ELEMENT_NODE)
         {
-          printf ("%s", node->name);
+          printf ("%s<-%s", node->name, node->parent->name);
+
+          char *attrs[500];
+          int n_attrs = 0;
           for (xmlAttr *attr = node->properties; attr; attr = attr->next)
-            printf (" %s", attr->name);
+            if (!strcmp((char *) attr->name, "baseFormat"))
+              printf(" baseFormat=%s", attr->children->content);
+            else
+              attrs[n_attrs++] = (char *) attr->name;
+          qsort(attrs, n_attrs, sizeof *attrs, compare_strings);
+
+          for (int i = 0; i < n_attrs; i++)
+            printf (" %s", attrs[i]);
           putchar ('\n');
         }
 
@@ -111,12 +184,45 @@ print_attribute (xmlNode *node, const char *attr)
     {
       const char *s = (char *) xmlGetProp (node, (xmlChar *) attr);
       if (s)
-        printf ("%s %s\n", node->name, s);
+        printf ("%s %s=%s\n", node->name, attr, s);
 
       print_attribute (node->children, attr);
     }
 }
 
+static void
+print_element (xmlDoc *doc, xmlNode *node, const char *element)
+{
+  for (; node; node = node->next)
+    {
+      if (!strcmp(element, (char *) node->name))
+        {
+          xmlBuffer *buf = xmlBufferCreate();
+          xmlNodeDump (buf, doc, node, 0, 1);
+          xmlBufferDump (stdout, buf);
+          xmlBufferFree (buf);
+          putchar ('\n');
+        }
+
+      print_element (doc, node->children, element);
+    }
+}
+
+static __attribute__((unused)) xmlNode *
+find_page_setup (xmlNode *node)
+{
+  for (; node; node = node->next)
+    {
+      if (node->name && !strcmp ((char *) node->name, "pageSetup"))
+        return node;
+
+      xmlNode *ps = find_page_setup (node->children);
+      if (ps)
+        return ps;
+    }
+  return NULL;
+}
+
 static void
 print_text (xmlNode *node)
 {
@@ -153,7 +259,7 @@ main (int argc, char **argv)
 
   LIBXML_TEST_VERSION;
 
-  xmlDoc *doc = xmlReadFile(argv[1], NULL, 0);
+  xmlDoc *doc = xmlReadFile(argv[1], NULL, XML_PARSE_NOBLANKS);
   if (doc == NULL)
     {
       fprintf (stderr, "error: could not parse file %s\n", argv[1]);
@@ -162,7 +268,17 @@ main (int argc, char **argv)
 
   xmlNode *root = xmlDocGetRootElement(doc);
 
-  if (!strcmp(argv[2], "containment"))
+#if 0
+  /* Limit what we look at to pageSetup node and below. */
+  root = find_page_setup(root);
+  if (!root)
+    return 0;
+  root->next = NULL;
+#endif
+
+  if (!strcmp(argv[2], "parents"))
+    print_parents (root);
+  else if (!strcmp(argv[2], "containment"))
     print_containment (root);
   else if (!strcmp(argv[2], "attributes"))
     print_attributes (root);
@@ -170,6 +286,8 @@ main (int argc, char **argv)
     print_cdata (root);
   else if (!strcmp(argv[2], "text"))
     print_text (root);
+  else if (!strncmp(argv[2], "element:", 8))
+    print_element (doc, root, argv[2] + 8);
   else if (!strncmp(argv[2], "attr:", 5))
     print_attribute (root, argv[2] + 5);
   else if (!strcmp(argv[2], "labels"))