X-Git-Url: https://git.liburcu.org/?a=blobdiff_plain;f=tests%2Fregression%2Ftools%2Fmi%2Fextract_xml.c;fp=tests%2Fregression%2Ftools%2Fmi%2Fextract_xml.c;h=724e005f4e128da61c4ff41cc2ff7a5374581e06;hb=68270f0f604eefdc89583950a7cfa02fe7a0cab5;hp=0000000000000000000000000000000000000000;hpb=99e88aea851afcb1c9388469c68c7e1fe2b8982a;p=lttng-tools.git diff --git a/tests/regression/tools/mi/extract_xml.c b/tests/regression/tools/mi/extract_xml.c new file mode 100644 index 000000000..724e005f4 --- /dev/null +++ b/tests/regression/tools/mi/extract_xml.c @@ -0,0 +1,227 @@ +/* + * Copyright (C) 2014 - Jonathan Rajotte + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License, version 2 only, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + */ + +/* + * Usage: extract_xml [-v] xml_path xpath_expression + * Evaluate XPath expression and prints result node set. + * args[1] path to the xml file + * args[2] xpath expression to extract + * If -v is set the name of the node will appear with his value delimited by + * a semicolon(;) + * Ex: + * Command:extract_xml ../file.xml /test/node/text() + * Output: + * a + * b + * c + * With -v + * node;a; + * node;b; + * node;c; + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#if defined(LIBXML_XPATH_ENABLED) + + +int opt_verbose; +/** + * print_xpath_nodes: + * nodes: the nodes set. + * output: the output file handle. + * + * Print the node content to the file + */ +static int print_xpath_nodes(xmlDocPtr doc, xmlNodeSetPtr nodes, FILE *output) +{ + int ret; + int size; + int i; + + xmlNodePtr cur; + xmlChar *node_child_value_string = NULL; + + assert(output); + size = (nodes) ? nodes->nodeNr : 0; + + for (i = 0; i < size; ++i) { + assert(nodes->nodeTab[i]); + + if (nodes->nodeTab[i]->type == XML_NAMESPACE_DECL) { + fprintf(stderr, "ERR:%s\n", + "This executable does not support xml namespacing\n"); + ret = -1; + goto end; + } else if (nodes->nodeTab[i]->type == XML_ELEMENT_NODE) { + cur = nodes->nodeTab[i]; + + if (xmlChildElementCount(cur) == 0) { + if (xmlNodeIsText(cur->children)) { + node_child_value_string = xmlNodeListGetString(doc, + cur->children, 1); + if (opt_verbose) { + fprintf(output, "%s;%s;\n", cur->name, + node_child_value_string); + } else { + fprintf(output, "%s\n", + node_child_value_string); + } + xmlFree(node_child_value_string); + } else { + /* We don't want to print non-final element */ + fprintf(stderr, "ERR:%s\n", + "Xpath expression return non-final xml element"); + ret = -1; + goto end; + } + } else { + /* We don't want to print non-final element */ + fprintf(stderr, "ERR:%s\n", + "Xpath expression return non-final xml element"); + ret = -1; + goto end; + } + + } else { + cur = nodes->nodeTab[i]; + if (opt_verbose) { + fprintf(output, "%s;%s;\n", cur->parent->name, cur->content); + } else { + fprintf(output, "%s\n", cur->content); + + } + } + } + /* Command Success */ + ret = 0; + +end: + return ret; +} + +/* + * Extract element corresponding to xpath + * xml_path The path to the xml file + * xpath: The xpath to evaluate. + * + * Evaluate an xpath expression onto an xml file. + * and print the result one by line. + * + * Returns 0 on success and a negative value otherwise. + */ +static int extract_xpath(const char *xml_path, const xmlChar *xpath) +{ + xmlDocPtr doc = NULL; + xmlXPathContextPtr xpathCtx = NULL; + xmlXPathObjectPtr xpathObj = NULL; + + assert(xml_path); + assert(xpath); + + /* Parse the xml file */ + doc = xmlParseFile(xml_path); + if (!doc) { + fprintf(stderr, "ERR parsing: xml file invalid \"%s\"\n", xml_path); + return -1; + } + + /* Initialize a xpath context */ + xpathCtx = xmlXPathNewContext(doc); + if (!xpathCtx) { + fprintf(stderr, "ERR: XPath context invalid\n"); + xmlFreeDoc(doc); + return -1; + } + + /* Evaluate xpath expression */ + xpathObj = xmlXPathEvalExpression(xpath, xpathCtx); + if (!xpathObj) { + fprintf(stderr, "ERR: invalid xpath expression \"%s\"\n", xpath); + xmlXPathFreeContext(xpathCtx); + xmlFreeDoc(doc); + return -1; + } + + /* Print results */ + if (print_xpath_nodes(doc, xpathObj->nodesetval, stdout)) { + xmlXPathFreeObject(xpathObj); + xmlXPathFreeContext(xpathCtx); + xmlFreeDoc(doc); + return -1; + } + + /* Cleanup */ + xmlXPathFreeObject(xpathObj); + xmlXPathFreeContext(xpathCtx); + xmlFreeDoc(doc); + + return 0; +} + +int main(int argc, char **argv) +{ + int opt; + + /* Parse command line and process file */ + while ((opt = getopt(argc, argv, "v")) != -1) { + switch (opt) { + case 'v': + opt_verbose = 1; + break; + default: + abort(); + } + } + + if (!(optind + 1 < argc)) { + fprintf(stderr, "ERR:%s\n", "Arguments missing"); + return -1; + } + + /* Init libxml */ + xmlInitParser(); + xmlKeepBlanksDefault(0); + if (access(argv[optind], F_OK)) { + fprintf(stderr, "ERR:%s\n", "Xml path not valid"); + return -1; + } + /* Do the main job */ + if (extract_xpath(argv[optind], (xmlChar *)argv[optind+1])) { + return -1; + } + + /* Shutdown libxml */ + xmlCleanupParser(); + + return 0; +} + +#else +int main(void) +{ + fprintf(stderr, "XPath support not compiled in\n"); + return -1; +} +#endif