使用XPath获取属性

418

给定以下 XML 结构:

<?xml version="1.0" encoding="ISO-8859-1"?>

<bookstore>

<book>
  <title lang="eng">Harry Potter</title>
  <price>29.99</price>
</book>

<book>
  <title lang="eng">Learning XML</title>
  <price>39.95</price>
</book>

</bookstore>

如何获取第一个元素的书名中 lang 的值(其中lang在书名中为 eng)?


5
使用 XPath 时非常好的链接:http://test-able.blogspot.ie/2016/04/xpath-selectors-cheat-sheet.html。 - user7813528
8个回答

584

如何获取书名中第一个元素的lang(其中lang=eng)的值?

使用:

/*/book[1]/title/@lang

这意味着:

选择XML文档顶层元素的第一个book子元素下的title元素的lang属性。

要获取此属性的字符串值,请使用标准XPath函数string():

string(/*/book[1]/title/@lang)

3
评估XPath表达式的结果将确切地产生“ lang”属性的字符串值。如果该属性不包含任何方括号,它们将不会成为评估XPath表达式的结果的一部分。我猜测这些是您正在使用的(不适当的)工具添加的。 - Dimitre Novatchev
6
是的,我找到了问题所在。那只是SoapUI显示的方式,但是当我使用XPath值时,括号并没有被使用。我已经看到这种情况很多次了。问题不在于工具本身,而是出现在使用者这一端。 - Abhishek Asthana
7
@KorayTugay,XPath表达式 /*/book[1]/title/@lang选择 一个有0个或多个属性节点的节点集合,而XPath表达式 string(/*/book[1]/title/@lang) 在求值时会产生这个节点集合的字符串值 -- 这是该节点集合中第一个(按文档顺序)节点的字符串值。 - Dimitre Novatchev
5
@KorayTugay,不,第一个表达式是选择(selects),而不是“返回”--一组节点,并且这组节点不是一个字符串。节点不是字符串--节点是树中的节点。XML文档是节点树。lang="eng"只是属性节点的许多文本表示之一,该属性节点具有名称“lang”,不属于命名空间,并且具有字符串值“eng”。 - Dimitre Novatchev
2
@Vladimir,如果v对应于命名空间URI,例如:“my:vvv”,那么可以在正在使用XPath引擎的主机中创建一个映射,将myPrefix(可以是v,但不是必需的)关联到相同的命名空间URI“my:vvv”。然后,可以使用以下语法选择属性:title/@myPrefix:lang。如何创建这样的映射是特定于实现的,必须阅读XPath引擎主机的文档。在.NET中,会以一种特定的方式完成这项操作,在Saxon中则会以另一种方式完成。如果没有这样的映射,请使用以下语法:title/@*[name()='v:lang'] - Dimitre Novatchev
显示剩余12条评论

67

谢谢!这解决了我在

标签中使用数据属性时遇到的类似问题。

<div id="prop_sample" data-want="data I want">data I do not want</div>

使用此xpath: //*[@id="prop_sample"]/@data-want

希望这能帮助其他人!


5
您可以尝试以下xPath模式:
  XPathExpression expr = xPath.compile("/bookstore/book/title[@lang='eng']")

7
这将选择/bookstore/book下具有lang属性且该属性的值为eng的任何XML标题元素,而不是选择lang属性的值。也就是说,它选择的是一组元素,而不是单个属性。 - JFK

5
使用XPath提取属性值的标准公式为:
elementXPath/@attributeName

这里是提取第一个属性的“lang”值的XPath表达式 -
//title[text()='Harry Potter']/@lang

注意: 不建议在XPath中使用索引,因为如果再添加一个标题标签,则索引可能会更改。


2

您可以使用:

(//@lang)[1]

这意味着您获取所有名称等于“lang”的属性节点,并获取第一个。

2
如果您正在使用PostgreSQL,那么这是正确的获取方式。我们假设您有一个book表,其中包含填充数据的TITLEPRICE列。以下是查询语句:
SELECT xpath('/bookstore/book/title/@lang', xmlforest(book.title AS title, book.price AS price), ARRAY[ARRAY[]::TEXT[]]) FROM book LIMIT 1;

1

你也可以通过以下方式获取

string(//bookstore/book[1]/title/@lang)    
string(//bookstore/book[2]/title/@lang)

尽管如果您正在使用JavaScript的XMLDOM,您可以编写类似以下的代码
var n1 = uXmlDoc.selectSingleNode("//bookstore/book[1]/title/@lang");

而且 n1.text 将会给你值为 "eng"


0

这里是用XPath和VTD-XML获取“lang”属性值的代码片段。

import com.ximpleware.*;
public class getAttrVal {
    public static void main(String s[]) throws VTDException{
        VTDGen vg = new VTDGen();
        if (!vg.parseFile("input.xml", false)){
            return ;
        }
        VTDNav vn = vg.getNav();
        AutoPilot ap = new AutoPilot(vn);
        ap.selectXPath("/bookstore/book/title/@lang");
        System.out.println(" lang's value is ===>"+ap.evalXPathToString());
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接