/* * gxpm.c -- Simple XPath Merge Util * * Copyright © 2006-2008 Red Hat, Inc. All rights reserved. * * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions of the * GNU General Public License v.2. This program is distributed in the hope * that it will be useful, but WITHOUT ANY WARRANTY expressed or implied, * including the implied warranties 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 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat * trademarks that are incorporated in the source code or documentation are not * subject to the GNU General Public License and may only be used or replicated * with the express permission of Red Hat, Inc. * * Red Hat Author(s): Nathan Straz */ #include #include #include #include #include #include #include #include #include #include #include "gxp-int.h" static void usage(const char *pname); static int gxpm(char *fn, const char *xpath_query, const char *prefix, xmlDocPtr snip); int main(int argc, char **argv) { xmlDocPtr snip; char *xpath_query = NULL; char *prefix = NULL; int c; while ((c = getopt(argc, argv, "+p:h")) != -1) { switch (c) { case 'p': prefix = strdup(optarg); break; case 'h': case '?': usage(argv[0]); exit(2); break; } } xpath_query = argv[optind]; if (!xpath_query) { fprintf(stderr, "Missing XPath Query\n"); usage(argv[0]); exit(2); } if (!(snip = xmlReadFd(fileno(stdin), NULL, NULL, 0))) { fprintf(stderr, "Failed to parse XML snippet on standard input\n"); exit(1); } optind++; if (!argv[optind]) { /* No files given, filter stdin to stdout */ gxpm("-", xpath_query, prefix, snip); } else { /* Rest of the args are the files to change */ #if 0 if (((argc - optind) > 1) && (!gxpp_opts.omitfileprefix)) gxpp_opts.addfileprefix = 1; #endif for (c = optind; c < argc; c++) { /* Make sure we can write to the file */ gxpm(argv[c], xpath_query, prefix, snip); } } xmlFreeDoc(snip); return 0; } static int gxpm(char *fn, const char *xpath_query, const char *prefix, xmlDocPtr snip) { xmlDocPtr doc; xmlXPathContextPtr ctx; xmlXPathObjectPtr obj; int i; if (!(doc = xmlParseFile(fn))) { fprintf(stderr, "Failed to parse XML file\n"); exit(1); } /* xmlXIncludeProcess(doc); */ ctx = generate_context(doc, prefix); obj = xmlXPathEvalExpression((xmlChar *)xpath_query, ctx); if (!obj) { fprintf(stderr, "XPath expression '%s' did not match in '%s'\n", xpath_query, fn); exit(1); } if (obj->type != XPATH_NODESET) { fprintf(stderr, "XPath expression '%s' did not match a nodeset.\n", xpath_query); exit(1); } for (i = 0; i < obj->nodesetval->nodeNr; i++) { xmlAddChild(obj->nodesetval->nodeTab[i], xmlCopyNode(xmlDocGetRootElement(snip), 1)); } xmlXPathFreeObject(obj); xmlXPathFreeContext(ctx); xmlSaveFile(fn, doc); xmlFreeDoc(doc); return 0; } static void usage(const char *pname) { fprintf(stderr,"%s [OPTION]... XPATH [FILE]... < XML\n", pname); fprintf(stderr,"Options:\n" "-p prefix Set prefix for default namespace\n"); return; }