Backport: trackers: tests: adapt tests to new xsd schemas
[lttng-tools.git] / tests / regression / tools / mi / extract_xml.c
CommitLineData
68270f0f
JRJ
1/*
2 * Copyright (C) 2014 - Jonathan Rajotte <jonathan.r.julien@gmail.com>
3 *
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.
7 *
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
11 * more details.
12 *
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
15 */
16
17/*
71f82f2b 18 * Usage: extract_xml [-v|-e] xml_path xpath_expression
68270f0f
JRJ
19 * Evaluate XPath expression and prints result node set.
20 * args[1] path to the xml file
21 * args[2] xpath expression to extract
71f82f2b 22 * If -e look if node exist return "true" else nothing
68270f0f
JRJ
23 * If -v is set the name of the node will appear with his value delimited by
24 * a semicolon(;)
25 * Ex:
26 * Command:extract_xml ../file.xml /test/node/text()
27 * Output:
28 * a
29 * b
30 * c
31 * With -v
32 * node;a;
33 * node;b;
34 * node;c;
35 */
36#include <stdlib.h>
37#include <stdio.h>
40f1bcbe 38#include <stdbool.h>
68270f0f
JRJ
39#include <string.h>
40#include <assert.h>
41#include <unistd.h>
42
43#include <libxml/tree.h>
44#include <libxml/parser.h>
45#include <libxml/xpath.h>
46#include <libxml/xpathInternals.h>
41af1adf 47#include <common/defaults.h>
68270f0f
JRJ
48
49#if defined(LIBXML_XPATH_ENABLED)
50
51
40f1bcbe
MD
52static int opt_verbose;
53static int node_exist;
54static bool result = false;
71f82f2b 55
68270f0f
JRJ
56/**
57 * print_xpath_nodes:
58 * nodes: the nodes set.
59 * output: the output file handle.
60 *
61 * Print the node content to the file
62 */
63static int print_xpath_nodes(xmlDocPtr doc, xmlNodeSetPtr nodes, FILE *output)
64{
71f82f2b 65 int ret = 0;
68270f0f
JRJ
66 int size;
67 int i;
68
69 xmlNodePtr cur;
70 xmlChar *node_child_value_string = NULL;
71
72 assert(output);
73 size = (nodes) ? nodes->nodeNr : 0;
74
75 for (i = 0; i < size; ++i) {
76 assert(nodes->nodeTab[i]);
77
78 if (nodes->nodeTab[i]->type == XML_NAMESPACE_DECL) {
79 fprintf(stderr, "ERR:%s\n",
80 "This executable does not support xml namespacing\n");
81 ret = -1;
82 goto end;
83 } else if (nodes->nodeTab[i]->type == XML_ELEMENT_NODE) {
84 cur = nodes->nodeTab[i];
85
86 if (xmlChildElementCount(cur) == 0) {
87 if (xmlNodeIsText(cur->children)) {
88 node_child_value_string = xmlNodeListGetString(doc,
89 cur->children, 1);
71f82f2b 90 if (node_exist) {
40f1bcbe 91 result = true;
71f82f2b 92 } else if (opt_verbose) {
68270f0f
JRJ
93 fprintf(output, "%s;%s;\n", cur->name,
94 node_child_value_string);
95 } else {
96 fprintf(output, "%s\n",
97 node_child_value_string);
98 }
99 xmlFree(node_child_value_string);
71f82f2b
JR
100 } else {
101 /* We don't want to print non-final element */
102 if (node_exist) {
40f1bcbe 103 result = true;
71f82f2b
JR
104 } else {
105 fprintf(stderr, "ERR:%s\n",
106 "Xpath expression return non-final xml element");
107 ret = -1;
108 goto end;
109 }
110 }
111 } else {
112 if (node_exist) {
40f1bcbe 113 result = true;
68270f0f
JRJ
114 } else {
115 /* We don't want to print non-final element */
116 fprintf(stderr, "ERR:%s\n",
117 "Xpath expression return non-final xml element");
118 ret = -1;
119 goto end;
120 }
68270f0f
JRJ
121 }
122
123 } else {
124 cur = nodes->nodeTab[i];
71f82f2b 125 if (node_exist) {
40f1bcbe 126 result = true;
71f82f2b 127 } else if (opt_verbose) {
68270f0f
JRJ
128 fprintf(output, "%s;%s;\n", cur->parent->name, cur->content);
129 } else {
130 fprintf(output, "%s\n", cur->content);
68270f0f
JRJ
131 }
132 }
133 }
134 /* Command Success */
135 ret = 0;
136
137end:
138 return ret;
139}
140
41af1adf
JG
141static int register_lttng_namespace(xmlXPathContextPtr xpathCtx)
142{
143 int ret;
144 xmlChar *prefix;
145 xmlChar *ns = NULL;
146
147 prefix = xmlCharStrdup("lttng");
148 if (!prefix) {
149 ret = -1;
150 goto end;
151 }
152
153 ns = xmlCharStrdup(DEFAULT_LTTNG_MI_NAMESPACE);
154 if (!ns) {
155 ret = -1;
156 goto end;
157 }
158
159 ret = xmlXPathRegisterNs(xpathCtx, prefix, ns);
160 xmlFree(prefix);
161end:
162 xmlFree(ns);
163 return ret;
164}
165
68270f0f
JRJ
166/*
167 * Extract element corresponding to xpath
168 * xml_path The path to the xml file
169 * xpath: The xpath to evaluate.
170 *
171 * Evaluate an xpath expression onto an xml file.
172 * and print the result one by line.
173 *
174 * Returns 0 on success and a negative value otherwise.
175 */
176static int extract_xpath(const char *xml_path, const xmlChar *xpath)
177{
41af1adf 178 int ret;
68270f0f
JRJ
179 xmlDocPtr doc = NULL;
180 xmlXPathContextPtr xpathCtx = NULL;
181 xmlXPathObjectPtr xpathObj = NULL;
182
183 assert(xml_path);
184 assert(xpath);
185
186 /* Parse the xml file */
187 doc = xmlParseFile(xml_path);
188 if (!doc) {
189 fprintf(stderr, "ERR parsing: xml file invalid \"%s\"\n", xml_path);
190 return -1;
191 }
192
193 /* Initialize a xpath context */
194 xpathCtx = xmlXPathNewContext(doc);
195 if (!xpathCtx) {
196 fprintf(stderr, "ERR: XPath context invalid\n");
197 xmlFreeDoc(doc);
198 return -1;
199 }
200
41af1adf
JG
201 /* Register the LTTng MI namespace */
202 ret = register_lttng_namespace(xpathCtx);
203 if (ret) {
204 fprintf(stderr, "ERR: Could not register lttng namespace\n");
205 xmlXPathFreeContext(xpathCtx);
206 xmlFreeDoc(doc);
207 return -1;
208 }
209
68270f0f
JRJ
210 /* Evaluate xpath expression */
211 xpathObj = xmlXPathEvalExpression(xpath, xpathCtx);
212 if (!xpathObj) {
213 fprintf(stderr, "ERR: invalid xpath expression \"%s\"\n", xpath);
214 xmlXPathFreeContext(xpathCtx);
215 xmlFreeDoc(doc);
216 return -1;
217 }
218
219 /* Print results */
220 if (print_xpath_nodes(doc, xpathObj->nodesetval, stdout)) {
221 xmlXPathFreeObject(xpathObj);
222 xmlXPathFreeContext(xpathCtx);
223 xmlFreeDoc(doc);
224 return -1;
225 }
40f1bcbe
MD
226 if (node_exist && result) {
227 fprintf(stdout, "true\n");
228 }
68270f0f
JRJ
229
230 /* Cleanup */
231 xmlXPathFreeObject(xpathObj);
232 xmlXPathFreeContext(xpathCtx);
233 xmlFreeDoc(doc);
234
235 return 0;
236}
237
238int main(int argc, char **argv)
239{
240 int opt;
241
242 /* Parse command line and process file */
71f82f2b 243 while ((opt = getopt(argc, argv, "ve")) != -1) {
68270f0f
JRJ
244 switch (opt) {
245 case 'v':
246 opt_verbose = 1;
247 break;
71f82f2b
JR
248 case 'e':
249 node_exist = 1;
250 break;
68270f0f
JRJ
251 default:
252 abort();
253 }
254 }
255
256 if (!(optind + 1 < argc)) {
257 fprintf(stderr, "ERR:%s\n", "Arguments missing");
258 return -1;
259 }
260
261 /* Init libxml */
262 xmlInitParser();
263 xmlKeepBlanksDefault(0);
264 if (access(argv[optind], F_OK)) {
265 fprintf(stderr, "ERR:%s\n", "Xml path not valid");
266 return -1;
267 }
268 /* Do the main job */
269 if (extract_xpath(argv[optind], (xmlChar *)argv[optind+1])) {
270 return -1;
271 }
272
273 /* Shutdown libxml */
274 xmlCleanupParser();
275
276 return 0;
277}
278
279#else
280int main(void)
281{
282 fprintf(stderr, "XPath support not compiled in\n");
283 return -1;
284}
285#endif
This page took 0.062296 seconds and 5 git commands to generate.