3 #include <libxml/parser.h>
4 #include <libxml/tree.h>
7 print_parents(xmlNode *node)
9 for (; node; node = node->next)
11 if (node->type == XML_ELEMENT_NODE)
13 for (xmlNode *child = node->children; child; child = child->next)
15 if (child->type == XML_ELEMENT_NODE)
16 printf ("%s %s\n", node->name, child->name);
17 else if (child->type == XML_TEXT_NODE)
18 printf ("%s <text>\n", node->name);
19 else if (child->type == XML_CDATA_SECTION_NODE)
20 printf ("%s <cdata>\n", node->name);
21 else if (child->type == XML_COMMENT_NODE)
22 printf ("%s <comment>\n", node->name);
24 printf ("%s <%d>\n", node->name, child->type);
28 print_parents (node->children);
33 print_containment (xmlNode *node)
35 for (; node; node = node->next)
37 if (node->type == XML_ELEMENT_NODE)
39 const char *child_names[512];
40 int child_name_cnt[512];
42 for (xmlNode *child = node->children; child; child = child->next)
46 if (child->type == XML_ELEMENT_NODE)
47 name = (char *) child->name;
48 else if (child->type == XML_TEXT_NODE)
50 else if (child->type == XML_CDATA_SECTION_NODE)
52 else if (child->type == XML_COMMENT_NODE)
55 //printf ("comment %s\n", (char *) child->content);
61 for (int i = 0; i < n_names; i++)
62 if (!strcmp(name, child_names[i]))
67 child_names[n_names] = name;
68 child_name_cnt[n_names] = 1;
74 printf ("%s", node->name);
75 for (int i = 0; i < n_names; i++)
77 printf (" %s", child_names[i]);
78 if (child_name_cnt[i] > 1)
84 print_containment (node->children);
89 print_labels (xmlNode *node)
91 for (; node; node = node->next)
93 if (node->type == XML_ELEMENT_NODE
94 && !strcmp((char *) node->name, "label")
95 && node->parent->type == XML_ELEMENT_NODE
96 && !strcmp((char *) node->parent->name, "container"))
98 for (xmlNode *child = node->children; child; child = child->next)
99 if (child->type == XML_TEXT_NODE)
100 puts ((char *) child->content);
103 print_labels (node->children);
108 print_attributes (xmlNode * a_node)
110 for (xmlNode *node = a_node; node; node = node->next)
112 if (node->type == XML_ELEMENT_NODE)
114 printf ("%s", node->name);
115 for (xmlAttr *attr = node->properties; attr; attr = attr->next)
117 printf (" %s", attr->name);
118 if (!strcmp ((char *) attr->name, "baseFormat"))
119 printf ("=%s", (char *) xmlGetProp (node, attr->name));
124 print_attributes (node->children);
129 print_string(xmlChar *s)
131 for (char *p = (char *) s; *p; p++)
139 print_cdata (xmlNode * a_node)
141 for (xmlNode *node = a_node; node; node = node->next)
143 if (node->type == XML_CDATA_SECTION_NODE)
145 print_string (node->content);
149 print_cdata (node->children);
154 print_attribute (xmlNode *node, const char *attr)
156 for (; node; node = node->next)
158 const char *s = (char *) xmlGetProp (node, (xmlChar *) attr);
160 printf ("%s %s=%s\n", node->name, attr, s);
162 print_attribute (node->children, attr);
167 print_xml (xmlDoc *doc, xmlNode *node)
169 xmlBuffer *buf = xmlBufferCreate();
170 xmlNodeDump (buf, doc, node, 0, 0);
171 xmlBufferDump (stdout, buf);
177 print_element (xmlDoc *doc, xmlNode *node, const char *element)
179 for (; node; node = node->next)
181 if (node->name && !strcmp(element, (char *) node->name))
182 print_xml (doc, node);
184 print_element (doc, node->children, element);
189 print_id (xmlDoc *doc, xmlNode *node, const char *id)
191 for (; node; node = node->next)
193 if (node->type == XML_ELEMENT_NODE)
195 const char *node_id = (char *) xmlGetProp (node, (xmlChar *) "id");
196 if (node_id && !strcmp (node_id, id))
198 print_xml (doc, node);
203 print_id (doc, node->children, id);
207 static __attribute__((unused)) xmlNode *
208 find_node (xmlNode *node, const char *name)
210 for (; node; node = node->next)
212 if (node->name && !strcmp ((char *) node->name, name))
215 xmlNode *ps = find_node (node->children, name);
223 print_text (xmlNode *node)
225 for (; node; node = node->next)
227 if (node->type == XML_ELEMENT_NODE)
229 printf ("%s", node->name);
230 for (xmlNode *child = node->children; child; child = child->next)
231 if (child->type == XML_TEXT_NODE)
234 print_string (child->content);
239 print_text (node->children);
244 check_version (xmlNode *root, const char *version)
246 const char *s = (char *) xmlGetProp (root, (xmlChar *) "version");
249 fprintf (stderr, "missing version\n");
252 else if (strcmp(version, s))
261 fprintf (stderr, "usage: parse-xml FILE.xml containment|attributes\n");
266 main (int argc, char **argv)
273 xmlDoc *doc = xmlReadFile(argv[1], NULL, XML_PARSE_NOBLANKS);
276 fprintf (stderr, "error: could not parse file %s\n", argv[1]);
280 xmlNode *root = xmlDocGetRootElement(doc);
282 for (int i = 2; i < argc; i++)
284 if (!strcmp(argv[i], "parents"))
285 print_parents (root);
286 else if (!strcmp(argv[i], "containment"))
287 print_containment (root);
288 else if (!strcmp(argv[i], "attributes"))
289 print_attributes (root);
290 else if (!strcmp(argv[i], "cdata"))
292 else if (!strcmp(argv[i], "text"))
294 else if (!strncmp(argv[i], "element:", 8))
295 print_element (doc, root, argv[i] + 8);
296 else if (!strncmp(argv[i], "attr:", 5))
297 print_attribute (root, argv[i] + 5);
298 else if (!strncmp(argv[i], "id:", 3))
299 print_id (doc, root, argv[i] + 3);
300 else if (!strncmp(argv[i], "root:", 5))
302 /* Limit content to descendants of the given node. */
303 root = find_node (root, argv[i] + 5);
308 else if (!strncmp(argv[i], "musthave:", 9))
310 if (!find_node (root, argv[i] + 9))
313 else if (!strcmp(argv[i], "labels"))
315 else if (!strncmp(argv[i], "version=", 8))
316 check_version (root, argv[i] + 8);