[PATCH 26/28] Rename xml.{c,h} to virxml.{c,h}

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: "Daniel P. Berrange" <berrange@xxxxxxxxxx>

---
 cfg.mk                               |   2 +-
 po/POTFILES.in                       |   2 +-
 src/Makefile.am                      |   2 +-
 src/conf/cpu_conf.h                  |   2 +-
 src/conf/device_conf.c               |   2 +-
 src/conf/domain_conf.c               |   2 +-
 src/conf/interface_conf.c            |   2 +-
 src/conf/netdev_bandwidth_conf.h     |   2 +-
 src/conf/netdev_vlan_conf.h          |   2 +-
 src/conf/netdev_vport_profile_conf.h |   2 +-
 src/conf/network_conf.c              |   2 +-
 src/conf/node_device_conf.c          |   2 +-
 src/conf/nwfilter_conf.h             |   2 +-
 src/conf/secret_conf.c               |   2 +-
 src/conf/snapshot_conf.c             |   2 +-
 src/conf/storage_conf.c              |   2 +-
 src/conf/storage_encryption_conf.c   |   2 +-
 src/cpu/cpu.c                        |   2 +-
 src/cpu/cpu_map.h                    |   2 +-
 src/esx/esx_vi.c                     |   2 +-
 src/qemu/qemu_conf.c                 |   2 +-
 src/qemu/qemu_driver.c               |   2 +-
 src/security/virt-aa-helper.c        |   2 +-
 src/storage/storage_backend_fs.c     |   2 +-
 src/test/test_driver.c               |   2 +-
 src/util/virxml.c                    | 890 +++++++++++++++++++++++++++++++++++
 src/util/virxml.h                    | 148 ++++++
 src/util/xml.c                       | 890 -----------------------------------
 src/util/xml.h                       | 148 ------
 src/xen/xen_driver.c                 |   2 +-
 tests/cputest.c                      |   2 +-
 tests/nwfilterxml2xmltest.c          |   2 +-
 tests/sexpr2xmltest.c                |   2 +-
 tests/virshtest.c                    |   2 +-
 tests/xencapstest.c                  |   2 +-
 tools/virsh-domain-monitor.c         |   2 +-
 tools/virsh-domain.c                 |   2 +-
 tools/virsh-host.c                   |   2 +-
 tools/virsh-interface.c              |   2 +-
 tools/virsh-network.c                |   2 +-
 tools/virsh-nodedev.c                |   2 +-
 tools/virsh-nwfilter.c               |   2 +-
 tools/virsh-pool.c                   |   2 +-
 tools/virsh-secret.c                 |   2 +-
 tools/virsh-snapshot.c               |   2 +-
 tools/virsh-volume.c                 |   2 +-
 tools/virsh.c                        |   2 +-
 47 files changed, 1081 insertions(+), 1081 deletions(-)
 create mode 100644 src/util/virxml.c
 create mode 100644 src/util/virxml.h
 delete mode 100644 src/util/xml.c
 delete mode 100644 src/util/xml.h

diff --git a/cfg.mk b/cfg.mk
index a269f77..2fcb444 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -809,7 +809,7 @@ exclude_file_name_regexp--sc_prohibit_strncpy = ^src/util/virutil\.c$$
 exclude_file_name_regexp--sc_prohibit_strtol = \
   ^src/(util/virsexpr|(vbox|xen|xenxs)/.*)\.c$$
 
-exclude_file_name_regexp--sc_prohibit_xmlGetProp = ^src/util/xml\.c$$
+exclude_file_name_regexp--sc_prohibit_xmlGetProp = ^src/util/virxml\.c$$
 
 exclude_file_name_regexp--sc_prohibit_xmlURI = ^src/util/viruri\.c$$
 
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 8a24fd4..1afdca5 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -180,7 +180,7 @@ src/util/virtypedparam.c
 src/util/viruri.c
 src/util/virusb.c
 src/util/virutil.c
-src/util/xml.c
+src/util/virxml.c
 src/vbox/vbox_MSCOMGlue.c
 src/vbox/vbox_XPCOMCGlue.c
 src/vbox/vbox_driver.c
diff --git a/src/Makefile.am b/src/Makefile.am
index dd5a1bd..dddd162 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -85,7 +85,6 @@ UTIL_SOURCES =							\
 		util/virthreadwin32.h				\
 		util/virthreadpool.c util/virthreadpool.h	\
 		util/virtypedparam.c util/virtypedparam.h	\
-		util/xml.c util/xml.h				\
 		util/virterror.c util/virterror_internal.h	\
 		util/vircgroup.c util/vircgroup.h		\
 		util/virdbus.c util/virdbus.h			\
@@ -115,6 +114,7 @@ UTIL_SOURCES =							\
 		util/viruri.h util/viruri.c			\
 		util/virutil.c util/virutil.h			\
 		util/viruuid.c util/viruuid.h			\
+		util/virxml.c util/virxml.h			\
 		$(NULL)
 
 EXTRA_DIST += $(srcdir)/util/virkeymaps.h $(srcdir)/util/keymaps.csv \
diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h
index 7bec912..616d813 100644
--- a/src/conf/cpu_conf.h
+++ b/src/conf/cpu_conf.h
@@ -26,7 +26,7 @@
 
 # include "virutil.h"
 # include "virbuffer.h"
-# include "xml.h"
+# include "virxml.h"
 # include "virbitmap.h"
 
 # define VIR_CPU_VENDOR_ID_LENGTH 12
diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c
index ecfaf30..45ecb28 100644
--- a/src/conf/device_conf.c
+++ b/src/conf/device_conf.c
@@ -24,7 +24,7 @@
 #include "virterror_internal.h"
 #include "datatypes.h"
 #include "viralloc.h"
-#include "xml.h"
+#include "virxml.h"
 #include "viruuid.h"
 #include "virutil.h"
 #include "virbuffer.h"
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 2943fe3..a4f33ed 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -36,7 +36,7 @@
 #include "snapshot_conf.h"
 #include "viralloc.h"
 #include "verify.h"
-#include "xml.h"
+#include "virxml.h"
 #include "viruuid.h"
 #include "virutil.h"
 #include "virbuffer.h"
diff --git a/src/conf/interface_conf.c b/src/conf/interface_conf.c
index 6a53bda..3867274 100644
--- a/src/conf/interface_conf.c
+++ b/src/conf/interface_conf.c
@@ -28,7 +28,7 @@
 #include "interface_conf.h"
 
 #include "viralloc.h"
-#include "xml.h"
+#include "virxml.h"
 #include "viruuid.h"
 #include "virutil.h"
 #include "virbuffer.h"
diff --git a/src/conf/netdev_bandwidth_conf.h b/src/conf/netdev_bandwidth_conf.h
index 216a540..23aaaf3 100644
--- a/src/conf/netdev_bandwidth_conf.h
+++ b/src/conf/netdev_bandwidth_conf.h
@@ -26,7 +26,7 @@
 # include "internal.h"
 # include "virnetdevbandwidth.h"
 # include "virbuffer.h"
-# include "xml.h"
+# include "virxml.h"
 
 virNetDevBandwidthPtr virNetDevBandwidthParse(xmlNodePtr node,
                                               int net_type)
diff --git a/src/conf/netdev_vlan_conf.h b/src/conf/netdev_vlan_conf.h
index 19b50cc..480d6c6 100644
--- a/src/conf/netdev_vlan_conf.h
+++ b/src/conf/netdev_vlan_conf.h
@@ -25,7 +25,7 @@
 # include "internal.h"
 # include "virnetdevvlan.h"
 # include "virbuffer.h"
-# include "xml.h"
+# include "virxml.h"
 
 int virNetDevVlanParse(xmlNodePtr node, xmlXPathContextPtr ctxt, virNetDevVlanPtr def);
 int virNetDevVlanFormat(virNetDevVlanPtr def, virBufferPtr buf);
diff --git a/src/conf/netdev_vport_profile_conf.h b/src/conf/netdev_vport_profile_conf.h
index 15ecbd6..a70256d 100644
--- a/src/conf/netdev_vport_profile_conf.h
+++ b/src/conf/netdev_vport_profile_conf.h
@@ -26,7 +26,7 @@
 # include "internal.h"
 # include "virnetdevvportprofile.h"
 # include "virbuffer.h"
-# include "xml.h"
+# include "virxml.h"
 
 typedef enum {
     /* generate random defaults for interfaceID/interfaceID
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 01a6f2e..2bd04c5 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -38,7 +38,7 @@
 #include "netdev_bandwidth_conf.h"
 #include "netdev_vlan_conf.h"
 #include "viralloc.h"
-#include "xml.h"
+#include "virxml.h"
 #include "viruuid.h"
 #include "virutil.h"
 #include "virbuffer.h"
diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c
index 67d743e..3c68011 100644
--- a/src/conf/node_device_conf.c
+++ b/src/conf/node_device_conf.c
@@ -32,7 +32,7 @@
 
 #include "node_device_conf.h"
 #include "viralloc.h"
-#include "xml.h"
+#include "virxml.h"
 #include "virutil.h"
 #include "virbuffer.h"
 #include "viruuid.h"
diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h
index 2ca44b3..ca2c070 100644
--- a/src/conf/nwfilter_conf.h
+++ b/src/conf/nwfilter_conf.h
@@ -30,7 +30,7 @@
 
 # include "virutil.h"
 # include "virhash.h"
-# include "xml.h"
+# include "virxml.h"
 # include "virbuffer.h"
 # include "virsocketaddr.h"
 # include "virmacaddr.h"
diff --git a/src/conf/secret_conf.c b/src/conf/secret_conf.c
index 2abb95a..46d2ae5 100644
--- a/src/conf/secret_conf.c
+++ b/src/conf/secret_conf.c
@@ -30,7 +30,7 @@
 #include "secret_conf.h"
 #include "virterror_internal.h"
 #include "virutil.h"
-#include "xml.h"
+#include "virxml.h"
 #include "viruuid.h"
 
 #define VIR_FROM_THIS VIR_FROM_SECRET
diff --git a/src/conf/snapshot_conf.c b/src/conf/snapshot_conf.c
index 3ad74d6..f7f8f63 100644
--- a/src/conf/snapshot_conf.c
+++ b/src/conf/snapshot_conf.c
@@ -46,7 +46,7 @@
 #include "viruuid.h"
 #include "virfile.h"
 #include "virterror_internal.h"
-#include "xml.h"
+#include "virxml.h"
 
 #define VIR_FROM_THIS VIR_FROM_DOMAIN_SNAPSHOT
 
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c
index 4239e49..04b2581 100644
--- a/src/conf/storage_conf.c
+++ b/src/conf/storage_conf.c
@@ -38,7 +38,7 @@
 #include "storage_conf.h"
 #include "virstoragefile.h"
 
-#include "xml.h"
+#include "virxml.h"
 #include "viruuid.h"
 #include "virbuffer.h"
 #include "virutil.h"
diff --git a/src/conf/storage_encryption_conf.c b/src/conf/storage_encryption_conf.c
index 8ea54fa..35e9da4 100644
--- a/src/conf/storage_encryption_conf.c
+++ b/src/conf/storage_encryption_conf.c
@@ -32,7 +32,7 @@
 #include "storage_conf.h"
 #include "storage_encryption_conf.h"
 #include "virutil.h"
-#include "xml.h"
+#include "virxml.h"
 #include "virterror_internal.h"
 #include "viruuid.h"
 #include "virfile.h"
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index 2222a91..3e25f7d 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -25,7 +25,7 @@
 
 #include "virlog.h"
 #include "viralloc.h"
-#include "xml.h"
+#include "virxml.h"
 #include "cpu.h"
 #include "cpu_x86.h"
 #include "cpu_powerpc.h"
diff --git a/src/cpu/cpu_map.h b/src/cpu/cpu_map.h
index 9120513..8d27bcd 100644
--- a/src/cpu/cpu_map.h
+++ b/src/cpu/cpu_map.h
@@ -24,7 +24,7 @@
 #ifndef __VIR_CPU_MAP_H__
 # define __VIR_CPU_MAP_H__
 
-# include "xml.h"
+# include "virxml.h"
 
 
 enum cpuMapElement {
diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
index 92ac8f8..99c1eb1 100644
--- a/src/esx/esx_vi.c
+++ b/src/esx/esx_vi.c
@@ -32,7 +32,7 @@
 #include "virutil.h"
 #include "viruuid.h"
 #include "vmx.h"
-#include "xml.h"
+#include "virxml.h"
 #include "esx_vi.h"
 #include "esx_vi_methods.h"
 #include "esx_util.h"
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 8d05b4c..56c93a8 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -46,7 +46,7 @@
 #include "virutil.h"
 #include "viralloc.h"
 #include "datatypes.h"
-#include "xml.h"
+#include "virxml.h"
 #include "nodeinfo.h"
 #include "virlog.h"
 #include "cpu/cpu.h"
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 3821d74..d24527b 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -76,7 +76,7 @@
 #include "virusb.h"
 #include "virprocess.h"
 #include "libvirt_internal.h"
-#include "xml.h"
+#include "virxml.h"
 #include "cpu/cpu.h"
 #include "virsysinfo.h"
 #include "domain_nwfilter.h"
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index 3c15226..ffd3f71 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -48,7 +48,7 @@
 #include "security_driver.h"
 #include "security_apparmor.h"
 #include "domain_conf.h"
-#include "xml.h"
+#include "virxml.h"
 #include "viruuid.h"
 #include "virusb.h"
 #include "virpci.h"
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
index b744fb4..23fa0f5 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -47,7 +47,7 @@
 #include "virstoragefile.h"
 #include "vircommand.h"
 #include "viralloc.h"
-#include "xml.h"
+#include "virxml.h"
 #include "virfile.h"
 #include "virlog.h"
 
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 1a85eb3..bd557d6 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -46,7 +46,7 @@
 #include "domain_event.h"
 #include "storage_conf.h"
 #include "node_device_conf.h"
-#include "xml.h"
+#include "virxml.h"
 #include "virthread.h"
 #include "virlog.h"
 #include "virfile.h"
diff --git a/src/util/virxml.c b/src/util/virxml.c
new file mode 100644
index 0000000..02f7d1a
--- /dev/null
+++ b/src/util/virxml.c
@@ -0,0 +1,890 @@
+/*
+ * xml.c: XML based interfaces for the libvir library
+ *
+ * Copyright (C) 2005, 2007-2012 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Daniel Veillard <veillard@xxxxxxxxxx>
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <limits.h>
+#include <math.h>               /* for isnan() */
+#include <sys/stat.h>
+
+#include "virterror_internal.h"
+#include "virxml.h"
+#include "virbuffer.h"
+#include "virutil.h"
+#include "viralloc.h"
+#include "virfile.h"
+
+#define VIR_FROM_THIS VIR_FROM_XML
+
+#define virGenericReportError(from, code, ...)                          \
+        virReportErrorHelper(from, code, __FILE__,                      \
+                             __FUNCTION__, __LINE__, __VA_ARGS__)
+
+/* Internal data to be passed to SAX parser and used by error handler. */
+struct virParserData {
+    int domcode;
+};
+
+
+/************************************************************************
+ *									*
+ * Wrappers around libxml2 XPath specific functions			*
+ *									*
+ ************************************************************************/
+
+/**
+ * virXPathString:
+ * @xpath: the XPath string to evaluate
+ * @ctxt: an XPath context
+ *
+ * Convenience function to evaluate an XPath string
+ *
+ * Returns a new string which must be deallocated by the caller or NULL
+ *         if the evaluation failed.
+ */
+char *
+virXPathString(const char *xpath,
+               xmlXPathContextPtr ctxt)
+{
+    xmlXPathObjectPtr obj;
+    xmlNodePtr relnode;
+    char *ret;
+
+    if ((ctxt == NULL) || (xpath == NULL)) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       "%s", _("Invalid parameter to virXPathString()"));
+        return NULL;
+    }
+    relnode = ctxt->node;
+    obj = xmlXPathEval(BAD_CAST xpath, ctxt);
+    ctxt->node = relnode;
+    if ((obj == NULL) || (obj->type != XPATH_STRING) ||
+        (obj->stringval == NULL) || (obj->stringval[0] == 0)) {
+        xmlXPathFreeObject(obj);
+        return NULL;
+    }
+    ret = strdup((char *) obj->stringval);
+    xmlXPathFreeObject(obj);
+    if (ret == NULL) {
+        virReportOOMError();
+    }
+    return ret;
+}
+
+/**
+ * virXPathStringLimit:
+ * @xpath: the XPath string to evaluate
+ * @maxlen: maximum length permittred string
+ * @ctxt: an XPath context
+ *
+ * Wrapper for virXPathString, which validates the length of the returned
+ * string.
+ *
+ * Returns a new string which must be deallocated by the caller or NULL if
+ * the evaluation failed.
+ */
+char *
+virXPathStringLimit(const char *xpath,
+                    size_t maxlen,
+                    xmlXPathContextPtr ctxt)
+{
+    char *tmp = virXPathString(xpath, ctxt);
+
+    if (tmp != NULL && strlen(tmp) >= maxlen) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("\'%s\' value longer than %zu bytes"),
+                       xpath, maxlen);
+        VIR_FREE(tmp);
+        return NULL;
+    }
+
+    return tmp;
+}
+
+/**
+ * virXPathNumber:
+ * @xpath: the XPath string to evaluate
+ * @ctxt: an XPath context
+ * @value: the returned double value
+ *
+ * Convenience function to evaluate an XPath number
+ *
+ * Returns 0 in case of success in which case @value is set,
+ *         or -1 if the evaluation failed.
+ */
+int
+virXPathNumber(const char *xpath,
+               xmlXPathContextPtr ctxt,
+               double *value)
+{
+    xmlXPathObjectPtr obj;
+    xmlNodePtr relnode;
+
+    if ((ctxt == NULL) || (xpath == NULL) || (value == NULL)) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       "%s", _("Invalid parameter to virXPathNumber()"));
+        return -1;
+    }
+    relnode = ctxt->node;
+    obj = xmlXPathEval(BAD_CAST xpath, ctxt);
+    ctxt->node = relnode;
+    if ((obj == NULL) || (obj->type != XPATH_NUMBER) ||
+        (isnan(obj->floatval))) {
+        xmlXPathFreeObject(obj);
+        return -1;
+    }
+
+    *value = obj->floatval;
+    xmlXPathFreeObject(obj);
+    return 0;
+}
+
+static int
+virXPathLongBase(const char *xpath,
+                 xmlXPathContextPtr ctxt,
+                 int base,
+                 long *value)
+{
+    xmlXPathObjectPtr obj;
+    xmlNodePtr relnode;
+    int ret = 0;
+
+    if ((ctxt == NULL) || (xpath == NULL) || (value == NULL)) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       "%s", _("Invalid parameter to virXPathLong()"));
+        return -1;
+    }
+    relnode = ctxt->node;
+    obj = xmlXPathEval(BAD_CAST xpath, ctxt);
+    ctxt->node = relnode;
+    if ((obj != NULL) && (obj->type == XPATH_STRING) &&
+        (obj->stringval != NULL) && (obj->stringval[0] != 0)) {
+        if (virStrToLong_l((char *) obj->stringval, NULL, base, value) < 0)
+            ret = -2;
+    } else if ((obj != NULL) && (obj->type == XPATH_NUMBER) &&
+               (!(isnan(obj->floatval)))) {
+        *value = (long) obj->floatval;
+        if (*value != obj->floatval) {
+            ret = -2;
+        }
+    } else {
+        ret = -1;
+    }
+
+    xmlXPathFreeObject(obj);
+    return ret;
+}
+
+/**
+ * virXPathInt:
+ * @xpath: the XPath string to evaluate
+ * @ctxt: an XPath context
+ * @value: the returned int value
+ *
+ * Convenience function to evaluate an XPath number
+ *
+ * Returns 0 in case of success in which case @value is set,
+ *         or -1 if the XPath evaluation failed or -2 if the
+ *         value doesn't have an int format.
+ */
+int
+virXPathInt(const char *xpath,
+            xmlXPathContextPtr ctxt,
+            int *value)
+{
+    long tmp;
+    int ret;
+
+    ret = virXPathLongBase(xpath, ctxt, 10, &tmp);
+    if (ret < 0)
+        return ret;
+    if ((int) tmp != tmp)
+        return -2;
+    *value = tmp;
+    return 0;
+}
+
+/**
+ * virXPathLong:
+ * @xpath: the XPath string to evaluate
+ * @ctxt: an XPath context
+ * @value: the returned long value
+ *
+ * Convenience function to evaluate an XPath number
+ *
+ * Returns 0 in case of success in which case @value is set,
+ *         or -1 if the XPath evaluation failed or -2 if the
+ *         value doesn't have a long format.
+ */
+int
+virXPathLong(const char *xpath,
+             xmlXPathContextPtr ctxt,
+             long *value)
+{
+    return virXPathLongBase(xpath, ctxt, 10, value);
+}
+
+/**
+ * virXPathLongHex:
+ * @xpath: the XPath string to evaluate
+ * @ctxt: an XPath context
+ * @value: the returned long value
+ *
+ * Convenience function to evaluate an XPath number
+ * according to a base of 16
+ *
+ * Returns 0 in case of success in which case @value is set,
+ *         or -1 if the XPath evaluation failed or -2 if the
+ *         value doesn't have a long format.
+ */
+int
+virXPathLongHex(const char *xpath,
+                xmlXPathContextPtr ctxt,
+                long *value)
+{
+    return virXPathLongBase(xpath, ctxt, 16, value);
+}
+
+static int
+virXPathULongBase(const char *xpath,
+                  xmlXPathContextPtr ctxt,
+                  int base,
+                  unsigned long *value)
+{
+    xmlXPathObjectPtr obj;
+    xmlNodePtr relnode;
+    int ret = 0;
+
+    if ((ctxt == NULL) || (xpath == NULL) || (value == NULL)) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       "%s", _("Invalid parameter to virXPathULong()"));
+        return -1;
+    }
+    relnode = ctxt->node;
+    obj = xmlXPathEval(BAD_CAST xpath, ctxt);
+    ctxt->node = relnode;
+    if ((obj != NULL) && (obj->type == XPATH_STRING) &&
+        (obj->stringval != NULL) && (obj->stringval[0] != 0)) {
+        if (virStrToLong_ul((char *) obj->stringval, NULL, base, value) < 0)
+            ret = -2;
+    } else if ((obj != NULL) && (obj->type == XPATH_NUMBER) &&
+               (!(isnan(obj->floatval)))) {
+        *value = (unsigned long) obj->floatval;
+        if (*value != obj->floatval) {
+            ret = -2;
+        }
+    } else {
+        ret = -1;
+    }
+
+    xmlXPathFreeObject(obj);
+    return ret;
+}
+
+/**
+ * virXPathUInt:
+ * @xpath: the XPath string to evaluate
+ * @ctxt: an XPath context
+ * @value: the returned int value
+ *
+ * Convenience function to evaluate an XPath number
+ *
+ * Returns 0 in case of success in which case @value is set,
+ *         or -1 if the XPath evaluation failed or -2 if the
+ *         value doesn't have an int format.
+ */
+int
+virXPathUInt(const char *xpath,
+             xmlXPathContextPtr ctxt,
+             unsigned int *value)
+{
+    unsigned long tmp;
+    int ret;
+
+    ret = virXPathULongBase(xpath, ctxt, 10, &tmp);
+    if (ret < 0)
+        return ret;
+    if ((unsigned int) tmp != tmp)
+        return -2;
+    *value = tmp;
+    return 0;
+}
+
+/**
+ * virXPathULong:
+ * @xpath: the XPath string to evaluate
+ * @ctxt: an XPath context
+ * @value: the returned long value
+ *
+ * Convenience function to evaluate an XPath number
+ *
+ * Returns 0 in case of success in which case @value is set,
+ *         or -1 if the XPath evaluation failed or -2 if the
+ *         value doesn't have a long format.
+ */
+int
+virXPathULong(const char *xpath,
+              xmlXPathContextPtr ctxt,
+              unsigned long *value)
+{
+    return virXPathULongBase(xpath, ctxt, 10, value);
+}
+
+/**
+ * virXPathUHex:
+ * @xpath: the XPath string to evaluate
+ * @ctxt: an XPath context
+ * @value: the returned long value
+ *
+ * Convenience function to evaluate an XPath number
+ * according to base of 16
+ *
+ * Returns 0 in case of success in which case @value is set,
+ *         or -1 if the XPath evaluation failed or -2 if the
+ *         value doesn't have a long format.
+ */
+int
+virXPathULongHex(const char *xpath,
+                 xmlXPathContextPtr ctxt,
+                 unsigned long *value)
+{
+    return virXPathULongBase(xpath, ctxt, 16, value);
+}
+
+/**
+ * virXPathULongLong:
+ * @xpath: the XPath string to evaluate
+ * @ctxt: an XPath context
+ * @value: the returned long long value
+ *
+ * Convenience function to evaluate an XPath number
+ *
+ * Returns 0 in case of success in which case @value is set,
+ *         or -1 if the XPath evaluation failed or -2 if the
+ *         value doesn't have a long format.
+ */
+int
+virXPathULongLong(const char *xpath,
+                  xmlXPathContextPtr ctxt,
+                  unsigned long long *value)
+{
+    xmlXPathObjectPtr obj;
+    xmlNodePtr relnode;
+    int ret = 0;
+
+    if ((ctxt == NULL) || (xpath == NULL) || (value == NULL)) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       "%s", _("Invalid parameter to virXPathULong()"));
+        return -1;
+    }
+    relnode = ctxt->node;
+    obj = xmlXPathEval(BAD_CAST xpath, ctxt);
+    ctxt->node = relnode;
+    if ((obj != NULL) && (obj->type == XPATH_STRING) &&
+        (obj->stringval != NULL) && (obj->stringval[0] != 0)) {
+        if (virStrToLong_ull((char *) obj->stringval, NULL, 10, value) < 0)
+            ret = -2;
+    } else if ((obj != NULL) && (obj->type == XPATH_NUMBER) &&
+               (!(isnan(obj->floatval)))) {
+        *value = (unsigned long long) obj->floatval;
+        if (*value != obj->floatval) {
+            ret = -2;
+        }
+    } else {
+        ret = -1;
+    }
+
+    xmlXPathFreeObject(obj);
+    return ret;
+}
+
+/**
+ * virXPathULongLong:
+ * @xpath: the XPath string to evaluate
+ * @ctxt: an XPath context
+ * @value: the returned long long value
+ *
+ * Convenience function to evaluate an XPath number
+ *
+ * Returns 0 in case of success in which case @value is set,
+ *         or -1 if the XPath evaluation failed or -2 if the
+ *         value doesn't have a long format.
+ */
+int
+virXPathLongLong(const char *xpath,
+                 xmlXPathContextPtr ctxt,
+                 long long *value)
+{
+    xmlXPathObjectPtr obj;
+    xmlNodePtr relnode;
+    int ret = 0;
+
+    if ((ctxt == NULL) || (xpath == NULL) || (value == NULL)) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       "%s", _("Invalid parameter to virXPathLongLong()"));
+        return -1;
+    }
+    relnode = ctxt->node;
+    obj = xmlXPathEval(BAD_CAST xpath, ctxt);
+    ctxt->node = relnode;
+    if ((obj != NULL) && (obj->type == XPATH_STRING) &&
+        (obj->stringval != NULL) && (obj->stringval[0] != 0)) {
+        if (virStrToLong_ll((char *) obj->stringval, NULL, 10, value) < 0)
+            ret = -2;
+    } else if ((obj != NULL) && (obj->type == XPATH_NUMBER) &&
+               (!(isnan(obj->floatval)))) {
+        *value = (long long) obj->floatval;
+        if (*value != obj->floatval) {
+            ret = -2;
+        }
+    } else {
+        ret = -1;
+    }
+
+    xmlXPathFreeObject(obj);
+    return ret;
+}
+
+char *
+virXMLPropString(xmlNodePtr node,
+                 const char *name)
+{
+    return (char *)xmlGetProp(node, BAD_CAST name);
+}
+
+/**
+ * virXPathBoolean:
+ * @xpath: the XPath string to evaluate
+ * @ctxt: an XPath context
+ *
+ * Convenience function to evaluate an XPath boolean
+ *
+ * Returns 0 if false, 1 if true, or -1 if the evaluation failed.
+ */
+int
+virXPathBoolean(const char *xpath,
+                xmlXPathContextPtr ctxt)
+{
+    xmlXPathObjectPtr obj;
+    xmlNodePtr relnode;
+    int ret;
+
+    if ((ctxt == NULL) || (xpath == NULL)) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       "%s", _("Invalid parameter to virXPathBoolean()"));
+        return -1;
+    }
+    relnode = ctxt->node;
+    obj = xmlXPathEval(BAD_CAST xpath, ctxt);
+    ctxt->node = relnode;
+    if ((obj == NULL) || (obj->type != XPATH_BOOLEAN) ||
+        (obj->boolval < 0) || (obj->boolval > 1)) {
+        xmlXPathFreeObject(obj);
+        return -1;
+    }
+    ret = obj->boolval;
+
+    xmlXPathFreeObject(obj);
+    return ret;
+}
+
+/**
+ * virXPathNode:
+ * @xpath: the XPath string to evaluate
+ * @ctxt: an XPath context
+ *
+ * Convenience function to evaluate an XPath node set and returning
+ * only one node, the first one in the set if any
+ *
+ * Returns a pointer to the node or NULL if the evaluation failed.
+ */
+xmlNodePtr
+virXPathNode(const char *xpath,
+             xmlXPathContextPtr ctxt)
+{
+    xmlXPathObjectPtr obj;
+    xmlNodePtr relnode;
+    xmlNodePtr ret;
+
+    if ((ctxt == NULL) || (xpath == NULL)) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       "%s", _("Invalid parameter to virXPathNode()"));
+        return NULL;
+    }
+    relnode = ctxt->node;
+    obj = xmlXPathEval(BAD_CAST xpath, ctxt);
+    ctxt->node = relnode;
+    if ((obj == NULL) || (obj->type != XPATH_NODESET) ||
+        (obj->nodesetval == NULL) || (obj->nodesetval->nodeNr <= 0) ||
+        (obj->nodesetval->nodeTab == NULL)) {
+        xmlXPathFreeObject(obj);
+        return NULL;
+    }
+
+    ret = obj->nodesetval->nodeTab[0];
+    xmlXPathFreeObject(obj);
+    return ret;
+}
+
+/**
+ * virXPathNodeSet:
+ * @xpath: the XPath string to evaluate
+ * @ctxt: an XPath context
+ * @list: the returned list of nodes (or NULL if only count matters)
+ *
+ * Convenience function to evaluate an XPath node set
+ *
+ * Returns the number of nodes found in which case @list is set (and
+ *         must be freed) or -1 if the evaluation failed.
+ */
+int
+virXPathNodeSet(const char *xpath,
+                xmlXPathContextPtr ctxt,
+                xmlNodePtr **list)
+{
+    xmlXPathObjectPtr obj;
+    xmlNodePtr relnode;
+    int ret;
+
+    if ((ctxt == NULL) || (xpath == NULL)) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       "%s", _("Invalid parameter to virXPathNodeSet()"));
+        return -1;
+    }
+
+    if (list != NULL)
+        *list = NULL;
+
+    relnode = ctxt->node;
+    obj = xmlXPathEval(BAD_CAST xpath, ctxt);
+    ctxt->node = relnode;
+    if (obj == NULL)
+        return 0;
+
+    if (obj->type != XPATH_NODESET) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Incorrect xpath '%s'"), xpath);
+        xmlXPathFreeObject(obj);
+        return -1;
+    }
+
+    if ((obj->nodesetval == NULL)  || (obj->nodesetval->nodeNr < 0)) {
+        xmlXPathFreeObject(obj);
+        return 0;
+    }
+
+    ret = obj->nodesetval->nodeNr;
+    if (list != NULL && ret) {
+        if (VIR_ALLOC_N(*list, ret) < 0) {
+            virReportOOMError();
+            ret = -1;
+        } else {
+            memcpy(*list, obj->nodesetval->nodeTab,
+                   ret * sizeof(xmlNodePtr));
+        }
+    }
+    xmlXPathFreeObject(obj);
+    return ret;
+}
+
+
+/**
+ * catchXMLError:
+ *
+ * Called from SAX on parsing errors in the XML.
+ *
+ * This version is heavily based on xmlParserPrintFileContextInternal from libxml2.
+ */
+static void
+catchXMLError(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...)
+{
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+
+    const xmlChar *cur, *base;
+    unsigned int n, col;	/* GCC warns if signed, because compared with sizeof() */
+    int domcode = VIR_FROM_XML;
+
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+    char *contextstr = NULL;
+    char *pointerstr = NULL;
+
+
+    /* conditions for error printing */
+    if (!ctxt ||
+        (virGetLastError() != NULL) ||
+        ctxt->input == NULL ||
+        ctxt->lastError.level != XML_ERR_FATAL ||
+        ctxt->lastError.message == NULL)
+        return;
+
+    if (ctxt->_private)
+            domcode = ((struct virParserData *) ctxt->_private)->domcode;
+
+
+    cur = ctxt->input->cur;
+    base = ctxt->input->base;
+
+    /* skip backwards over any end-of-lines */
+    while ((cur > base) && ((*(cur) == '\n') || (*(cur) == '\r'))) {
+        cur--;
+    }
+
+    /* search backwards for beginning-of-line (to max buff size) */
+    while ((cur > base) && (*(cur) != '\n') && (*(cur) != '\r'))
+        cur--;
+    if ((*(cur) == '\n') || (*(cur) == '\r')) cur++;
+
+    /* calculate the error position in terms of the current position */
+    col = ctxt->input->cur - cur;
+
+    /* search forward for end-of-line (to max buff size) */
+    /* copy selected text to our buffer */
+    while ((*cur != 0) && (*(cur) != '\n') && (*(cur) != '\r')) {
+        virBufferAddChar(&buf, *cur++);
+    }
+
+    /* create blank line with problem pointer */
+    contextstr = virBufferContentAndReset(&buf);
+
+    /* (leave buffer space for pointer + line terminator) */
+    for  (n = 0; (n<col) && (contextstr[n] != 0); n++) {
+        if (contextstr[n] == '\t')
+            virBufferAddChar(&buf, '\t');
+        else
+            virBufferAddChar(&buf, '-');
+    }
+
+    virBufferAddChar(&buf, '^');
+
+    pointerstr = virBufferContentAndReset(&buf);
+
+    if (ctxt->lastError.file) {
+        virGenericReportError(domcode, VIR_ERR_XML_DETAIL,
+                              _("%s:%d: %s%s\n%s"),
+                              ctxt->lastError.file,
+                              ctxt->lastError.line,
+                              ctxt->lastError.message,
+                              contextstr,
+                              pointerstr);
+    } else {
+         virGenericReportError(domcode, VIR_ERR_XML_DETAIL,
+                              _("at line %d: %s%s\n%s"),
+                              ctxt->lastError.line,
+                              ctxt->lastError.message,
+                              contextstr,
+                              pointerstr);
+    }
+
+    VIR_FREE(contextstr);
+    VIR_FREE(pointerstr);
+}
+
+/**
+ * virXMLParseHelper:
+ * @domcode: error domain of the caller, usually VIR_FROM_THIS
+ * @filename: file to be parsed or NULL if string parsing is requested
+ * @xmlStr: XML string to be parsed in case filename is NULL
+ * @url: URL of XML document for string parser
+ * @ctxt: optional pointer to populate with new context pointer
+ *
+ * Parse XML document provided either as a file or a string. The function
+ * guarantees that the XML document contains a root element.
+ *
+ * Returns parsed XML document.
+ */
+xmlDocPtr
+virXMLParseHelper(int domcode,
+                  const char *filename,
+                  const char *xmlStr,
+                  const char *url,
+                  xmlXPathContextPtr *ctxt)
+{
+    struct virParserData private;
+    xmlParserCtxtPtr pctxt;
+    xmlDocPtr xml = NULL;
+
+    /* Set up a parser context so we can catch the details of XML errors. */
+    pctxt = xmlNewParserCtxt();
+    if (!pctxt || !pctxt->sax) {
+        virReportOOMError();
+        goto error;
+    }
+
+    private.domcode = domcode;
+    pctxt->_private = &private;
+    pctxt->sax->error = catchXMLError;
+
+    if (filename) {
+        xml = xmlCtxtReadFile(pctxt, filename, NULL,
+                              XML_PARSE_NOENT | XML_PARSE_NONET |
+                              XML_PARSE_NOWARNING);
+    } else {
+        xml = xmlCtxtReadDoc(pctxt, BAD_CAST xmlStr, url, NULL,
+                             XML_PARSE_NOENT | XML_PARSE_NONET |
+                             XML_PARSE_NOWARNING);
+    }
+    if (!xml)
+        goto error;
+
+    if (xmlDocGetRootElement(xml) == NULL) {
+        virGenericReportError(domcode, VIR_ERR_INTERNAL_ERROR,
+                              "%s", _("missing root element"));
+        goto error;
+    }
+
+    if (ctxt) {
+        *ctxt = xmlXPathNewContext(xml);
+        if (!*ctxt) {
+            virReportOOMError();
+            goto error;
+        }
+        (*ctxt)->node = xmlDocGetRootElement(xml);
+    }
+
+cleanup:
+    xmlFreeParserCtxt(pctxt);
+
+    return xml;
+
+error:
+    xmlFreeDoc(xml);
+    xml = NULL;
+
+    if (virGetLastError() == NULL) {
+        virGenericReportError(domcode, VIR_ERR_XML_ERROR,
+                              "%s", _("failed to parse xml document"));
+    }
+    goto cleanup;
+}
+
+const char *virXMLPickShellSafeComment(const char *str1, const char *str2)
+{
+    if (str1 && !strpbrk(str1, "\r\t\n !\"#$&'()*;<>?[\\]^`{|}~") &&
+        !strstr(str1, "--"))
+        return str1;
+    if (str2 && !strpbrk(str2, "\r\t\n !\"#$&'()*;<>?[\\]^`{|}~") &&
+        !strstr(str2, "--"))
+        return str2;
+    return NULL;
+}
+
+static int virXMLEmitWarning(int fd,
+                             const char *name,
+                             const char *cmd)
+{
+    size_t len;
+    const char *prologue =
+        "<!--\n"
+        "WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE\n"
+        "OVERWRITTEN AND LOST. Changes to this xml configuration should be made using:\n"
+        "  virsh ";
+    const char *epilogue =
+        "\n"
+        "or other application using the libvirt API.\n"
+        "-->\n\n";
+
+    if (fd < 0 || !cmd) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    len = strlen(prologue);
+    if (safewrite(fd, prologue, len) != len)
+        return -1;
+
+    len = strlen(cmd);
+    if (safewrite(fd, cmd, len) != len)
+        return -1;
+
+    if (name) {
+        if (safewrite(fd, " ", 1) != 1)
+            return -1;
+
+        len = strlen(name);
+        if (safewrite(fd, name, len) != len)
+            return -1;
+    }
+
+    len = strlen(epilogue);
+    if (safewrite(fd, epilogue, len) != len)
+        return -1;
+
+    return 0;
+}
+
+
+struct virXMLRewriteFileData {
+    const char *warnName;
+    const char *warnCommand;
+    const char *xml;
+};
+
+static int
+virXMLRewriteFile(int fd, void *opaque)
+{
+    struct virXMLRewriteFileData *data = opaque;
+
+    if (data->warnCommand) {
+        if (virXMLEmitWarning(fd, data->warnName, data->warnCommand) < 0)
+            return -1;
+    }
+
+    if (safewrite(fd, data->xml, strlen(data->xml)) < 0)
+        return -1;
+
+    return 0;
+}
+
+int
+virXMLSaveFile(const char *path,
+               const char *warnName,
+               const char *warnCommand,
+               const char *xml)
+{
+    struct virXMLRewriteFileData data = { warnName, warnCommand, xml };
+
+    return virFileRewrite(path, S_IRUSR | S_IWUSR, virXMLRewriteFile, &data);
+}
+
+/* Returns the number of children of node, or -1 on error.  */
+long
+virXMLChildElementCount(xmlNodePtr node)
+{
+    long ret = 0;
+    xmlNodePtr cur = NULL;
+
+    /* xmlChildElementCount returns 0 on error, which isn't helpful;
+     * besides, it is not available in libxml2 2.6.  */
+    if (!node || node->type != XML_ELEMENT_NODE)
+        return -1;
+    cur = node->children;
+    while (cur) {
+        if (cur->type == XML_ELEMENT_NODE)
+            ret++;
+        cur = cur->next;
+    }
+    return ret;
+}
diff --git a/src/util/virxml.h b/src/util/virxml.h
new file mode 100644
index 0000000..c3b05df
--- /dev/null
+++ b/src/util/virxml.h
@@ -0,0 +1,148 @@
+/*
+ * xml.h: internal definitions used for XML parsing routines.
+ */
+
+#ifndef __VIR_XML_H__
+# define __VIR_XML_H__
+
+# include "internal.h"
+
+# include <libxml/parser.h>
+# include <libxml/tree.h>
+# include <libxml/xpath.h>
+
+int              virXPathBoolean(const char *xpath,
+                                 xmlXPathContextPtr ctxt);
+char *            virXPathString(const char *xpath,
+                                 xmlXPathContextPtr ctxt);
+char *       virXPathStringLimit(const char *xpath,
+                                 size_t maxlen,
+                                 xmlXPathContextPtr ctxt);
+int               virXPathNumber(const char *xpath,
+                                 xmlXPathContextPtr ctxt,
+                                 double *value);
+int                  virXPathInt(const char *xpath,
+                                 xmlXPathContextPtr ctxt,
+                                 int *value);
+int                 virXPathUInt(const char *xpath,
+                                 xmlXPathContextPtr ctxt,
+                                 unsigned int *value);
+int                 virXPathLong(const char *xpath,
+                                 xmlXPathContextPtr ctxt,
+                                 long *value);
+int                virXPathULong(const char *xpath,
+                                 xmlXPathContextPtr ctxt,
+                                 unsigned long *value);
+int            virXPathULongLong(const char *xpath,
+                                 xmlXPathContextPtr ctxt,
+                                 unsigned long long *value);
+int             virXPathLongLong(const char *xpath,
+                                 xmlXPathContextPtr ctxt,
+                                 long long *value);
+int              virXPathLongHex(const char *xpath,
+                                 xmlXPathContextPtr ctxt,
+                                 long *value);
+int             virXPathULongHex(const char *xpath,
+                                 xmlXPathContextPtr ctxt,
+                                 unsigned long *value);
+xmlNodePtr          virXPathNode(const char *xpath,
+                                 xmlXPathContextPtr ctxt);
+int              virXPathNodeSet(const char *xpath,
+                                 xmlXPathContextPtr ctxt,
+                                 xmlNodePtr **list);
+char *          virXMLPropString(xmlNodePtr node,
+                                 const char *name);
+long     virXMLChildElementCount(xmlNodePtr node);
+
+/* Internal function; prefer the macros below.  */
+xmlDocPtr      virXMLParseHelper(int domcode,
+                                 const char *filename,
+                                 const char *xmlStr,
+                                 const char *url,
+                                 xmlXPathContextPtr *pctxt);
+
+const char *virXMLPickShellSafeComment(const char *str1, const char *str2);
+/**
+ * virXMLParse:
+ * @filename: file to parse, or NULL for string parsing
+ * @xmlStr: if @filename is NULL, a string to parse
+ * @url: if @filename is NULL, an optional filename to attribute the parse to
+ *
+ * Parse xml from either a file or a string.
+ *
+ * Return the parsed document object, or NULL on failure.
+ */
+# define virXMLParse(filename, xmlStr, url)                     \
+    virXMLParseHelper(VIR_FROM_THIS, filename, xmlStr, url, NULL)
+
+/**
+ * virXMLParseString:
+ * @xmlStr: a string to parse
+ * @url: an optional filename to attribute the parse to
+ *
+ * Parse xml from a string.
+ *
+ * Return the parsed document object, or NULL on failure.
+ */
+# define virXMLParseString(xmlStr, url)                         \
+    virXMLParseHelper(VIR_FROM_THIS, NULL, xmlStr, url, NULL)
+
+/**
+ * virXMLParseFile:
+ * @filename: file to parse
+ *
+ * Parse xml from a file.
+ *
+ * Return the parsed document object, or NULL on failure.
+ */
+# define virXMLParseFile(filename)                              \
+    virXMLParseHelper(VIR_FROM_THIS, filename, NULL, NULL, NULL)
+
+/**
+ * virXMLParseCtxt:
+ * @filename: file to parse, or NULL for string parsing
+ * @xmlStr: if @filename is NULL, a string to parse
+ * @url: if @filename is NULL, an optional filename to attribute the parse to
+ * @pctxt: if non-NULL, populate with a new context object on success,
+ * with (*pctxt)->node pre-set to the root node
+ *
+ * Parse xml from either a file or a string.
+ *
+ * Return the parsed document object, or NULL on failure.
+ */
+# define virXMLParseCtxt(filename, xmlStr, url, pctxt)                  \
+    virXMLParseHelper(VIR_FROM_THIS, filename, xmlStr, url, pctxt)
+
+/**
+ * virXMLParseStringCtxt:
+ * @xmlStr: a string to parse
+ * @url: an optional filename to attribute the parse to
+ * @pctxt: if non-NULL, populate with a new context object on success,
+ * with (*pctxt)->node pre-set to the root node
+ *
+ * Parse xml from a string.
+ *
+ * Return the parsed document object, or NULL on failure.
+ */
+# define virXMLParseStringCtxt(xmlStr, url, pctxt)              \
+    virXMLParseHelper(VIR_FROM_THIS, NULL, xmlStr, url, pctxt)
+
+/**
+ * virXMLParseFileCtxt:
+ * @filename: file to parse
+ * @pctxt: if non-NULL, populate with a new context object on success,
+ * with (*pctxt)->node pre-set to the root node
+ *
+ * Parse xml from a file.
+ *
+ * Return the parsed document object, or NULL on failure.
+ */
+# define virXMLParseFileCtxt(filename, pctxt)                           \
+    virXMLParseHelper(VIR_FROM_THIS, filename, NULL, NULL, pctxt)
+
+int virXMLSaveFile(const char *path,
+                   const char *warnName,
+                   const char *warnCommand,
+                   const char *xml);
+
+#endif                          /* __VIR_XML_H__ */
diff --git a/src/util/xml.c b/src/util/xml.c
deleted file mode 100644
index 05c7f33..0000000
--- a/src/util/xml.c
+++ /dev/null
@@ -1,890 +0,0 @@
-/*
- * xml.c: XML based interfaces for the libvir library
- *
- * Copyright (C) 2005, 2007-2012 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library.  If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * Daniel Veillard <veillard@xxxxxxxxxx>
- */
-
-#include <config.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <limits.h>
-#include <math.h>               /* for isnan() */
-#include <sys/stat.h>
-
-#include "virterror_internal.h"
-#include "xml.h"
-#include "virbuffer.h"
-#include "virutil.h"
-#include "viralloc.h"
-#include "virfile.h"
-
-#define VIR_FROM_THIS VIR_FROM_XML
-
-#define virGenericReportError(from, code, ...)                          \
-        virReportErrorHelper(from, code, __FILE__,                      \
-                             __FUNCTION__, __LINE__, __VA_ARGS__)
-
-/* Internal data to be passed to SAX parser and used by error handler. */
-struct virParserData {
-    int domcode;
-};
-
-
-/************************************************************************
- *									*
- * Wrappers around libxml2 XPath specific functions			*
- *									*
- ************************************************************************/
-
-/**
- * virXPathString:
- * @xpath: the XPath string to evaluate
- * @ctxt: an XPath context
- *
- * Convenience function to evaluate an XPath string
- *
- * Returns a new string which must be deallocated by the caller or NULL
- *         if the evaluation failed.
- */
-char *
-virXPathString(const char *xpath,
-               xmlXPathContextPtr ctxt)
-{
-    xmlXPathObjectPtr obj;
-    xmlNodePtr relnode;
-    char *ret;
-
-    if ((ctxt == NULL) || (xpath == NULL)) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       "%s", _("Invalid parameter to virXPathString()"));
-        return NULL;
-    }
-    relnode = ctxt->node;
-    obj = xmlXPathEval(BAD_CAST xpath, ctxt);
-    ctxt->node = relnode;
-    if ((obj == NULL) || (obj->type != XPATH_STRING) ||
-        (obj->stringval == NULL) || (obj->stringval[0] == 0)) {
-        xmlXPathFreeObject(obj);
-        return NULL;
-    }
-    ret = strdup((char *) obj->stringval);
-    xmlXPathFreeObject(obj);
-    if (ret == NULL) {
-        virReportOOMError();
-    }
-    return ret;
-}
-
-/**
- * virXPathStringLimit:
- * @xpath: the XPath string to evaluate
- * @maxlen: maximum length permittred string
- * @ctxt: an XPath context
- *
- * Wrapper for virXPathString, which validates the length of the returned
- * string.
- *
- * Returns a new string which must be deallocated by the caller or NULL if
- * the evaluation failed.
- */
-char *
-virXPathStringLimit(const char *xpath,
-                    size_t maxlen,
-                    xmlXPathContextPtr ctxt)
-{
-    char *tmp = virXPathString(xpath, ctxt);
-
-    if (tmp != NULL && strlen(tmp) >= maxlen) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("\'%s\' value longer than %zu bytes"),
-                       xpath, maxlen);
-        VIR_FREE(tmp);
-        return NULL;
-    }
-
-    return tmp;
-}
-
-/**
- * virXPathNumber:
- * @xpath: the XPath string to evaluate
- * @ctxt: an XPath context
- * @value: the returned double value
- *
- * Convenience function to evaluate an XPath number
- *
- * Returns 0 in case of success in which case @value is set,
- *         or -1 if the evaluation failed.
- */
-int
-virXPathNumber(const char *xpath,
-               xmlXPathContextPtr ctxt,
-               double *value)
-{
-    xmlXPathObjectPtr obj;
-    xmlNodePtr relnode;
-
-    if ((ctxt == NULL) || (xpath == NULL) || (value == NULL)) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       "%s", _("Invalid parameter to virXPathNumber()"));
-        return -1;
-    }
-    relnode = ctxt->node;
-    obj = xmlXPathEval(BAD_CAST xpath, ctxt);
-    ctxt->node = relnode;
-    if ((obj == NULL) || (obj->type != XPATH_NUMBER) ||
-        (isnan(obj->floatval))) {
-        xmlXPathFreeObject(obj);
-        return -1;
-    }
-
-    *value = obj->floatval;
-    xmlXPathFreeObject(obj);
-    return 0;
-}
-
-static int
-virXPathLongBase(const char *xpath,
-                 xmlXPathContextPtr ctxt,
-                 int base,
-                 long *value)
-{
-    xmlXPathObjectPtr obj;
-    xmlNodePtr relnode;
-    int ret = 0;
-
-    if ((ctxt == NULL) || (xpath == NULL) || (value == NULL)) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       "%s", _("Invalid parameter to virXPathLong()"));
-        return -1;
-    }
-    relnode = ctxt->node;
-    obj = xmlXPathEval(BAD_CAST xpath, ctxt);
-    ctxt->node = relnode;
-    if ((obj != NULL) && (obj->type == XPATH_STRING) &&
-        (obj->stringval != NULL) && (obj->stringval[0] != 0)) {
-        if (virStrToLong_l((char *) obj->stringval, NULL, base, value) < 0)
-            ret = -2;
-    } else if ((obj != NULL) && (obj->type == XPATH_NUMBER) &&
-               (!(isnan(obj->floatval)))) {
-        *value = (long) obj->floatval;
-        if (*value != obj->floatval) {
-            ret = -2;
-        }
-    } else {
-        ret = -1;
-    }
-
-    xmlXPathFreeObject(obj);
-    return ret;
-}
-
-/**
- * virXPathInt:
- * @xpath: the XPath string to evaluate
- * @ctxt: an XPath context
- * @value: the returned int value
- *
- * Convenience function to evaluate an XPath number
- *
- * Returns 0 in case of success in which case @value is set,
- *         or -1 if the XPath evaluation failed or -2 if the
- *         value doesn't have an int format.
- */
-int
-virXPathInt(const char *xpath,
-            xmlXPathContextPtr ctxt,
-            int *value)
-{
-    long tmp;
-    int ret;
-
-    ret = virXPathLongBase(xpath, ctxt, 10, &tmp);
-    if (ret < 0)
-        return ret;
-    if ((int) tmp != tmp)
-        return -2;
-    *value = tmp;
-    return 0;
-}
-
-/**
- * virXPathLong:
- * @xpath: the XPath string to evaluate
- * @ctxt: an XPath context
- * @value: the returned long value
- *
- * Convenience function to evaluate an XPath number
- *
- * Returns 0 in case of success in which case @value is set,
- *         or -1 if the XPath evaluation failed or -2 if the
- *         value doesn't have a long format.
- */
-int
-virXPathLong(const char *xpath,
-             xmlXPathContextPtr ctxt,
-             long *value)
-{
-    return virXPathLongBase(xpath, ctxt, 10, value);
-}
-
-/**
- * virXPathLongHex:
- * @xpath: the XPath string to evaluate
- * @ctxt: an XPath context
- * @value: the returned long value
- *
- * Convenience function to evaluate an XPath number
- * according to a base of 16
- *
- * Returns 0 in case of success in which case @value is set,
- *         or -1 if the XPath evaluation failed or -2 if the
- *         value doesn't have a long format.
- */
-int
-virXPathLongHex(const char *xpath,
-                xmlXPathContextPtr ctxt,
-                long *value)
-{
-    return virXPathLongBase(xpath, ctxt, 16, value);
-}
-
-static int
-virXPathULongBase(const char *xpath,
-                  xmlXPathContextPtr ctxt,
-                  int base,
-                  unsigned long *value)
-{
-    xmlXPathObjectPtr obj;
-    xmlNodePtr relnode;
-    int ret = 0;
-
-    if ((ctxt == NULL) || (xpath == NULL) || (value == NULL)) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       "%s", _("Invalid parameter to virXPathULong()"));
-        return -1;
-    }
-    relnode = ctxt->node;
-    obj = xmlXPathEval(BAD_CAST xpath, ctxt);
-    ctxt->node = relnode;
-    if ((obj != NULL) && (obj->type == XPATH_STRING) &&
-        (obj->stringval != NULL) && (obj->stringval[0] != 0)) {
-        if (virStrToLong_ul((char *) obj->stringval, NULL, base, value) < 0)
-            ret = -2;
-    } else if ((obj != NULL) && (obj->type == XPATH_NUMBER) &&
-               (!(isnan(obj->floatval)))) {
-        *value = (unsigned long) obj->floatval;
-        if (*value != obj->floatval) {
-            ret = -2;
-        }
-    } else {
-        ret = -1;
-    }
-
-    xmlXPathFreeObject(obj);
-    return ret;
-}
-
-/**
- * virXPathUInt:
- * @xpath: the XPath string to evaluate
- * @ctxt: an XPath context
- * @value: the returned int value
- *
- * Convenience function to evaluate an XPath number
- *
- * Returns 0 in case of success in which case @value is set,
- *         or -1 if the XPath evaluation failed or -2 if the
- *         value doesn't have an int format.
- */
-int
-virXPathUInt(const char *xpath,
-             xmlXPathContextPtr ctxt,
-             unsigned int *value)
-{
-    unsigned long tmp;
-    int ret;
-
-    ret = virXPathULongBase(xpath, ctxt, 10, &tmp);
-    if (ret < 0)
-        return ret;
-    if ((unsigned int) tmp != tmp)
-        return -2;
-    *value = tmp;
-    return 0;
-}
-
-/**
- * virXPathULong:
- * @xpath: the XPath string to evaluate
- * @ctxt: an XPath context
- * @value: the returned long value
- *
- * Convenience function to evaluate an XPath number
- *
- * Returns 0 in case of success in which case @value is set,
- *         or -1 if the XPath evaluation failed or -2 if the
- *         value doesn't have a long format.
- */
-int
-virXPathULong(const char *xpath,
-              xmlXPathContextPtr ctxt,
-              unsigned long *value)
-{
-    return virXPathULongBase(xpath, ctxt, 10, value);
-}
-
-/**
- * virXPathUHex:
- * @xpath: the XPath string to evaluate
- * @ctxt: an XPath context
- * @value: the returned long value
- *
- * Convenience function to evaluate an XPath number
- * according to base of 16
- *
- * Returns 0 in case of success in which case @value is set,
- *         or -1 if the XPath evaluation failed or -2 if the
- *         value doesn't have a long format.
- */
-int
-virXPathULongHex(const char *xpath,
-                 xmlXPathContextPtr ctxt,
-                 unsigned long *value)
-{
-    return virXPathULongBase(xpath, ctxt, 16, value);
-}
-
-/**
- * virXPathULongLong:
- * @xpath: the XPath string to evaluate
- * @ctxt: an XPath context
- * @value: the returned long long value
- *
- * Convenience function to evaluate an XPath number
- *
- * Returns 0 in case of success in which case @value is set,
- *         or -1 if the XPath evaluation failed or -2 if the
- *         value doesn't have a long format.
- */
-int
-virXPathULongLong(const char *xpath,
-                  xmlXPathContextPtr ctxt,
-                  unsigned long long *value)
-{
-    xmlXPathObjectPtr obj;
-    xmlNodePtr relnode;
-    int ret = 0;
-
-    if ((ctxt == NULL) || (xpath == NULL) || (value == NULL)) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       "%s", _("Invalid parameter to virXPathULong()"));
-        return -1;
-    }
-    relnode = ctxt->node;
-    obj = xmlXPathEval(BAD_CAST xpath, ctxt);
-    ctxt->node = relnode;
-    if ((obj != NULL) && (obj->type == XPATH_STRING) &&
-        (obj->stringval != NULL) && (obj->stringval[0] != 0)) {
-        if (virStrToLong_ull((char *) obj->stringval, NULL, 10, value) < 0)
-            ret = -2;
-    } else if ((obj != NULL) && (obj->type == XPATH_NUMBER) &&
-               (!(isnan(obj->floatval)))) {
-        *value = (unsigned long long) obj->floatval;
-        if (*value != obj->floatval) {
-            ret = -2;
-        }
-    } else {
-        ret = -1;
-    }
-
-    xmlXPathFreeObject(obj);
-    return ret;
-}
-
-/**
- * virXPathULongLong:
- * @xpath: the XPath string to evaluate
- * @ctxt: an XPath context
- * @value: the returned long long value
- *
- * Convenience function to evaluate an XPath number
- *
- * Returns 0 in case of success in which case @value is set,
- *         or -1 if the XPath evaluation failed or -2 if the
- *         value doesn't have a long format.
- */
-int
-virXPathLongLong(const char *xpath,
-                 xmlXPathContextPtr ctxt,
-                 long long *value)
-{
-    xmlXPathObjectPtr obj;
-    xmlNodePtr relnode;
-    int ret = 0;
-
-    if ((ctxt == NULL) || (xpath == NULL) || (value == NULL)) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       "%s", _("Invalid parameter to virXPathLongLong()"));
-        return -1;
-    }
-    relnode = ctxt->node;
-    obj = xmlXPathEval(BAD_CAST xpath, ctxt);
-    ctxt->node = relnode;
-    if ((obj != NULL) && (obj->type == XPATH_STRING) &&
-        (obj->stringval != NULL) && (obj->stringval[0] != 0)) {
-        if (virStrToLong_ll((char *) obj->stringval, NULL, 10, value) < 0)
-            ret = -2;
-    } else if ((obj != NULL) && (obj->type == XPATH_NUMBER) &&
-               (!(isnan(obj->floatval)))) {
-        *value = (long long) obj->floatval;
-        if (*value != obj->floatval) {
-            ret = -2;
-        }
-    } else {
-        ret = -1;
-    }
-
-    xmlXPathFreeObject(obj);
-    return ret;
-}
-
-char *
-virXMLPropString(xmlNodePtr node,
-                 const char *name)
-{
-    return (char *)xmlGetProp(node, BAD_CAST name);
-}
-
-/**
- * virXPathBoolean:
- * @xpath: the XPath string to evaluate
- * @ctxt: an XPath context
- *
- * Convenience function to evaluate an XPath boolean
- *
- * Returns 0 if false, 1 if true, or -1 if the evaluation failed.
- */
-int
-virXPathBoolean(const char *xpath,
-                xmlXPathContextPtr ctxt)
-{
-    xmlXPathObjectPtr obj;
-    xmlNodePtr relnode;
-    int ret;
-
-    if ((ctxt == NULL) || (xpath == NULL)) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       "%s", _("Invalid parameter to virXPathBoolean()"));
-        return -1;
-    }
-    relnode = ctxt->node;
-    obj = xmlXPathEval(BAD_CAST xpath, ctxt);
-    ctxt->node = relnode;
-    if ((obj == NULL) || (obj->type != XPATH_BOOLEAN) ||
-        (obj->boolval < 0) || (obj->boolval > 1)) {
-        xmlXPathFreeObject(obj);
-        return -1;
-    }
-    ret = obj->boolval;
-
-    xmlXPathFreeObject(obj);
-    return ret;
-}
-
-/**
- * virXPathNode:
- * @xpath: the XPath string to evaluate
- * @ctxt: an XPath context
- *
- * Convenience function to evaluate an XPath node set and returning
- * only one node, the first one in the set if any
- *
- * Returns a pointer to the node or NULL if the evaluation failed.
- */
-xmlNodePtr
-virXPathNode(const char *xpath,
-             xmlXPathContextPtr ctxt)
-{
-    xmlXPathObjectPtr obj;
-    xmlNodePtr relnode;
-    xmlNodePtr ret;
-
-    if ((ctxt == NULL) || (xpath == NULL)) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       "%s", _("Invalid parameter to virXPathNode()"));
-        return NULL;
-    }
-    relnode = ctxt->node;
-    obj = xmlXPathEval(BAD_CAST xpath, ctxt);
-    ctxt->node = relnode;
-    if ((obj == NULL) || (obj->type != XPATH_NODESET) ||
-        (obj->nodesetval == NULL) || (obj->nodesetval->nodeNr <= 0) ||
-        (obj->nodesetval->nodeTab == NULL)) {
-        xmlXPathFreeObject(obj);
-        return NULL;
-    }
-
-    ret = obj->nodesetval->nodeTab[0];
-    xmlXPathFreeObject(obj);
-    return ret;
-}
-
-/**
- * virXPathNodeSet:
- * @xpath: the XPath string to evaluate
- * @ctxt: an XPath context
- * @list: the returned list of nodes (or NULL if only count matters)
- *
- * Convenience function to evaluate an XPath node set
- *
- * Returns the number of nodes found in which case @list is set (and
- *         must be freed) or -1 if the evaluation failed.
- */
-int
-virXPathNodeSet(const char *xpath,
-                xmlXPathContextPtr ctxt,
-                xmlNodePtr **list)
-{
-    xmlXPathObjectPtr obj;
-    xmlNodePtr relnode;
-    int ret;
-
-    if ((ctxt == NULL) || (xpath == NULL)) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       "%s", _("Invalid parameter to virXPathNodeSet()"));
-        return -1;
-    }
-
-    if (list != NULL)
-        *list = NULL;
-
-    relnode = ctxt->node;
-    obj = xmlXPathEval(BAD_CAST xpath, ctxt);
-    ctxt->node = relnode;
-    if (obj == NULL)
-        return 0;
-
-    if (obj->type != XPATH_NODESET) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("Incorrect xpath '%s'"), xpath);
-        xmlXPathFreeObject(obj);
-        return -1;
-    }
-
-    if ((obj->nodesetval == NULL)  || (obj->nodesetval->nodeNr < 0)) {
-        xmlXPathFreeObject(obj);
-        return 0;
-    }
-
-    ret = obj->nodesetval->nodeNr;
-    if (list != NULL && ret) {
-        if (VIR_ALLOC_N(*list, ret) < 0) {
-            virReportOOMError();
-            ret = -1;
-        } else {
-            memcpy(*list, obj->nodesetval->nodeTab,
-                   ret * sizeof(xmlNodePtr));
-        }
-    }
-    xmlXPathFreeObject(obj);
-    return ret;
-}
-
-
-/**
- * catchXMLError:
- *
- * Called from SAX on parsing errors in the XML.
- *
- * This version is heavily based on xmlParserPrintFileContextInternal from libxml2.
- */
-static void
-catchXMLError(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...)
-{
-    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-
-    const xmlChar *cur, *base;
-    unsigned int n, col;	/* GCC warns if signed, because compared with sizeof() */
-    int domcode = VIR_FROM_XML;
-
-    virBuffer buf = VIR_BUFFER_INITIALIZER;
-    char *contextstr = NULL;
-    char *pointerstr = NULL;
-
-
-    /* conditions for error printing */
-    if (!ctxt ||
-        (virGetLastError() != NULL) ||
-        ctxt->input == NULL ||
-        ctxt->lastError.level != XML_ERR_FATAL ||
-        ctxt->lastError.message == NULL)
-        return;
-
-    if (ctxt->_private)
-            domcode = ((struct virParserData *) ctxt->_private)->domcode;
-
-
-    cur = ctxt->input->cur;
-    base = ctxt->input->base;
-
-    /* skip backwards over any end-of-lines */
-    while ((cur > base) && ((*(cur) == '\n') || (*(cur) == '\r'))) {
-        cur--;
-    }
-
-    /* search backwards for beginning-of-line (to max buff size) */
-    while ((cur > base) && (*(cur) != '\n') && (*(cur) != '\r'))
-        cur--;
-    if ((*(cur) == '\n') || (*(cur) == '\r')) cur++;
-
-    /* calculate the error position in terms of the current position */
-    col = ctxt->input->cur - cur;
-
-    /* search forward for end-of-line (to max buff size) */
-    /* copy selected text to our buffer */
-    while ((*cur != 0) && (*(cur) != '\n') && (*(cur) != '\r')) {
-        virBufferAddChar(&buf, *cur++);
-    }
-
-    /* create blank line with problem pointer */
-    contextstr = virBufferContentAndReset(&buf);
-
-    /* (leave buffer space for pointer + line terminator) */
-    for  (n = 0; (n<col) && (contextstr[n] != 0); n++) {
-        if (contextstr[n] == '\t')
-            virBufferAddChar(&buf, '\t');
-        else
-            virBufferAddChar(&buf, '-');
-    }
-
-    virBufferAddChar(&buf, '^');
-
-    pointerstr = virBufferContentAndReset(&buf);
-
-    if (ctxt->lastError.file) {
-        virGenericReportError(domcode, VIR_ERR_XML_DETAIL,
-                              _("%s:%d: %s%s\n%s"),
-                              ctxt->lastError.file,
-                              ctxt->lastError.line,
-                              ctxt->lastError.message,
-                              contextstr,
-                              pointerstr);
-    } else {
-         virGenericReportError(domcode, VIR_ERR_XML_DETAIL,
-                              _("at line %d: %s%s\n%s"),
-                              ctxt->lastError.line,
-                              ctxt->lastError.message,
-                              contextstr,
-                              pointerstr);
-    }
-
-    VIR_FREE(contextstr);
-    VIR_FREE(pointerstr);
-}
-
-/**
- * virXMLParseHelper:
- * @domcode: error domain of the caller, usually VIR_FROM_THIS
- * @filename: file to be parsed or NULL if string parsing is requested
- * @xmlStr: XML string to be parsed in case filename is NULL
- * @url: URL of XML document for string parser
- * @ctxt: optional pointer to populate with new context pointer
- *
- * Parse XML document provided either as a file or a string. The function
- * guarantees that the XML document contains a root element.
- *
- * Returns parsed XML document.
- */
-xmlDocPtr
-virXMLParseHelper(int domcode,
-                  const char *filename,
-                  const char *xmlStr,
-                  const char *url,
-                  xmlXPathContextPtr *ctxt)
-{
-    struct virParserData private;
-    xmlParserCtxtPtr pctxt;
-    xmlDocPtr xml = NULL;
-
-    /* Set up a parser context so we can catch the details of XML errors. */
-    pctxt = xmlNewParserCtxt();
-    if (!pctxt || !pctxt->sax) {
-        virReportOOMError();
-        goto error;
-    }
-
-    private.domcode = domcode;
-    pctxt->_private = &private;
-    pctxt->sax->error = catchXMLError;
-
-    if (filename) {
-        xml = xmlCtxtReadFile(pctxt, filename, NULL,
-                              XML_PARSE_NOENT | XML_PARSE_NONET |
-                              XML_PARSE_NOWARNING);
-    } else {
-        xml = xmlCtxtReadDoc(pctxt, BAD_CAST xmlStr, url, NULL,
-                             XML_PARSE_NOENT | XML_PARSE_NONET |
-                             XML_PARSE_NOWARNING);
-    }
-    if (!xml)
-        goto error;
-
-    if (xmlDocGetRootElement(xml) == NULL) {
-        virGenericReportError(domcode, VIR_ERR_INTERNAL_ERROR,
-                              "%s", _("missing root element"));
-        goto error;
-    }
-
-    if (ctxt) {
-        *ctxt = xmlXPathNewContext(xml);
-        if (!*ctxt) {
-            virReportOOMError();
-            goto error;
-        }
-        (*ctxt)->node = xmlDocGetRootElement(xml);
-    }
-
-cleanup:
-    xmlFreeParserCtxt(pctxt);
-
-    return xml;
-
-error:
-    xmlFreeDoc(xml);
-    xml = NULL;
-
-    if (virGetLastError() == NULL) {
-        virGenericReportError(domcode, VIR_ERR_XML_ERROR,
-                              "%s", _("failed to parse xml document"));
-    }
-    goto cleanup;
-}
-
-const char *virXMLPickShellSafeComment(const char *str1, const char *str2)
-{
-    if (str1 && !strpbrk(str1, "\r\t\n !\"#$&'()*;<>?[\\]^`{|}~") &&
-        !strstr(str1, "--"))
-        return str1;
-    if (str2 && !strpbrk(str2, "\r\t\n !\"#$&'()*;<>?[\\]^`{|}~") &&
-        !strstr(str2, "--"))
-        return str2;
-    return NULL;
-}
-
-static int virXMLEmitWarning(int fd,
-                             const char *name,
-                             const char *cmd)
-{
-    size_t len;
-    const char *prologue =
-        "<!--\n"
-        "WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE\n"
-        "OVERWRITTEN AND LOST. Changes to this xml configuration should be made using:\n"
-        "  virsh ";
-    const char *epilogue =
-        "\n"
-        "or other application using the libvirt API.\n"
-        "-->\n\n";
-
-    if (fd < 0 || !cmd) {
-        errno = EINVAL;
-        return -1;
-    }
-
-    len = strlen(prologue);
-    if (safewrite(fd, prologue, len) != len)
-        return -1;
-
-    len = strlen(cmd);
-    if (safewrite(fd, cmd, len) != len)
-        return -1;
-
-    if (name) {
-        if (safewrite(fd, " ", 1) != 1)
-            return -1;
-
-        len = strlen(name);
-        if (safewrite(fd, name, len) != len)
-            return -1;
-    }
-
-    len = strlen(epilogue);
-    if (safewrite(fd, epilogue, len) != len)
-        return -1;
-
-    return 0;
-}
-
-
-struct virXMLRewriteFileData {
-    const char *warnName;
-    const char *warnCommand;
-    const char *xml;
-};
-
-static int
-virXMLRewriteFile(int fd, void *opaque)
-{
-    struct virXMLRewriteFileData *data = opaque;
-
-    if (data->warnCommand) {
-        if (virXMLEmitWarning(fd, data->warnName, data->warnCommand) < 0)
-            return -1;
-    }
-
-    if (safewrite(fd, data->xml, strlen(data->xml)) < 0)
-        return -1;
-
-    return 0;
-}
-
-int
-virXMLSaveFile(const char *path,
-               const char *warnName,
-               const char *warnCommand,
-               const char *xml)
-{
-    struct virXMLRewriteFileData data = { warnName, warnCommand, xml };
-
-    return virFileRewrite(path, S_IRUSR | S_IWUSR, virXMLRewriteFile, &data);
-}
-
-/* Returns the number of children of node, or -1 on error.  */
-long
-virXMLChildElementCount(xmlNodePtr node)
-{
-    long ret = 0;
-    xmlNodePtr cur = NULL;
-
-    /* xmlChildElementCount returns 0 on error, which isn't helpful;
-     * besides, it is not available in libxml2 2.6.  */
-    if (!node || node->type != XML_ELEMENT_NODE)
-        return -1;
-    cur = node->children;
-    while (cur) {
-        if (cur->type == XML_ELEMENT_NODE)
-            ret++;
-        cur = cur->next;
-    }
-    return ret;
-}
diff --git a/src/util/xml.h b/src/util/xml.h
deleted file mode 100644
index c3b05df..0000000
--- a/src/util/xml.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * xml.h: internal definitions used for XML parsing routines.
- */
-
-#ifndef __VIR_XML_H__
-# define __VIR_XML_H__
-
-# include "internal.h"
-
-# include <libxml/parser.h>
-# include <libxml/tree.h>
-# include <libxml/xpath.h>
-
-int              virXPathBoolean(const char *xpath,
-                                 xmlXPathContextPtr ctxt);
-char *            virXPathString(const char *xpath,
-                                 xmlXPathContextPtr ctxt);
-char *       virXPathStringLimit(const char *xpath,
-                                 size_t maxlen,
-                                 xmlXPathContextPtr ctxt);
-int               virXPathNumber(const char *xpath,
-                                 xmlXPathContextPtr ctxt,
-                                 double *value);
-int                  virXPathInt(const char *xpath,
-                                 xmlXPathContextPtr ctxt,
-                                 int *value);
-int                 virXPathUInt(const char *xpath,
-                                 xmlXPathContextPtr ctxt,
-                                 unsigned int *value);
-int                 virXPathLong(const char *xpath,
-                                 xmlXPathContextPtr ctxt,
-                                 long *value);
-int                virXPathULong(const char *xpath,
-                                 xmlXPathContextPtr ctxt,
-                                 unsigned long *value);
-int            virXPathULongLong(const char *xpath,
-                                 xmlXPathContextPtr ctxt,
-                                 unsigned long long *value);
-int             virXPathLongLong(const char *xpath,
-                                 xmlXPathContextPtr ctxt,
-                                 long long *value);
-int              virXPathLongHex(const char *xpath,
-                                 xmlXPathContextPtr ctxt,
-                                 long *value);
-int             virXPathULongHex(const char *xpath,
-                                 xmlXPathContextPtr ctxt,
-                                 unsigned long *value);
-xmlNodePtr          virXPathNode(const char *xpath,
-                                 xmlXPathContextPtr ctxt);
-int              virXPathNodeSet(const char *xpath,
-                                 xmlXPathContextPtr ctxt,
-                                 xmlNodePtr **list);
-char *          virXMLPropString(xmlNodePtr node,
-                                 const char *name);
-long     virXMLChildElementCount(xmlNodePtr node);
-
-/* Internal function; prefer the macros below.  */
-xmlDocPtr      virXMLParseHelper(int domcode,
-                                 const char *filename,
-                                 const char *xmlStr,
-                                 const char *url,
-                                 xmlXPathContextPtr *pctxt);
-
-const char *virXMLPickShellSafeComment(const char *str1, const char *str2);
-/**
- * virXMLParse:
- * @filename: file to parse, or NULL for string parsing
- * @xmlStr: if @filename is NULL, a string to parse
- * @url: if @filename is NULL, an optional filename to attribute the parse to
- *
- * Parse xml from either a file or a string.
- *
- * Return the parsed document object, or NULL on failure.
- */
-# define virXMLParse(filename, xmlStr, url)                     \
-    virXMLParseHelper(VIR_FROM_THIS, filename, xmlStr, url, NULL)
-
-/**
- * virXMLParseString:
- * @xmlStr: a string to parse
- * @url: an optional filename to attribute the parse to
- *
- * Parse xml from a string.
- *
- * Return the parsed document object, or NULL on failure.
- */
-# define virXMLParseString(xmlStr, url)                         \
-    virXMLParseHelper(VIR_FROM_THIS, NULL, xmlStr, url, NULL)
-
-/**
- * virXMLParseFile:
- * @filename: file to parse
- *
- * Parse xml from a file.
- *
- * Return the parsed document object, or NULL on failure.
- */
-# define virXMLParseFile(filename)                              \
-    virXMLParseHelper(VIR_FROM_THIS, filename, NULL, NULL, NULL)
-
-/**
- * virXMLParseCtxt:
- * @filename: file to parse, or NULL for string parsing
- * @xmlStr: if @filename is NULL, a string to parse
- * @url: if @filename is NULL, an optional filename to attribute the parse to
- * @pctxt: if non-NULL, populate with a new context object on success,
- * with (*pctxt)->node pre-set to the root node
- *
- * Parse xml from either a file or a string.
- *
- * Return the parsed document object, or NULL on failure.
- */
-# define virXMLParseCtxt(filename, xmlStr, url, pctxt)                  \
-    virXMLParseHelper(VIR_FROM_THIS, filename, xmlStr, url, pctxt)
-
-/**
- * virXMLParseStringCtxt:
- * @xmlStr: a string to parse
- * @url: an optional filename to attribute the parse to
- * @pctxt: if non-NULL, populate with a new context object on success,
- * with (*pctxt)->node pre-set to the root node
- *
- * Parse xml from a string.
- *
- * Return the parsed document object, or NULL on failure.
- */
-# define virXMLParseStringCtxt(xmlStr, url, pctxt)              \
-    virXMLParseHelper(VIR_FROM_THIS, NULL, xmlStr, url, pctxt)
-
-/**
- * virXMLParseFileCtxt:
- * @filename: file to parse
- * @pctxt: if non-NULL, populate with a new context object on success,
- * with (*pctxt)->node pre-set to the root node
- *
- * Parse xml from a file.
- *
- * Return the parsed document object, or NULL on failure.
- */
-# define virXMLParseFileCtxt(filename, pctxt)                           \
-    virXMLParseHelper(VIR_FROM_THIS, filename, NULL, NULL, pctxt)
-
-int virXMLSaveFile(const char *path,
-                   const char *warnName,
-                   const char *warnCommand,
-                   const char *xml);
-
-#endif                          /* __VIR_XML_H__ */
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
index 4cbe827..c35695a 100644
--- a/src/xen/xen_driver.c
+++ b/src/xen/xen_driver.c
@@ -53,7 +53,7 @@
 #if WITH_XEN_INOTIFY
 # include "xen_inotify.h"
 #endif
-#include "xml.h"
+#include "virxml.h"
 #include "virutil.h"
 #include "viralloc.h"
 #include "node_device_conf.h"
diff --git a/tests/cputest.c b/tests/cputest.c
index ee1a608..6505367 100644
--- a/tests/cputest.c
+++ b/tests/cputest.c
@@ -31,7 +31,7 @@
 #include <fcntl.h>
 
 #include "internal.h"
-#include "xml.h"
+#include "virxml.h"
 #include "viralloc.h"
 #include "virbuffer.h"
 #include "testutils.h"
diff --git a/tests/nwfilterxml2xmltest.c b/tests/nwfilterxml2xmltest.c
index 8c29a46..a215bf8 100644
--- a/tests/nwfilterxml2xmltest.c
+++ b/tests/nwfilterxml2xmltest.c
@@ -10,7 +10,7 @@
 
 #include "internal.h"
 #include "testutils.h"
-#include "xml.h"
+#include "virxml.h"
 #include "virthread.h"
 #include "nwfilter_params.h"
 #include "nwfilter_conf.h"
diff --git a/tests/sexpr2xmltest.c b/tests/sexpr2xmltest.c
index 9b9b09d..07f6f8e 100644
--- a/tests/sexpr2xmltest.c
+++ b/tests/sexpr2xmltest.c
@@ -5,7 +5,7 @@
 #include <unistd.h>
 
 #include "internal.h"
-#include "xml.h"
+#include "virxml.h"
 #include "datatypes.h"
 #include "xen/xen_driver.h"
 #include "xen/xend_internal.h"
diff --git a/tests/virshtest.c b/tests/virshtest.c
index 8741d47..b82a4c4 100644
--- a/tests/virshtest.c
+++ b/tests/virshtest.c
@@ -5,7 +5,7 @@
 #include <unistd.h>
 
 #include "internal.h"
-#include "xml.h"
+#include "virxml.h"
 #include "virutil.h"
 #include "testutils.h"
 
diff --git a/tests/xencapstest.c b/tests/xencapstest.c
index 387e278..b3f7d62 100644
--- a/tests/xencapstest.c
+++ b/tests/xencapstest.c
@@ -6,7 +6,7 @@
 #include <unistd.h>
 
 #include "internal.h"
-#include "xml.h"
+#include "virxml.h"
 #include "testutils.h"
 #include "xen/xen_hypervisor.h"
 #include "virfile.h"
diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
index a443988..f4940fa 100644
--- a/tools/virsh-domain-monitor.c
+++ b/tools/virsh-domain-monitor.c
@@ -37,7 +37,7 @@
 #include "viralloc.h"
 #include "virmacaddr.h"
 #include "virsh-domain.h"
-#include "xml.h"
+#include "virxml.h"
 
 static const char *
 vshDomainIOErrorToString(int error)
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 244ffb8..3a9cebe 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -51,7 +51,7 @@
 #include "virsh-domain-monitor.h"
 #include "virterror_internal.h"
 #include "virtypedparam.h"
-#include "xml.h"
+#include "virxml.h"
 
 /* Gnulib doesn't guarantee SA_SIGINFO support.  */
 #ifndef SA_SIGINFO
diff --git a/tools/virsh-host.c b/tools/virsh-host.c
index 0ad4296..45b89a8 100644
--- a/tools/virsh-host.c
+++ b/tools/virsh-host.c
@@ -36,7 +36,7 @@
 #include "viralloc.h"
 #include "virutil.h"
 #include "virsh-domain.h"
-#include "xml.h"
+#include "virxml.h"
 #include "virtypedparam.h"
 #include "virjson.h"
 
diff --git a/tools/virsh-interface.c b/tools/virsh-interface.c
index ea8a6c5..cd14e89 100644
--- a/tools/virsh-interface.c
+++ b/tools/virsh-interface.c
@@ -35,7 +35,7 @@
 #include "virbuffer.h"
 #include "viralloc.h"
 #include "virutil.h"
-#include "xml.h"
+#include "virxml.h"
 
 virInterfacePtr
 vshCommandOptInterfaceBy(vshControl *ctl, const vshCmd *cmd,
diff --git a/tools/virsh-network.c b/tools/virsh-network.c
index 918dee6..c9cd15a 100644
--- a/tools/virsh-network.c
+++ b/tools/virsh-network.c
@@ -35,7 +35,7 @@
 #include "virbuffer.h"
 #include "viralloc.h"
 #include "virutil.h"
-#include "xml.h"
+#include "virxml.h"
 #include "conf/network_conf.h"
 
 virNetworkPtr
diff --git a/tools/virsh-nodedev.c b/tools/virsh-nodedev.c
index 974e495..f9517cc 100644
--- a/tools/virsh-nodedev.c
+++ b/tools/virsh-nodedev.c
@@ -35,7 +35,7 @@
 #include "virbuffer.h"
 #include "viralloc.h"
 #include "virutil.h"
-#include "xml.h"
+#include "virxml.h"
 #include "conf/node_device_conf.h"
 
 /*
diff --git a/tools/virsh-nwfilter.c b/tools/virsh-nwfilter.c
index 1480d13..9341ea7 100644
--- a/tools/virsh-nwfilter.c
+++ b/tools/virsh-nwfilter.c
@@ -35,7 +35,7 @@
 #include "virbuffer.h"
 #include "viralloc.h"
 #include "virutil.h"
-#include "xml.h"
+#include "virxml.h"
 
 virNWFilterPtr
 vshCommandOptNWFilterBy(vshControl *ctl, const vshCmd *cmd,
diff --git a/tools/virsh-pool.c b/tools/virsh-pool.c
index b3177e0..adac7f1 100644
--- a/tools/virsh-pool.c
+++ b/tools/virsh-pool.c
@@ -35,7 +35,7 @@
 #include "virbuffer.h"
 #include "viralloc.h"
 #include "virutil.h"
-#include "xml.h"
+#include "virxml.h"
 #include "conf/storage_conf.h"
 
 virStoragePoolPtr
diff --git a/tools/virsh-secret.c b/tools/virsh-secret.c
index a29454f..8297743 100644
--- a/tools/virsh-secret.c
+++ b/tools/virsh-secret.c
@@ -36,7 +36,7 @@
 #include "virbuffer.h"
 #include "viralloc.h"
 #include "virutil.h"
-#include "xml.h"
+#include "virxml.h"
 
 static virSecretPtr
 vshCommandOptSecret(vshControl *ctl, const vshCmd *cmd, const char **name)
diff --git a/tools/virsh-snapshot.c b/tools/virsh-snapshot.c
index 8428282..3b179e2 100644
--- a/tools/virsh-snapshot.c
+++ b/tools/virsh-snapshot.c
@@ -38,7 +38,7 @@
 #include "viralloc.h"
 #include "virutil.h"
 #include "virsh-domain.h"
-#include "xml.h"
+#include "virxml.h"
 #include "conf/snapshot_conf.h"
 
 /* Helper for snapshot-create and snapshot-create-as */
diff --git a/tools/virsh-volume.c b/tools/virsh-volume.c
index 6f2c591..a57fc28 100644
--- a/tools/virsh-volume.c
+++ b/tools/virsh-volume.c
@@ -39,7 +39,7 @@
 #include "virutil.h"
 #include "virfile.h"
 #include "virsh-pool.h"
-#include "xml.h"
+#include "virxml.h"
 
 virStorageVolPtr
 vshCommandOptVolBy(vshControl *ctl, const vshCmd *cmd,
diff --git a/tools/virsh.c b/tools/virsh.c
index bfeaaa1..790cf56 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -60,7 +60,7 @@
 #include "console.h"
 #include "virutil.h"
 #include "viralloc.h"
-#include "xml.h"
+#include "virxml.h"
 #include "libvirt/libvirt-qemu.h"
 #include "virfile.h"
 #include "configmake.h"
-- 
1.7.11.7

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list


[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]