首页 文章

XPath入门

提问于
浏览
1

我是从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>

Expression 1: /people/student[@scholarship='Yes']/name
Explanation: 将选择 <people> 中包含的元素 <name>..</name> ,使 <student> 具有名为 scholarship 的属性,其值为 Yes
Question: 这还会选择John中的值????

Expression 2: /people/student[2]
Explanation: 将选择元素 <student>..</student> ,它位于元素 <people> 的第2个位置
Question: 它还会选择其中的子节点吗?

Expression 3: /people/student/@scholarship
Explanation: 将在元素学生中选择属性奖学金 . 如果有多个 <student scholarship=""> 则会选择多个属性

Expression 4: //name[ancestor::student]
Explanation: 将选择所有 <name>..</name> 元素
// 表示'all-the-descendants' . 在我的背景下,它意味着,只要我的直系祖先是学生,后代就是在乎

2 回答

  • 2

    表达式1:/ people / student [@ scholarship ='Yes'] / name说明:将选择包含在其中的元素..具有名为scholarship的属性,值为Yes问题:这也会选择值约翰在里面????

    此表达式选择任何(所有) name 元素,该元素是 student 元素的子元素(其 scholarship 属性的字符串值为字符串"yes"),并且是XML文档的顶部元素(名为 people )的子元素 . XPath不选择"values" - 它选择节点 . 在这种情况下,字符串"John"是所选 name 元素的字符串值 . 选定的 name 元素具有单个子文本节点,其字符串值为"John" .

    表达式2:/ people / student [2]说明:将选择元素位于元素中的第2位置问题:它是否也会选择其中的子节点?

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

    count(/people/student[2])
    

    它是 1 - 这意味着只选择了元素(但不是它的子元素或后代) .

    表达式3:/ people / student / @ scholarship说明:将在元素学生中选择属性奖学金 . 如果有多个则会选择多个属性

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

    表达式4:// name [ancestor :: student]说明:将选择所有..元素//表示'all-the-descendants' . 在我的背景下,它意味着“我不关心后代是谁,只要我的直系祖先是学生”

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

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

    //student//name
    

    如果您想要选择父级为 student 元素的所有 name 元素,表达方式的一种方法是:

    //student/name
    

    Finally, I would recommend using a tool like the XPath Visualizer (which I created 12 years ago) that has helped many thousands of people learn XPath by playing and having fun .

  • 2

    所有四个XPath表达式都选择输入树中的节点,如果你使用XPath 1.0这样的XPath表达式返回一组节点(其中set可以是空的或包含输入树的一个或多个节点),如果你使用XPath 2.0这样的话表达式返回一系列节点(也可以是空的,或者可以包含输入树的一个或多个节点) .

    • 您的第一个表达式在给定输入树中选择一个 name 元素节点,此节点包含值为 John 的单个文本节点 .

    • 您的第二个表达式选择输入树中的 student 元素节点, student 元素节点具有多个子节点(并且XPath选择只是在输入树中选择一个节点,它不会修改任何内容或创建新节点) .

    • 你的第三个表达式选择一个 scholarship 属性节点,如果输入XML包含几个具有 scholarship 属性的 student 元素节点,则它会选择几个这样的节点 .

    • 您的第四个表达式 //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 相同 .

相关问题