8 static const char *_static_root = "/";
9 static const char *_static_element = "*";
10 static unsigned int _fcount = 0;
11 static char **_filenames = 0;
12 static char *_element = 0;
13 static char *_value = 0;
14 static char *_root = 0;
15 static char *_print = 0;
16 static int print_filenames = 0;
18 static void free_and_exit(int i);
20 #define SHOW_NOVAL(opt) \
22 printf("option '%s' requires a value\n\n", (opt)); \
29 printf("usage: xmlgrep [options] [file ...]\n\n");
31 printf("\t-h\t\tshow this help message\n");
32 printf("\t-e <id>\t\tshow sections that contain this element\n");
33 printf("\t-p <id>\t\tprint this element as the output\n");
34 printf("\t-r <path>\tspecify the XML search root\n");
35 printf("\t-v <string>\tshow sections where one of the elements has this ");
37 printf(" To print the contents of the 'type' element of the XML section ");
38 printf("that begins\n at '/printer/output' one would use the following ");
39 printf("syntax:\n\n\txmlgrep -r /printer/output -p type sample.xml\n\n");
40 printf(" To filter out sections that contain the 'driver' element with ");
41 printf("'generic' as\n it's value one would issue the following command:");
42 printf("\n\n\txmlgrep -r /printer/output -e driver -v generic sample.xml");
50 if (_root && _root != _static_root) free(_root);
51 if (_element && _element != _static_element) free(_element);
52 if (_value) free(_value);
53 if (_print) free(_print);
56 for (i=0; i < _fcount; i++)
60 if (print_filenames) printf("%s\n", _filenames[i]);
71 parse_option(char **args, int n, int max)
77 if (opt[0] == '-' && opt[1] == '-')
80 if ((arg = strchr(opt, '=')) != NULL)
88 if (arg && arg[0] == '-')
94 if (strncmp(opt, "-help", sz) == 0)
98 else if (strncmp(opt, "-root", sz) == 0)
100 if (arg == 0) SHOW_NOVAL(opt);
104 else if (strncmp(opt, "-element", sz) == 0)
106 if (arg == 0) SHOW_NOVAL(opt);
107 _element = strdup(arg);
110 else if (strncmp(opt, "-value", sz) == 0)
112 if (arg == 0) SHOW_NOVAL(opt);
113 _value = strdup(arg);
116 else if (strncmp(opt, "-print", sz) == 0)
118 if (arg == 0) SHOW_NOVAL(opt);
119 _print = strdup(arg);
122 else if (strncmp(opt, "-list-filenames", sz) == 0)
123 { /* undocumented test argument */
127 else if (opt[0] == '-')
129 printf("Unknown option %s\n", opt);
137 _filenames = (char **)malloc(sizeof(char*));
141 char **ptr = (char **)realloc(_filenames, _fcount*sizeof(char*));
144 printf("Out of memory.\n\n");
150 _filenames[pos] = strdup(opt);
156 void walk_the_tree(size_t num, void *xid, char *tree)
158 unsigned int i, no_elements;
160 if (!tree) /* last node from the tree */
162 void *xmid = xmlMarkId(xid);
165 no_elements = xmlGetNumNodes(xid, _print);
166 for (i=0; i<no_elements; i++)
168 if (xmlGetNodeNum(xid, xmid, _print, i) != 0)
172 xmlCopyString(xmid, (char *)&value, 64);
173 printf("%s: <%s>%s</%s>\n",
174 _filenames[num], _print, value, _print);
179 else if (xmid && _value)
181 no_elements = xmlGetNumNodes(xmid, _element);
182 for (i=0; i<no_elements; i++)
184 if (xmlGetNodeNum(xid, xmid, _element, i) != 0)
188 xmlCopyNodeName(xmid, (char *)&nodename, 64);
189 if (xmlCompareString(xmid, _value) == 0)
191 printf("%s: <%s>%s</%s>\n",
192 _filenames[num], nodename, _value, nodename);
198 else if (xmid && _element)
202 xmlCopyNodeName(xid, (char *)&parentname, 64);
204 no_elements = xmlGetNumNodes(xmid, _element);
205 for (i=0; i<no_elements; i++)
207 if (xmlGetNodeNum(xid, xmid, _element, i) != 0)
211 xmlCopyNodeName(xmid, (char *)&nodename, 64);
212 if (strncasecmp((char *)&nodename, _element, 64) == 0)
215 xmlCopyString(xmid, (char *)&value, 64);
216 printf("%s: <%s> <%s>%s</%s> </%s>\n",
217 _filenames[num], parentname, nodename, value,
218 nodename, parentname);
223 else printf("Error executing xmlMarkId\n");
225 else if (xid) /* walk the rest of the tree */
231 if (*elem == '/') elem++;
233 next = strchr(elem, '/');
235 xmid = xmlMarkId(xid);
238 if (next) *next++ = 0;
240 no_elements = xmlGetNumNodes(xid, elem);
241 for (i=0; i<no_elements; i++)
243 if (xmlGetNodeNum(xid, xmid, elem, i) != 0)
244 walk_the_tree(num, xmid, next);
247 if (next) *--next = '/';
251 else printf("Error executing xmlMarkId\n");
256 void grep_file(unsigned num)
260 xid = xmlOpen(_filenames[num]);
263 void *xrid = xmlMarkId(xid);
264 walk_the_tree(num, xrid, _root);
269 fprintf(stderr, "Error reading file '%s'\n", _filenames[num]);
276 main (int argc, char **argv)
285 int ret = parse_option(argv, i, argc);
289 if (_root == 0) _root = (char *)_static_root;
290 if (_element == 0) _element = (char *)_static_element;
292 for (i=0; i<_fcount; i++)