鉴于以下文档,我想提取tns:EchoResponse
。 (为了便于阅读,对原始文档进行了美化。)
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<tns:EchoResponse
xmlns:tns="http://www.apis-it.hr/fin/2012/types/f73"
xsi:schemaLocation="http://www.apis-it.hr/fin/2012/types/f73 FiskalizacijaSchema.xsd "
>
hello
</tns:EchoResponse>
</soap:Body>
</soap:Envelope>
我已经解析了文档,创建了 XPath 上下文,注册了命名空间 soap
和 tns
,然后运行了查询使用以下 XPath 表达式。
//soap:Envelope[1]/soap:Body[1]/tns:EchoResponse[1]
不幸的是,只有忽略 namespace 并仅使用本地名称的查找似乎才有效:
//*[local-name(.) = 'Envelope']/*[local-name(.) = 'Body'][1]/*[local-name(.) = 'EchoResponse'][1]
那么...我做错了什么?我错误地假设了什么?这是处理此文档的代码片段。
xmlDocPtr xmldoc = xmlReadMemory(databuffer, datasize, ISFEndpointURL(), NULL, 0);
if(!xmldoc)
{
err = -1;
goto finalize;
}
xmlXPathContextPtr xpathCtx = xmlXPathNewContext(xmldoc);
if(!xpathCtx)
{
err = -1;
xmlFreeDoc(xmldoc);
goto finalize;
}
xmlXPathRegisterNs(xpathCtx, BAD_CAST "soap", BAD_CAST "http://schemas.xmlsoap.org/soap/envelope");
xmlXPathRegisterNs(xpathCtx, BAD_CAST "tns", BAD_CAST "http://www.apis-it.hr/fin/2012/types/f73");
// //soap:Envelope[1]/soap:Body[1]/*[local-name(.) = 'EchoResponse']
xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression(BAD_CAST "./*[local-name(.) = 'Envelope']/*[local-name(.) = 'Body'][1]/*[local-name(.) = 'EchoResponse'][1]", xpathCtx);
if(!xpathObj)
{
err = -1;
xmlXPathFreeContext(xpathCtx);
xmlFreeDoc(xmldoc);
goto finalize;
}
if(xmlXPathNodeSetIsEmpty(xpathObj->nodesetval)){
err = -1;
xmlXPathFreeObject(xpathObj);
xmlXPathFreeContext(xpathCtx);
xmlFreeDoc(xmldoc);
printf("%s: No XPath result\n", __FUNCTION__);
goto finalize;
}
if(strcmp((char *)xmlXPathCastNodeSetToString(xpathObj->nodesetval), echoText))
{
err = 1;
xmlXPathFreeObject(xpathObj);
xmlXPathFreeContext(xpathCtx);
xmlFreeDoc(xmldoc);
printf("%s: Incorrect echo result: %s\n", __FUNCTION__, xpathObj->stringval);
goto finalize;
}
xmlXPathFreeObject(xpathObj);
xmlXPathFreeContext(xpathCtx);
最佳答案
XML 文档中的 soap
前缀绑定(bind)到命名空间 URI
http://schemas.xmlsoap.org/soap/envelope/
而您的代码将 XPath 上下文中的 soap
前缀绑定(bind)到不同的 URI
http://schemas.xmlsoap.org/soap/envelope
XPath 不匹配任何内容,因为它正在寻找错误的命名空间。
关于c - 使用 libxml2 的 XPath 在 XML 文档中查找命名空间节点时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14585111/