2 * Copyright (C) 2014 - Jonathan Rajotte <jonathan.r.julien@gmail.com>
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License, version 2 only, as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 51
18 * Usage: extract_xml [-v|-e] xml_path xpath_expression
19 * Evaluate XPath expression and prints result node set.
20 * args[1] path to the xml file
21 * args[2] xpath expression to extract
22 * If -e look if node exist return "true" else nothing
23 * If -v is set the name of the node will appear with his value delimited by
26 * Command:extract_xml ../file.xml /test/node/text()
42 #include <libxml/tree.h>
43 #include <libxml/parser.h>
44 #include <libxml/xpath.h>
45 #include <libxml/xpathInternals.h>
46 #include <common/defaults.h>
48 #if defined(LIBXML_XPATH_ENABLED)
56 * nodes: the nodes set.
57 * output: the output file handle.
59 * Print the node content to the file
61 static int print_xpath_nodes(xmlDocPtr doc
, xmlNodeSetPtr nodes
, FILE *output
)
68 xmlChar
*node_child_value_string
= NULL
;
71 size
= (nodes
) ? nodes
->nodeNr
: 0;
73 for (i
= 0; i
< size
; ++i
) {
74 assert(nodes
->nodeTab
[i
]);
76 if (nodes
->nodeTab
[i
]->type
== XML_NAMESPACE_DECL
) {
77 fprintf(stderr
, "ERR:%s\n",
78 "This executable does not support xml namespacing\n");
81 } else if (nodes
->nodeTab
[i
]->type
== XML_ELEMENT_NODE
) {
82 cur
= nodes
->nodeTab
[i
];
84 if (xmlChildElementCount(cur
) == 0) {
85 if (xmlNodeIsText(cur
->children
)) {
86 node_child_value_string
= xmlNodeListGetString(doc
,
89 fprintf(output
, "true\n");
90 } else if (opt_verbose
) {
91 fprintf(output
, "%s;%s;\n", cur
->name
,
92 node_child_value_string
);
94 fprintf(output
, "%s\n",
95 node_child_value_string
);
97 xmlFree(node_child_value_string
);
99 /* We don't want to print non-final element */
101 fprintf(output
, "true\n");
103 fprintf(stderr
, "ERR:%s\n",
104 "Xpath expression return non-final xml element");
111 fprintf(output
, "true\n");
113 /* We don't want to print non-final element */
114 fprintf(stderr
, "ERR:%s\n",
115 "Xpath expression return non-final xml element");
122 cur
= nodes
->nodeTab
[i
];
124 fprintf(output
, "true\n");
125 } else if (opt_verbose
) {
126 fprintf(output
, "%s;%s;\n", cur
->parent
->name
, cur
->content
);
128 fprintf(output
, "%s\n", cur
->content
);
132 /* Command Success */
139 static int register_lttng_namespace(xmlXPathContextPtr xpathCtx
)
145 prefix
= xmlCharStrdup("lttng");
151 ns
= xmlCharStrdup(DEFAULT_LTTNG_MI_NAMESPACE
);
157 ret
= xmlXPathRegisterNs(xpathCtx
, prefix
, ns
);
165 * Extract element corresponding to xpath
166 * xml_path The path to the xml file
167 * xpath: The xpath to evaluate.
169 * Evaluate an xpath expression onto an xml file.
170 * and print the result one by line.
172 * Returns 0 on success and a negative value otherwise.
174 static int extract_xpath(const char *xml_path
, const xmlChar
*xpath
)
177 xmlDocPtr doc
= NULL
;
178 xmlXPathContextPtr xpathCtx
= NULL
;
179 xmlXPathObjectPtr xpathObj
= NULL
;
184 /* Parse the xml file */
185 doc
= xmlParseFile(xml_path
);
187 fprintf(stderr
, "ERR parsing: xml file invalid \"%s\"\n", xml_path
);
191 /* Initialize a xpath context */
192 xpathCtx
= xmlXPathNewContext(doc
);
194 fprintf(stderr
, "ERR: XPath context invalid\n");
199 /* Register the LTTng MI namespace */
200 ret
= register_lttng_namespace(xpathCtx
);
202 fprintf(stderr
, "ERR: Could not register lttng namespace\n");
203 xmlXPathFreeContext(xpathCtx
);
208 /* Evaluate xpath expression */
209 xpathObj
= xmlXPathEvalExpression(xpath
, xpathCtx
);
211 fprintf(stderr
, "ERR: invalid xpath expression \"%s\"\n", xpath
);
212 xmlXPathFreeContext(xpathCtx
);
218 if (print_xpath_nodes(doc
, xpathObj
->nodesetval
, stdout
)) {
219 xmlXPathFreeObject(xpathObj
);
220 xmlXPathFreeContext(xpathCtx
);
226 xmlXPathFreeObject(xpathObj
);
227 xmlXPathFreeContext(xpathCtx
);
233 int main(int argc
, char **argv
)
237 /* Parse command line and process file */
238 while ((opt
= getopt(argc
, argv
, "ve")) != -1) {
251 if (!(optind
+ 1 < argc
)) {
252 fprintf(stderr
, "ERR:%s\n", "Arguments missing");
258 xmlKeepBlanksDefault(0);
259 if (access(argv
[optind
], F_OK
)) {
260 fprintf(stderr
, "ERR:%s\n", "Xml path not valid");
263 /* Do the main job */
264 if (extract_xpath(argv
[optind
], (xmlChar
*)argv
[optind
+1])) {
268 /* Shutdown libxml */
277 fprintf(stderr
, "XPath support not compiled in\n");