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