#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)
{
{
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);
}
}
+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)
{
{
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');
}
}
}
-static xmlNode *
+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)
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]);
}
xmlNode *root = xmlDocGetRootElement(doc);
+
+#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], "containment"))
+ 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);
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"))