使用XPath检索属性的值

时间:2013-02-08 15:15:02

标签: java xml xpath

我正在尝试使用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的值?

4 个答案:

答案 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做到这一点。