summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Straz <nstraz@redhat.com>2008-08-04 17:43:36 -0400
committerNathan Straz <nstraz@redhat.com>2008-08-04 17:43:36 -0400
commitb24a04e34392574cdab78bab048bdd73fd86997d (patch)
tree69238d02298d4e767f9c764d42c362f1d603bfa8
parente01f689aa62ec343670bfdea5235c919666d4aba (diff)
downloadgxpp-b24a04e34392574cdab78bab048bdd73fd86997d.tar.gz
gxpp-b24a04e34392574cdab78bab048bdd73fd86997d.tar.xz
gxpp-b24a04e34392574cdab78bab048bdd73fd86997d.zip
Add gxpd to remove sections from XML files.
-rw-r--r--Makefile8
-rw-r--r--gxpd.153
-rw-r--r--gxpd.c131
-rw-r--r--gxpp.12
4 files changed, 189 insertions, 5 deletions
diff --git a/Makefile b/Makefile
index 1aa1d9f..b82aecc 100644
--- a/Makefile
+++ b/Makefile
@@ -1,12 +1,12 @@
-TARGETS := gxpp
+TARGETS := gxpp gxpd
all: $(TARGETS)
CFLAGS := -Wall -g
-gxpp: gxp-int.c
-gxpp: CFLAGS += -I/usr/include/libxml2
-gxpp: LOADLIBES := -lxml2
+$(TARGETS): gxp-int.c
+$(TARGETS): CFLAGS += -I/usr/include/libxml2
+$(TARGETS): LOADLIBES := -lxml2
install: all
for i in $(TARGETS); do \
diff --git a/gxpd.1 b/gxpd.1
new file mode 100644
index 0000000..9eb619c
--- /dev/null
+++ b/gxpd.1
@@ -0,0 +1,53 @@
+.TH GXPD 1 "4 Aug 2008"
+.SH NAME
+gxpd \- Delete sections of XML documents using XPath expressions
+.SH SYNOPSIS
+\fBgxpd\fR [\fIoptions\fR] \fIXPATH\fR [\fIFILE\fR...]
+.SH DESCRIPTION
+
+.B Gxpd
+deletes sections from the specified XML files and saves the result in-place,
+or removes the sections from a document parsed from standard input and prints
+it to standard output.
+
+.SH ARGUMENTS
+
+.TP
+.BI \-p " PRE"
+The prefix to use in the XPath expression to match the default XML
+name space in the document. XPath 1.0 does not define a way to match
+the default name space when an XML document contains XML name spaces.
+By specifying a default name space prefix here, you can match on the
+default prefix in the document.
+
+.SH EXAMPLES
+.nf
+.B Example document
+<A>
+ <B name="foo">
+ <C>C of foo</C>
+ </B>
+ <B name="bar">
+ <C>C of bar</C>
+ </B>
+ <B name="baz">
+ <C>C of baz</C>
+ </B>
+</A>
+
+.B # gxpd "/A/B[@name='baz']" example.xml
+Removed 1 nodes
+.B # cat example.xml
+<?xml version="1.0"?>
+<A>
+ <B name="foo">
+ <C>C of foo</C>
+ </B>
+ <B name="bar">
+ <C>C of bar</C>
+ </B>
+
+</A>
+
+.SH "SEE ALSO"
+gxpp(1), http://www.w3.org/TR/xpath
diff --git a/gxpd.c b/gxpd.c
new file mode 100644
index 0000000..ecd0ff6
--- /dev/null
+++ b/gxpd.c
@@ -0,0 +1,131 @@
+/*
+ * gxpd.c -- Simple XPath Delete Util
+ *
+ * Copyright © 2006-2007 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 <nstraz@redhat.com>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+#include <libxml/xinclude.h>
+
+#include "gxp-int.h"
+
+static void usage(const char *pname);
+static int gxpd(char *fn, const char *xpath_query, const char *prefix);
+
+int
+main(int argc, char **argv)
+{
+ 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);
+ }
+
+ optind++;
+ if (!argv[optind]) {
+ /* No files given, filter stdin to stdout */
+ gxpd("-", xpath_query, prefix);
+ } 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 */
+ gxpd(argv[c], xpath_query, prefix);
+ }
+ }
+ return 0;
+}
+
+static int
+gxpd(char *fn, const char *xpath_query, const char *prefix)
+{
+ 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++) {
+ xmlUnlinkNode(obj->nodesetval->nodeTab[i]);
+ xmlFreeNode(obj->nodesetval->nodeTab[i]);
+ }
+ printf("Removed %d nodes\n", i);
+
+ xmlXPathFreeObject(obj);
+ xmlSaveFile(fn, doc);
+
+ xmlXPathFreeContext(ctx);
+ xmlFreeDoc(doc);
+
+ return 0;
+}
+
+
+static void
+usage(const char *pname)
+{
+ fprintf(stderr,"%s [OPTION]... XPATH [FILE]...\n", pname);
+ fprintf(stderr,"Options:\n"
+ "-p prefix Set prefix for default namespace\n");
+ return;
+}
+
diff --git a/gxpp.1 b/gxpp.1
index 70c8d27..7c7f9b5 100644
--- a/gxpp.1
+++ b/gxpp.1
@@ -87,4 +87,4 @@ C of baz
.fi
.SH "SEE ALSO"
-xpm(1), grep(1), http://www.w3.org/TR/xpath
+gxpd(1), grep(1), http://www.w3.org/TR/xpath