Often, we want to use XPath functions on the just-parsed document;
fold this into the parser function for convenience.
* src/util/xml.h (virXMLParseHelper): Add argument.
(virXMLParseStrHelper, virXMLParseFileHelper): Delete.
(virXMLParseCtxt, virXMLParseStringCtxt, virXMLParseFileCtxt): New
macros.
* src/libvirt_private.syms (xml.h): Remove deleted functions.
* src/util/xml.c (virXMLParseHelper): Add argument.
(virXMLParseStrHelper, virXMLParseFileHelper): Delete.
---
src/libvirt_private.syms | 2 -
src/util/xml.c | 53 ++++++++---------------------
src/util/xml.h | 84 +++++++++++++++++++++++++++++++++++++++++-----
3 files changed, 90 insertions(+), 49 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index acae122..0618b49 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1164,9 +1164,7 @@ virKeycodeValueFromString;
virKeycodeValueTranslate;
# xml.h
-virXMLParseFileHelper;
virXMLParseHelper;
-virXMLParseStrHelper;
virXMLPropString;
virXPathBoolean;
virXPathInt;
diff --git a/src/util/xml.c b/src/util/xml.c
index 05317ea..d301af6 100644
--- a/src/util/xml.c
+++ b/src/util/xml.c
@@ -662,6 +662,7 @@ catchXMLError(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...)
* @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.
@@ -672,7 +673,8 @@ xmlDocPtr
virXMLParseHelper(int domcode,
const char *filename,
const char *xmlStr,
- const char *url)
+ const char *url,
+ xmlXPathContextPtr *ctxt)
{
struct virParserData private;
xmlParserCtxtPtr pctxt;
@@ -680,8 +682,10 @@ virXMLParseHelper(int domcode,
/* Set up a parser context so we can catch the details of XML errors. */
pctxt = xmlNewParserCtxt();
- if (!pctxt || !pctxt->sax)
+ if (!pctxt || !pctxt->sax) {
+ virReportOOMError();
goto error;
+ }
private.domcode = domcode;
pctxt->_private = &private;
@@ -705,6 +709,15 @@ virXMLParseHelper(int domcode,
goto error;
}
+ if (ctxt) {
+ *ctxt = xmlXPathNewContext(xml);
+ if (!*ctxt) {
+ virReportOOMError();
+ goto error;
+ }
+ (*ctxt)->node = xmlDocGetRootElement(xml);
+ }
+
cleanup:
xmlFreeParserCtxt(pctxt);
@@ -720,39 +733,3 @@ error:
}
goto cleanup;
}
-
-/**
- * virXMLParseStrHelper:
- * @domcode: error domain of the caller, usually VIR_FROM_THIS
- * @xmlStr: XML string to be parsed in case filename is NULL
- * @url: URL of XML document for string parser
- *
- * Parse XML document provided as a string. The function guarantees that
- * the XML document contains a root element.
- *
- * Returns parsed XML document.
- */
-xmlDocPtr
-virXMLParseStrHelper(int domcode,
- const char *xmlStr,
- const char *url)
-{
- return virXMLParseHelper(domcode, NULL, xmlStr, url);
-}
-
-/**
- * virXMLParseFileHelper:
- * @domcode: error domain of the caller, usually VIR_FROM_THIS
- * @filename: file to be parsed
- *
- * Parse XML document provided as a file. The function guarantees that
- * the XML document contains a root element.
- *
- * Returns parsed XML document.
- */
-xmlDocPtr
-virXMLParseFileHelper(int domcode,
- const char *filename)
-{
- return virXMLParseHelper(domcode, filename, NULL, NULL);
-}
diff --git a/src/util/xml.h b/src/util/xml.h
index b342e83..d30e066 100644
--- a/src/util/xml.h
+++ b/src/util/xml.h
@@ -53,23 +53,89 @@ int virXPathNodeSet(const char *xpath,
char * virXMLPropString(xmlNodePtr node,
const char *name);
+/* Internal function; prefer the macros below. */
xmlDocPtr virXMLParseHelper(int domcode,
const char *filename,
const char *xmlStr,
- const char *url);
-xmlDocPtr virXMLParseStrHelper(int domcode,
- const char *xmlStr,
- const char *url);
-xmlDocPtr virXMLParseFileHelper(int domcode,
- const char *filename);
+ const char *url,
+ xmlXPathContextPtr *pctxt);
+/**
+ * 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)
+ 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) \
- virXMLParseStrHelper(VIR_FROM_THIS, 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) \
- virXMLParseFileHelper(VIR_FROM_THIS, 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)
#endif /* __VIR_XML_H__ */
--
1.7.4.4