【问题标题】:Getting started with XPathXPath 入门
【发布时间】:2013-05-06 15:45:47
【问题描述】:

我正在自学 Pro XML Development with Java 中的 XPath。为了练习,我构建了一个示例 XML 文档和一些 XPath 表达式。
下面是一些 XPath 表达式及其解释和一些相关问题。如果我的解释有误,请纠正我,并在适用的地方回答问题。

XML

<?xml version="1.0" encoding="UTF-8" ?>
<people>
    <student scholarship="Yes">
        <name>John</name>
        <course>Computer Technology</course>
        <semester>6</semester>
        <scheme>E</scheme>
    </student>

    <student>
        <name>Foo</name>
        <course>Industrial Electronics</course>
        <semester>6</semester>
        <scheme>E</scheme>
    </student>

    <grumpy-cat>
        <soup-noodle>
            <student>
                <name>Dingle</name>
                <course>Grumpiness</course>
                <semester>3</semester>
                <scheme>E</scheme>
            </student>
        </soup-noodle>
    </grumpy-cat>
</people>  

表达式 1: /people/student[@scholarship='Yes']/name
解释: 将选择 &lt;name&gt;..&lt;/name&gt; 包含在 &lt;people&gt; 中的元素,使得 &lt;student&gt; 具有属性命名为 scholarship 的值为 Yes
问题: 这是否也会选择其中的值 John ????

表达式 2: /people/student[2]
解释: 将选择元素 &lt;student&gt;..&lt;/student&gt; 在元素 &lt;people&gt; 中的第二个位置
问题: 是否也会选择其中的子节点?

表达式 3: /people/student/@scholarship
说明: 将在元素 student 中选择属性奖学金。如果有多个&lt;student scholarship=""&gt;,那么它会选择多个属性

表达式 4: //name[ancestor::student]
解释: 将选择所有 &lt;name&gt;..&lt;/name&gt; 元素
// 表示“所有后代” .在我的上下文中,它的意思是“我不在乎后代是谁 只要我的直系祖先是学生'

【问题讨论】:

    标签: java xpath


    【解决方案1】:

    表达式 1:/people/student[@scholarship='Yes']/name 解释:将选择元素 .. 包含在 这样有一个名为奖学金的属性 是的值问题:这是否也会选择其中的值约翰????

    此表达式选择任何(所有)name 元素,它是 student 元素的子元素(其 scholarship 属性的字符串值是字符串“yes”)并且是顶部元素的子元素 (名为 people) 的 XML 文档。 XPath 不选择“值”——它选择节点。在这种情况下,字符串“John”是所选name 元素的字符串值。选中的name 元素有一个子文本节点,其字符串值为“John”。

    表达式2:/people/student[2] 解释:将选择元素 .. 位于元素中的第二个位置 问题:它还会选择其中的子节点吗?

    这将选择顶部元素(其名称必须为 people)的第二个(按文档顺序)student 子元素。所选元素的子节点本身不会被选中。可以使用count()函数获取选中的节点数:

    count(/people/student[2])
    

    它是1——这意味着只有元素(而不是它的子元素或后代)被选中。

    表达式 3:/people/student/@scholarship 解释:将选择 元素学生中的属性奖学金。如果有 多个然后它将选择多个 属性

    这将选择作为顶部元素(其名称必须为people)的子元素的任何student 元素的scholarship 属性。这意味着,如果有 N 个 student 元素是 people 顶级元素的子元素,并且每个元素都有一个 scholarship 属性,则将选择 N 个奖学金属性。

    表达式 4: //name[ancestor::student] 解释:将全选 .. 元素 // 表示“所有的后代”。在我的 上下文它的意思是“我不在乎谁的后代,只要我的 直系祖先是学生'

    这将选择所有具有student 祖先的name 元素(并且此祖先可能不仅是直接父级,而且是直接父级的祖先)。

    这里可以编写一个不包含任何反向轴的等效 XPath 表达式:

    //student//name
    

    如果您想选择所有 name 元素,其父元素是 student 元素,一种表达方式是:

    //student/name
    

    最后,我建议使用像 XPath Visualizer(我在 12 年前创建的)这样的工具,它帮助成千上万的人通过玩耍和玩乐来学习 XPath

    【讨论】:

    • 您有兴趣成为我的导师吗? :D
    • @LittleChild,是的,我希望我在 SO 的回答能为大家提供知识和建议。
    • 你能推荐一个轻量级的XML可视化工具吗?我尝试了 NuBean 的 XMLEspresso,结果很糟糕!
    【解决方案2】:

    所有四个 XPath 表达式都选择输入树中的节点,如果您使用 XPath 1.0,则此类 XPath 表达式返回一组节点(其中该组可以为空或包含输入树的一个或多个节点),如果您使用XPath 2.0 此类表达式返回一系列节点(也可以是空的,也可以包含输入树的一个或多个节点)。

    1. 您的第一个表达式在给定的输入树中选择一个name 元素节点,该节点包含一个值为John 的文本节点。
    2. 您的第二个表达式在输入树中选择了一个student 元素节点,该student 元素节点有几个子节点(XPath 选择只是在输入树中选择一个节点,它不会修改任何内容或创建新的节点)。
    3. 您的第三个表达式选择了一个 scholarship 属性节点,如果输入 XML 包含多个具有 scholarship 属性的 student 元素节点,您是对的,它会选择几个这样的节点。
    4. 您的第四个表达式//name[ancestor::student]/descendant-or-self::node()/name[ancestor::student] 的缩写形式(参见http://www.w3.org/TR/xpath/#path-abbrev),它是/descendant-or-self::node()/child::name[ancestor::student] 的缩写形式。因此它选择了根节点的所有name 子元素以及根节点的所有后代节点,其中name 元素具有student 祖先元素节点。您对该表达式的解释是错误的,关于all the descendants 的部分(这至少是不精确的)以及my immediate ancestor is student。直接祖先是父级,在 XPath 中简单地表示为 parent::student,而您的 ancestor::student 查找所有级别的祖先。所有的后代都是/descendant::name。另一方面,// 的定义方式和您的下一步name //name 归结为与/descendant::name 相同。

    【讨论】:

      猜你喜欢
      • 2012-11-15
      • 2010-09-21
      • 1970-01-01
      • 1970-01-01
      • 2011-06-26
      • 2018-10-21
      • 2011-08-20
      • 2010-11-06
      • 2014-02-27
      相关资源
      最近更新 更多