简体   繁体   English

使用XPath检索属性的值

[英]Retrieve value of attribute using XPath

I am trying to retrieve the value of an attribute from an xmel file using XPath and I am not sure where I am going wrong.. 我正在尝试使用XPath从xmel文件中检索属性的值,但是我不确定我要去哪里。

This is the XML File 这是XML文件

<soapenv:Envelope>
  <soapenv:Header>
    <common:TestInfo testID="PI1" />
  </soapenv:Header>
</soapenv:Envelope>

And this is the code I am using to get the value. 这是我用来获取价值的代码。 Both of these return nothing.. 这两个都不返回。

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);

How can I retrieve the value of testID? 如何获取testID的值?

The XML file you provided does not contain an <Envelope> element, so an expression that requires it will never match. 您提供的XML文件不包含<Envelope>元素,因此需要它的表达式将永远不匹配。

Post-edit edit 编辑后编辑

As can be seen from your XML snippet, the document uses a specific namespace for the elements you're trying to match. 从您的XML代码段可以看出,该文档为您要匹配的元素使用了特定的名称空间。 An XPath engine is namespace-aware, meaning you'll have to ask it exactly what you need. XPath引擎支持名称空间,这意味着您必须确切地询问它所需要的内容。 And, keep in mind that a namespace is defined by its uri, not by its abbreviation (so, /namespace:element doesn't do much unless you let the XPath engine know what the namespace namespace refers to). 并且,请记住,名称空间是由其uri定义的, 而不是由其缩写定义的(因此, /namespace:element不会做很多事情,除非您让XPath引擎知道该名称namespace是指该名称namespace )。

However you're iterating within the java, your context node is probably not what you think, so remove the "." 但是,在Java中进行迭代时,上下文节点可能不是您想的那样,因此请删除“。” specifier in your local-name(.) like so: 您的local-name(.)说明符,如下所示:

/*[local-name()='Header']/*[local-name()='TestInfo']/@testID worked fine for me with your XML, although as akaIDIOT says, there isn't an <Envelope> tag to be seen. /*[local-name()='Header']/*[local-name()='TestInfo']/@testID对于您的XML来说对我来说效果很好,尽管正如akaIDIOT所说,没有<Envelope>待查看的标签。

If you don't care for the namespaces and use an XPath 2.0 compatible engine, use * for it. 如果您不关心名称空间,而使用XPath 2.0兼容引擎,请使用*

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

will return the desired input. 将返回所需的输入。

It will probably be more elegant to register the needed namespaces (not covered here, depends on your XPath engine) and query using these: 注册所需的名称空间(此处未涵盖,取决于您的XPath引擎)并使用以下命令进行查询可能会更优雅:

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

Your first XPath has an extra local-name() wrapped around the whole thing: 您的第一个XPath包含一个额外的local-name()围绕整个内容:

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

The result of this XPath will either be the string value "TestInfo" if the TestInfo node is found, or a blank string if it is not. 如果找到了TestInfo节点,则此XPath的结果将是字符串值“ TestInfo”,否则将是空白字符串。

If your XML is structured like you say it is, then this should work: 如果您的XML的结构如您所说的那样,那么这应该可以工作:

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

But preferably, you should be working with namespaces properly instead of (ab)using local-name() . 但最好是,您应该正确使用名称空间,而不是(ab)使用local-name() I have a post here that shows how to do this in Java. 我在这里有一篇文章,展示了如何在Java中执行此操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM