7 static const char *_static_root = "/";
8 static unsigned int _fcount = 0;
9 static char **_filenames = 0;
10 static char *_element = 0;
11 static char *_value = 0;
12 static char *_root = 0;
13 static char *_print = 0;
14 static int print_filenames = 0;
16 static void free_and_exit(int i);
18 #define SHOW_NOVAL(opt) \
20 printf("option '%s' requires a value\n\n", (opt)); \
27 printf("usage: xmlgrep [options] [file ...]\n\n");
29 printf("\t-h\t\tshow this help message\n");
30 printf("\t-e <id>\t\tshow sections that contain this element\n");
31 printf("\t-p <id>\t\tprint this element as the output\n");
32 printf("\t-r <path>\tspecify the XML search root\n");
33 printf("\t-v <string>\tshow sections where one of the elements has this ");
35 printf(" To print the contents of the 'type' element of the XML section ");
36 printf("that begins\n at '/printer/output' one would use the following ");
37 printf("syntax:\n\n\txmlgrep -r /printer/output -p type sample.xml\n\n");
38 printf(" To filter out sections that contain the 'driver' element with ");
39 printf("'generic' as\n it's value one would issue the following command:");
40 printf("\n\n\txmlgrep -r /printer/output -e driver -v generic sample.xml");
48 if (_root != _static_root) free(_root);
49 if (_element) free(_element);
50 if (_value) free(_value);
51 if (_print) free(_print);
54 for (i=0; i < _fcount; i++)
58 if (print_filenames) printf("%s\n", _filenames[i]);
69 parse_option(char **args, int n, int max)
75 if (opt[0] == '-' && opt[1] == '-')
78 if ((arg = strchr(opt, '=')) != NULL)
86 if (arg && arg[0] == '-')
92 if (strncmp(opt, "-help", sz) == 0)
96 else if (strncmp(opt, "-root", sz) == 0)
98 if (arg == 0) SHOW_NOVAL(opt);
102 else if (strncmp(opt, "-element", sz) == 0)
104 if (arg == 0) SHOW_NOVAL(opt);
105 _element = strdup(arg);
108 else if (strncmp(opt, "-value", sz) == 0)
110 if (arg == 0) SHOW_NOVAL(opt);
111 _value = strdup(arg);
114 else if (strncmp(opt, "-print", sz) == 0)
116 if (arg == 0) SHOW_NOVAL(opt);
117 _print = strdup(arg);
120 else if (strncmp(opt, "-list-filenames", sz) == 0)
121 { /* undocumented test argument */
125 else if (opt[0] == '-')
127 printf("Unknown option %s\n", opt);
135 _filenames = (char **)malloc(sizeof(char*));
139 char **ptr = (char **)realloc(_filenames, _fcount*sizeof(char*));
142 printf("Out of memory.\n\n");
148 _filenames[pos] = strdup(opt);
154 void walk_the_tree(size_t num, void *xid, char *tree)
156 unsigned int q, no_elements;
160 if (*elem == '/') elem++;
162 next = strchr(elem, '/');
163 if (!next) /* last node from the tree */
165 void *elem_id = xmlMarkId(xid);
167 no_elements = xmlGetNumElements(xid, elem);
168 for (q=0; q<no_elements; q++)
170 void *node_id = xmlGetNextElement(xid, elem_id, elem);
171 if (node_id && _print)
173 unsigned int i, no_nodes;
176 xmid = xmlMarkId(node_id);
178 no_nodes = xmlGetNumElements(node_id, _print);
179 for (i=0; i<no_nodes; i++)
181 if (xmlGetNextElement(node_id, xmid, _print) != 0)
183 char *value = xmlGetString(xmid);
186 printf("%s: <%s>%s</%s>\n",
187 _filenames[num], _print, value, _print);
194 else if (node_id && _value)
198 unsigned int i, no_nodes;
201 xmid = xmlMarkId(node_id);
203 no_nodes = xmlGetNumElements(node_id, _element);
204 for (i=0; i<no_nodes; i++)
206 xmlGetNextElement(node_id, xmid, _element);
207 if (xmlCompareString(xmid, _value) == 0)
209 printf("%s: <%s>%s</%s>\n",
210 _filenames[num], _element, _value, _element);
219 else if (node_id && _element)
225 else /* walk the rest of the tree */
229 xmid = xmlMarkId(xid);
234 no_elements = xmlGetNumElements(xid, elem);
235 for (q=0; q<no_elements; q++)
237 void *elem_id = xmlGetNextElement(xid, xmid, elem);
238 walk_the_tree(num, elem_id, next);
245 else printf("Error executing xmlMarkId\n");
250 void grep_file(unsigned num)
254 xrid = xmlOpen(_filenames[num]);
257 void *xid = xmlMarkId(xrid);
258 walk_the_tree(num, xrid, _root);
264 fprintf(stderr, "Error reading file '%s'\n", _filenames[num]);
271 main (int argc, char **argv)
280 int ret = parse_option(argv, i, argc);
284 if (_root == 0) (_root = (char *)_static_root);
286 for (i=0; i<_fcount; i++)