0

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

4 回答 4

0

但是,您在 java 中进行迭代,您的上下文节点可能不是您想的那样,所以删除“。” 你local-name(.)喜欢这样的说明符:

/*[local-name()='Header']/*[local-name()='TestInfo']/@testID使用您的 XML 对我来说工作得很好,尽管正如 akaIDIOT 所说,没有<Envelope>可以看到的标签。

于 2013-02-08T15:28:39.293 回答
0

您提供的 XML 文件不包含<Envelope>元素,因此需要它的表达式永远不会匹配。

后期编辑

从您的 XML 片段可以看出,该文档对您尝试匹配的元素使用特定的命名空间。XPath 引擎是名称空间感知的,这意味着您必须准确地询问它您需要什么。而且,请记住,名称空间是由其 uri 定义的,而不是由其缩写定义的(因此,除非您让 XPath 引擎知道名称空间所指的/namespace:element内容,否则不会做太多事情)。namespace

于 2013-02-08T15:20:50.303 回答
0

如果您不关心名称空间并使用 XPath 2.0 兼容引擎,请使用*它。

//*:Header/*:TestInfo/@testID

将返回所需的输入。

注册所需的名称空间(此处未介绍,取决于您的 XPath 引擎)并使用这些进行查询可能会更优雅:

//soapenv:Header/common:TestInfo/@testID
于 2013-02-08T15:43:48.053 回答
0

你的第一个 XPath 有一个额外的local-name()包裹整个事情:

local-name(/*[local-name(.)='Envelope']/*[local-name(.)='Header']
                                                         /*[local-name(.)='TestInfo'])

如果找到节点,则此 XPath 的结果将是字符串值“TestInfo” TestInfo,否则将是空白字符串。

如果您的 XML 的结构像您说的那样,那么这应该可以工作:

/*[local-name()='Envelope']/*[local-name()='Header']/*[local-name()='TestInfo']/@testID

但最好是,您应该正确使用命名空间而不是 (ab)using local-name()我在这里有一篇文章,展示了如何在 Java 中执行此操作。

于 2013-02-08T17:19:00.647 回答