2013-02-08 65 views
0

我试图使用XPath检索的xmel文件属性的值,我不知道我要去的地方错了检索属性的值..使用XPath

这是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

您正在使用哪种“XPathBuilder”实现? – parsifal 2013-02-08 15:40:09

+0

请确保发布* valid * XML,'结束标签实际上是另一个开放标签。 – 2013-02-08 15:46:52

+1

可能是脱离主题,但是因为这涉及到SOAP:如果您尝试实现您自己的SOAP服务/请求解析器,请不要;你会削减自己在许多锋利的边缘之一。 – akaIDIOT 2013-02-08 15:57:22

回答

0

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

进行后期编辑编辑

如可以从XML片断中可以看出,该文件使用特定的命名空间,你想匹配的元素。 XPath引擎具有名称空间感知功能,这意味着您必须正确地询问您需要的内容。并且,请记住,名称空间是由其URI缩写而不是缩写(因此,除非让XPath引擎知道命名空间namespace引用的内容,否则/namespace:element不会做太多工作。

+0

我只是以横截面为例。需要XPath表达式的帮助.. – stinkyPete 2013-02-08 15:27:36

+1

虽然这是可以理解的,但是如果他们决定尝试,请始终为任何人提供足够的数据来重现问题。要求人们根据一半的问题提供帮助并不适用:) – akaIDIOT 2013-02-08 15:52:47

0

但是你在java中迭代,你的上下文节点可能不是你的想法,所以删除“。”在你的local-name(.)像这样说:

/*[local-name()='Header']/*[local-name()='TestInfo']/@testID/*[local-name()='Header']/*[local-name()='TestInfo']/@testID工作适合我用你的XML,虽然akaIDIOT说,没有<Envelope>标签被看到。

+0

我已经添加了Envelope标签以显示我拥有它们。 XPath字符串仍然不能与我的代码一起工作。 – stinkyPete 2013-02-08 15:36:15

+0

'local-name()'和'local-name(。)'之间没有区别。第一个只是一个字符短。 – JLRishe 2013-02-08 18:03:20

+0

好吧,这是多余的。 – JWiley 2013-02-08 18:05:05

0

如果您不在意名称空间并使用XPath 2.0兼容引擎,请使用*

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

将返回所需的输入。

这将可能是更优雅注册所需的命名空间(这里不是盖的,取决于你的XPath引擎)和查询使用这些:

//soapenv:Header/common:TestInfo/@testID 
+0

这些工作都没有..我很难倒。 – stinkyPete 2013-02-08 15:58:50

+0

这不是有效的XPath。您不能使用'*'作为名称空间前缀通配符。 – JLRishe 2013-02-08 18:04:52

+0

你是对的,它不是有效的XPath 1.0,但[在XPath 2.0中允许](http://developer.marklogic.com/blog/namespace-wildcards-in-xpath)。我把这个添加到我的回答中,谢谢。 – 2013-02-08 18:26:38

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)使用local-name()合作。我有一个帖子here,它显示了如何在Java中执行此操作。