7 static const char *_static_root = "/";
8 static const char *_static_element = "*";
9 static unsigned int _fcount = 0;
10 static char **_filenames = 0;
11 static char *_element = 0;
12 static char *_value = 0;
13 static char *_root = 0;
14 static char *_print = 0;
15 static int print_filenames = 0;
17 static void free_and_exit(int i);
19 #define SHOW_NOVAL(opt) \
21 printf("option '%s' requires a value\n\n", (opt)); \
28 printf("usage: xmlgrep [options] [file ...]\n\n");
30 printf("\t-h\t\tshow this help message\n");
31 printf("\t-e <id>\t\tshow sections that contain this element\n");
32 printf("\t-p <id>\t\tprint this element as the output\n");
33 printf("\t-r <path>\tspecify the XML search root\n");
34 printf("\t-v <string>\tshow sections where one of the elements has this ");
36 printf(" To print the contents of the 'type' element of the XML section ");
37 printf("that begins\n at '/printer/output' one would use the following ");
38 printf("syntax:\n\n\txmlgrep -r /printer/output -p type sample.xml\n\n");
39 printf(" To filter out sections that contain the 'driver' element with ");
40 printf("'generic' as\n it's value one would issue the following command:");
41 printf("\n\n\txmlgrep -r /printer/output -e driver -v generic sample.xml");
49 if (_root && _root != _static_root) free(_root);
50 if (_element && _element != _static_element) free(_element);
51 if (_value) free(_value);
52 if (_print) free(_print);
55 for (i=0; i < _fcount; i++)
59 if (print_filenames) printf("%s\n", _filenames[i]);
70 parse_option(char **args, int n, int max)
76 if (opt[0] == '-' && opt[1] == '-')
79 if ((arg = strchr(opt, '=')) != NULL)
87 if (arg && arg[0] == '-')
93 if (strncmp(opt, "-help", sz) == 0)
97 else if (strncmp(opt, "-root", sz) == 0)
99 if (arg == 0) SHOW_NOVAL(opt);
103 else if (strncmp(opt, "-element", sz) == 0)
105 if (arg == 0) SHOW_NOVAL(opt);
106 _element = strdup(arg);
109 else if (strncmp(opt, "-value", sz) == 0)
111 if (arg == 0) SHOW_NOVAL(opt);
112 _value = strdup(arg);
115 else if (strncmp(opt, "-print", sz) == 0)
117 if (arg == 0) SHOW_NOVAL(opt);
118 _print = strdup(arg);
121 else if (strncmp(opt, "-list-filenames", sz) == 0)
122 { /* undocumented test argument */
126 else if (opt[0] == '-')
128 printf("Unknown option %s\n", opt);
136 _filenames = (char **)malloc(sizeof(char*));
140 char **ptr = (char **)realloc(_filenames, _fcount*sizeof(char*));
143 printf("Out of memory.\n\n");
149 _filenames[pos] = strdup(opt);
155 void walk_the_tree(size_t num, void *xid, char *tree)
157 unsigned int i, no_elements;
159 if (!tree) /* last node from the tree */
161 void *xmid = xmlMarkId(xid);
164 no_elements = xmlGetNumElements(xmid, _print);
165 for (i=0; i<no_elements; i++)
167 if (xmlGetNextElement(xid, xmid, _print) != 0)
169 char *value = xmlGetString(xmid);
172 printf("%s: <%s>%s</%s>\n",
173 _filenames[num], _print, value, _print);
180 else if (xmid && _value)
182 no_elements = xmlGetNumElements(xmid, _element);
183 for (i=0; i<no_elements; i++)
185 if ((xmlGetNextElement(xid, xmid, _element) != 0)
186 && (xmlCompareString(xmid, _value) == 0))
188 printf("%s: <%s>%s</%s>\n",
189 _filenames[num], _element, _value, _element);
194 else if (xmid && _element)
197 else printf("Error executing xmlMarkId\n");
199 else if (xid) /* walk the rest of the tree */
205 if (*elem == '/') elem++;
207 next = strchr(elem, '/');
209 xmid = xmlMarkId(xid);
212 if (next) *next++ = 0;
214 no_elements = xmlGetNumElements(xid, elem);
215 for (i=0; i<no_elements; i++)
217 if (xmlGetNextElement(xid, xmid, elem) != 0)
218 walk_the_tree(num, xmid, next);
221 if (next) *--next = '/';
225 else printf("Error executing xmlMarkId\n");
230 void grep_file(unsigned num)
234 xid = xmlOpen(_filenames[num]);
237 void *xrid = xmlMarkId(xid);
238 walk_the_tree(num, xrid, _root);
243 fprintf(stderr, "Error reading file '%s'\n", _filenames[num]);
250 main (int argc, char **argv)
259 int ret = parse_option(argv, i, argc);
263 if (_root == 0) _root = (char *)_static_root;
264 if (_element == 0) _element = (char *)_static_element;
266 for (i=0; i<_fcount; i++)