9 # define strncasecmp strnicmp
16 static const char *_static_root = "/";
17 static const char *_static_element = "*";
18 static unsigned int _fcount = 0;
19 static char **_filenames = 0;
20 static char *_element = 0;
21 static char *_value = 0;
22 static char *_root = 0;
23 static char *_print = 0;
24 static char *_attribute = 0;
25 static int print_filenames = 0;
27 static void free_and_exit(int i);
29 #define SHOW_NOVAL(opt) \
31 printf("option '%s' requires a value\n\n", (opt)); \
38 printf("usage: xmlgrep [options] [file ...]\n\n");
40 printf("\t-h\t\tshow this help message\n");
41 printf("\t-a <string>\tprint this attribute as the output\n");
42 printf("\t-e <id>\t\tshow sections that contain this element\n");
43 printf("\t-p <id>\t\tprint this element as the output\n");
44 printf("\t-r <path>\tspecify the XML search root\n");
45 printf("\t-v <string>\tfilter sections that contain this vale\n\n");
46 printf(" To print the contents of the 'type' element of the XML section ");
47 printf("that begins\n at '/printer/output' use the following command:\n\n");
48 printf("\txmlgrep -r /printer/output -p type sample.xml\n\n");
49 printf(" To filter 'output' elements under '/printer' that have attribute");
50 printf(" 'n' set to '1'\n use the following command:\n\n");
51 printf("\txmlgrep -r /printer -p output -a n -v 1 sample.xml\n\n");
52 printf(" To filter out sections that contain the 'driver' element with ");
53 printf("'generic' as\n it's value use the following command:");
54 printf("\n\n\txmlgrep -r /printer/output -e driver -v generic sample.xml");
60 free_and_exit(int ret)
62 if (_root && _root != _static_root) free(_root);
63 if (_element && _element != _static_element) free(_element);
64 if (_value) free(_value);
65 if (_print) free(_print);
66 if (_attribute) free(_attribute);
70 for (i=0; i < _fcount; i++)
74 if (print_filenames) printf("%s\n", _filenames[i]);
85 parse_option(char **args, int n, int max)
88 unsigned int alen = 0;
92 if (strncmp(opt, "--", 2) == 0)
95 if ((arg = strchr(opt, '=')) != NULL)
103 if (arg && arg[0] == '-')
109 if (strncmp(opt, "-help", olen) == 0)
113 else if (strncmp(opt, "-root", olen) == 0)
115 if (arg == 0) SHOW_NOVAL(opt);
116 alen = strlen(arg)+1;
117 _root = malloc(alen);
118 memcpy(_root, arg, alen);
121 else if (strncmp(opt, "-element", olen) == 0)
123 if (arg == 0) SHOW_NOVAL(opt);
124 alen = strlen(arg)+1;
125 _element = malloc(alen);
126 memcpy(_element, arg, alen);
129 else if (strncmp(opt, "-value", olen) == 0)
131 if (arg == 0) SHOW_NOVAL(opt);
132 alen = strlen(arg)+1;
133 _value = malloc(alen);
134 memcpy(_value, arg, alen);
137 else if (strncmp(opt, "-print", olen) == 0)
139 if (arg == 0) SHOW_NOVAL(opt);
140 alen = strlen(arg)+1;
141 _print = malloc(alen);
142 memcpy(_print, arg, alen);
145 else if (strncmp(opt, "-attribute", olen) == 0)
147 if (arg == 0) SHOW_NOVAL(opt);
148 alen = strlen(arg)+1;
149 _attribute = malloc(alen);
150 memcpy(_attribute, arg, alen);
153 else if (strncmp(opt, "-list-filenames", olen) == 0)
154 { /* undocumented test argument */
158 else if (opt[0] == '-')
160 printf("Unknown option %s\n", opt);
168 _filenames = (char **)malloc(sizeof(char*));
172 char **ptr = (char **)realloc(_filenames, _fcount*sizeof(char*));
175 printf("Out of memory.\n\n");
181 alen = strlen(opt)+1;
182 _filenames[pos] = malloc(alen);
183 memcpy(_filenames[pos], opt, alen);
189 void walk_the_tree(size_t num, void *xid, char *tree)
191 unsigned int i, no_elements;
193 if (!tree) /* last node from the tree */
195 void *xmid = xmlMarkId(xid);
198 no_elements = xmlNodeGetNum(xid, _print);
199 for (i=0; i<no_elements; i++)
201 if (xmlNodeGetPos(xid, xmid, _print, i) != 0)
205 xmlCopyString(xmid, (char *)&value, 1024);
206 if (_value && _attribute)
208 if (!xmlAttributeCompareString(xmid, _attribute, _value))
210 printf("%s: <%s %s=\"%s\">%s</%s>\n",
211 _filenames[num], _print, _attribute, _value,
217 printf("%s: <%s>%s</%s>\n",
218 _filenames[num], _print, value, _print);
224 else if (xmid && _value)
226 no_elements = xmlNodeGetNum(xmid, _element);
227 for (i=0; i<no_elements; i++)
229 if (xmlNodeGetPos(xid, xmid, _element, i) != 0)
233 xmlNodeCopyName(xmid, (char *)&nodename, 64);
234 if (xmlCompareString(xmid, _value) == 0)
236 printf("%s: <%s>%s</%s>\n",
237 _filenames[num], nodename, _value, nodename);
243 else if (xmid && _element)
247 xmlNodeCopyName(xid, (char *)&parentname, 64);
249 no_elements = xmlNodeGetNum(xmid, _element);
250 for (i=0; i<no_elements; i++)
252 if (xmlNodeGetPos(xid, xmid, _element, i) != 0)
256 xmlNodeCopyName(xmid, (char *)&nodename, 64);
257 if (strncasecmp((char *)&nodename, _element, 64) == 0)
260 xmlCopyString(xmid, (char *)&value, 64);
261 printf("%s: <%s> <%s>%s</%s> </%s>\n",
262 _filenames[num], parentname, nodename, value,
263 nodename, parentname);
268 else printf("Error executing xmlMarkId\n");
270 else if (xid) /* walk the rest of the tree */
276 if (*elem == '/') elem++;
278 next = strchr(elem, '/');
280 xmid = xmlMarkId(xid);
288 no_elements = xmlNodeGetNum(xid, elem);
289 for (i=0; i<no_elements; i++)
291 if (xmlNodeGetPos(xid, xmid, elem, i) != 0)
292 walk_the_tree(num, xmid, next);
302 else printf("Error executing xmlMarkId\n");
307 void grep_file(unsigned num)
311 xid = xmlOpen(_filenames[num]);
314 void *xrid = xmlMarkId(xid);
318 walk_the_tree(num, xrid, _root);
320 s = xmlErrorGetString(xrid);
321 n = xmlErrorGetLineNo(xrid);
322 r = xmlErrorGetNo(xrid);
323 if (r) printf("Error #%i at line #%u: '%s'\n", r, n, s);
329 fprintf(stderr, "Error reading file '%s'\n", _filenames[num]);
336 main (int argc, char **argv)
345 int ret = parse_option(argv, i, argc);
349 if (_root == 0) _root = (char *)_static_root;
350 if (_element == 0) _element = (char *)_static_element;
352 for (i=0; i<_fcount; i++)