This change adjusts the XML parsing routines so that they will
preserve the context node when evaluating XPath expressions.
This allows us to use relative XPath expressions reliably in
the parsers. Needed one tiny fix to a typo in the Xen driver to
work
xml.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
Daniel
diff -r e72258d9d0d1 src/xml.c
--- a/src/xml.c Mon Jul 07 11:13:21 2008 +0100
+++ b/src/xml.c Mon Jul 07 11:37:50 2008 +0100
@@ -386,6 +386,7 @@
virXPathString(const char *xpath, xmlXPathContextPtr ctxt)
{
xmlXPathObjectPtr obj;
+ xmlNodePtr relnode;
char *ret;
if ((ctxt == NULL) || (xpath == NULL)) {
@@ -393,6 +394,7 @@
_("Invalid parameter to virXPathString()"), 0);
return (NULL);
}
+ relnode = ctxt->node;
obj = xmlXPathEval(BAD_CAST xpath, ctxt);
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
@@ -404,6 +406,7 @@
if (ret == NULL) {
virXMLError(NULL, VIR_ERR_NO_MEMORY, _("strdup failed"), 0);
}
+ ctxt->node = relnode;
return (ret);
}
@@ -422,21 +425,25 @@
virXPathNumber(const char *xpath, xmlXPathContextPtr ctxt, double *value)
{
xmlXPathObjectPtr obj;
+ xmlNodePtr relnode;
if ((ctxt == NULL) || (xpath == NULL) || (value == NULL)) {
virXMLError(NULL, VIR_ERR_INTERNAL_ERROR,
_("Invalid parameter to virXPathNumber()"), 0);
return (-1);
}
+ relnode = ctxt->node;
obj = xmlXPathEval(BAD_CAST xpath, ctxt);
if ((obj == NULL) || (obj->type != XPATH_NUMBER) ||
(isnan(obj->floatval))) {
xmlXPathFreeObject(obj);
+ ctxt->node = relnode;
return (-1);
}
*value = obj->floatval;
xmlXPathFreeObject(obj);
+ ctxt->node = relnode;
return (0);
}
@@ -456,6 +463,7 @@
virXPathLong(const char *xpath, xmlXPathContextPtr ctxt, long *value)
{
xmlXPathObjectPtr obj;
+ xmlNodePtr relnode;
int ret = 0;
if ((ctxt == NULL) || (xpath == NULL) || (value == NULL)) {
@@ -463,6 +471,7 @@
_("Invalid parameter to virXPathNumber()"), 0);
return (-1);
}
+ relnode = ctxt->node;
obj = xmlXPathEval(BAD_CAST xpath, ctxt);
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
@@ -486,6 +495,7 @@
}
xmlXPathFreeObject(obj);
+ ctxt->node = relnode;
return (ret);
}
@@ -502,6 +512,7 @@
virXPathBoolean(const char *xpath, xmlXPathContextPtr ctxt)
{
xmlXPathObjectPtr obj;
+ xmlNodePtr relnode;
int ret;
if ((ctxt == NULL) || (xpath == NULL)) {
@@ -509,6 +520,7 @@
_("Invalid parameter to virXPathBoolean()"), 0);
return (-1);
}
+ relnode = ctxt->node;
obj = xmlXPathEval(BAD_CAST xpath, ctxt);
if ((obj == NULL) || (obj->type != XPATH_BOOLEAN) ||
(obj->boolval < 0) || (obj->boolval > 1)) {
@@ -518,6 +530,7 @@
ret = obj->boolval;
xmlXPathFreeObject(obj);
+ ctxt->node = relnode;
return (ret);
}
@@ -535,6 +548,7 @@
virXPathNode(const char *xpath, xmlXPathContextPtr ctxt)
{
xmlXPathObjectPtr obj;
+ xmlNodePtr relnode;
xmlNodePtr ret;
if ((ctxt == NULL) || (xpath == NULL)) {
@@ -542,16 +556,19 @@
_("Invalid parameter to virXPathNode()"), 0);
return (NULL);
}
+ relnode = ctxt->node;
obj = xmlXPathEval(BAD_CAST xpath, ctxt);
if ((obj == NULL) || (obj->type != XPATH_NODESET) ||
(obj->nodesetval == NULL) || (obj->nodesetval->nodeNr <= 0) ||
(obj->nodesetval->nodeTab == NULL)) {
xmlXPathFreeObject(obj);
+ ctxt->node = relnode;
return (NULL);
}
ret = obj->nodesetval->nodeTab[0];
xmlXPathFreeObject(obj);
+ ctxt->node = relnode;
return (ret);
}
@@ -571,6 +588,7 @@
xmlNodePtr ** list)
{
xmlXPathObjectPtr obj;
+ xmlNodePtr relnode;
int ret;
if ((ctxt == NULL) || (xpath == NULL)) {
@@ -578,6 +596,7 @@
_("Invalid parameter to virXPathNodeSet()"), 0);
return (-1);
}
+ relnode = ctxt->node;
obj = xmlXPathEval(BAD_CAST xpath, ctxt);
if ((obj == NULL) || (obj->type != XPATH_NODESET) ||
(obj->nodesetval == NULL) || (obj->nodesetval->nodeNr <= 0) ||
@@ -585,6 +604,7 @@
xmlXPathFreeObject(obj);
if (list != NULL)
*list = NULL;
+ ctxt->node = relnode;
return (-1);
}
@@ -601,6 +621,7 @@
}
}
xmlXPathFreeObject(obj);
+ ctxt->node = relnode;
return (ret);
}
@@ -1139,7 +1160,7 @@
goto error;
virBufferVSprintf(buf, "(serial %s)", scratch);
} else {
- res = virXPathBoolean("count(domain/devices/console) > 0", ctxt);
+ res = virXPathBoolean("count(/domain/devices/console) > 0", ctxt);
if (res < 0) {
virXMLError(conn, VIR_ERR_XML_ERROR, NULL, 0);
goto error;
--
|: Red Hat, Engineering, London -o-
http://people.redhat.com/berrange/ :|
|:
http://libvirt.org -o-
http://virt-manager.org -o-
http://ovirt.org :|
|:
http://autobuild.org -o-
http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|