diff --git a/include/libxml/xpath.h b/include/libxml/xpath.h index 8819a290..d96776c5 100644 --- a/include/libxml/xpath.h +++ b/include/libxml/xpath.h @@ -508,6 +508,13 @@ XMLPUBFUN int XMLCALL */ XMLPUBFUN long XMLCALL xmlXPathOrderDocElems (xmlDocPtr doc); +XMLPUBFUN int XMLCALL + xmlXPathSetContextNode (xmlNodePtr node, + xmlXPathContextPtr ctx); +XMLPUBFUN xmlXPathObjectPtr XMLCALL + xmlXPathNodeEval (xmlNodePtr node, + const xmlChar *str, + xmlXPathContextPtr ctx); XMLPUBFUN xmlXPathObjectPtr XMLCALL xmlXPathEval (const xmlChar *str, xmlXPathContextPtr ctx); diff --git a/xpath.c b/xpath.c index c5b6aeb7..97410e7b 100644 --- a/xpath.c +++ b/xpath.c @@ -15078,6 +15078,49 @@ xmlXPathEval(const xmlChar *str, xmlXPathContextPtr ctx) { return(res); } +/** + * xmlXPathSetContextNode: + * @node: the node to to use as the context node + * @ctx: the XPath context + * + * Sets 'node' as the context node. The node must be in the same + * document as that associated with the context. + * + * Returns -1 in case of error or 0 if successful + */ +int +xmlXPathSetContextNode(xmlNodePtr node, xmlXPathContextPtr ctx) { + if ((node == NULL) || (ctx == NULL)) + return(-1); + + if (node->doc == ctx->doc) { + ctx->node = node; + return(0); + } + return(-1); +} + +/** + * xmlXPathNodeEval: + * @node: the node to to use as the context node + * @str: the XPath expression + * @ctx: the XPath context + * + * Evaluate the XPath Location Path in the given context. The node 'node' + * is set as the context node. The context node is not restored. + * + * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL. + * the caller has to free the object. + */ +xmlXPathObjectPtr +xmlXPathNodeEval(xmlNodePtr node, const xmlChar *str, xmlXPathContextPtr ctx) { + if (str == NULL) + return(NULL); + if (xmlXPathSetContextNode(node, ctx) < 0) + return(NULL); + return(xmlXPathEval(str, ctx)); +} + /** * xmlXPathEvalExpression: * @str: the XPath expression