我正在尝试使用XPath从xmel文件中检索属性的值,我不确定我的错误在哪里..
这是XML文件
<soapenv:Envelope>
<soapenv:Header>
<common:TestInfo testID="PI1" />
</soapenv:Header>
</soapenv:Envelope>
这是我用来获取价值的代码。这两个都没有返回..
XPathBuilder getTestID = new XPathBuilder("local-name(/*[local-name(.)='Envelope']/*[local-name(.)='Header']/*[local-name(.)='TestInfo'])");
XPathBuilder getTestID2 = new XPathBuilder("Envelope/Header/TestInfo/@testID");
Object doc2 = getTestID.evaluate(context, sourceXML);
Object doc3 = getTestID2.evaluate(context, sourceXML);
如何检索testID的值?
答案 0 :(得分:0)
您提供的XML文件不包含<Envelope>
元素,因此需要它的表达式永远不会匹配。
编辑后编辑
从XML片段中可以看出,该文档对您尝试匹配的元素使用特定的命名空间。 XPath引擎是名称空间感知的,这意味着您必须准确地询问它所需要的内容。并且,请记住,命名空间由其uri定义, not 由其缩写定义(因此,除非让XPath引擎知道命名空间{{/namespace:element
,否则namespace
不会做太多事情。 1}}指的是。
答案 1 :(得分:0)
但是你在java中进行迭代,你的上下文节点可能不是你想的那样,所以删除“。” local-name(.)
中的说明符如下:
/*[local-name()='Header']/*[local-name()='TestInfo']/@testID
使用您的XML工作得很好,尽管正如akaIDIOT所说,没有<Envelope>
标记可供查看。
答案 2 :(得分:0)
如果您不关心命名空间并使用兼容XPath 2.0的引擎,请使用*
。
//*:Header/*:TestInfo/@testID
将返回所需的输入。
注册所需的命名空间(这里没有涉及,取决于你的XPath引擎)和使用这些命令查询可能会更优雅:
//soapenv:Header/common:TestInfo/@testID
答案 3 :(得分:0)
你的第一个XPath包含了额外的local-name()
:
local-name(/*[local-name(.)='Envelope']/*[local-name(.)='Header']
/*[local-name(.)='TestInfo'])
如果找到TestInfo
节点,则此XPath的结果将是字符串值“TestInfo”,如果不是,则为空字符串。
如果你的XML结构与你说的一样,那么这应该有效:
/*[local-name()='Envelope']/*[local-name()='Header']/*[local-name()='TestInfo']/@testID
但最好是,您应该正确使用命名空间而不是(ab)使用local-name()
。我有一篇帖子here,展示了如何用Java做到这一点。