我是从 Pro XML Development with Java 自学的XPath。为了练习,我构建了一个示例XML文档和一些XPath表达式 下面是一些XPath表达式及其解释和一些相关问题。如果我的解释错误,请纠正我,并在适用的地方回答问题。
<?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
说明:将选择<name>..</name>
中包含的<people>
元素,使<student>
具有名为scholarship
的属性,其值为{{1} }}
问题:这还会选择John中的值????
表达式2: Yes
说明:将选择元素/people/student[2]
中第2个位置的元素<student>..</student>
问题:它还会选择其中的子节点吗?
表达式3: <people>
说明:将在元素学生中选择属性奖学金。如果有多个/people/student/@scholarship
,那么它会选择多个属性
表达式4: <student scholarship="">
说明:将选择所有//name[ancestor::student]
元素
<name>..</name>
表示“所有后代”。在我的背景下,它意味着'我不在乎后代是谁
只要我的直系祖先是学生
答案 0 :(得分:2)
所有四个XPath表达式都选择输入树中的节点,如果使用XPath 1.0,则此类XPath表达式返回一组节点(其中集合可以为空或包含输入树的一个或多个节点),如果使用XPath 2.0这样的表达式返回一系列节点(也可以是空的,或者可以包含输入树的一个或多个节点)。
name
元素节点,此节点包含值为John
的单个文本节点。 student
元素节点,student
元素节点有几个子节点(并且XPath选择只是在输入树中选择一个节点,它不会修改任何事情或创建新节点。)scholarship
属性节点,如果输入XML包含多个student
属性scholarship
个元素节点,则它会选择多个此类节点。//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
相同。 答案 1 :(得分:2)
表情1:
/people/student[@scholarship='Yes']/name
说明:将选择包含在中的元素.. 这样有一个名为scholarship的属性 是的问题问题:这还会选择约翰中的值????
此表达式选择任何(所有)name
元素,该元素是student
元素的子元素(其scholarship
属性具有字符串值为字符串“yes”)并且这是一个XML文档的顶部元素(名为people
)的子元素。 XPath不选择“值” - 它选择节点。在这种情况下,字符串“John”是所选name
元素的字符串值。选定的name
元素具有单个子文本节点,其字符串值为“John”。
表达式2:/ people / student [2]说明:将选择元素 ..位于元素的第2位置 问题:它还会选择?
中的子节点
这将选择top元素的第二个(按文档顺序)student
子元素(其名称必须为people
)。所选元素的子节点本身不会被选中。可以使用count()
函数获取所选节点的数量:
count(/people/student[2])
它是1
- 这意味着只选择了元素(但不是它的子元素或后代)。
表达式3:/ people / student / @ scholarship说明:将选择 元素学生的属性奖学金。如果有的话 多个然后它会选择多个 属性
这将选择任何scholarship
元素的student
属性,该元素是top元素的子元素(其名称必须为people
)。这意味着,如果有student
个元素是people
顶部元素的子元素,并且每个元素都具有scholarship
属性,则会选择N个奖学金属性。
表达式4:// name [ancestor :: student]说明:将全部选中 ..元素//表示'所有后代'。在我的 语境意味着“我不关心后代和我一样长 直系祖先是学生
这将选择具有name
祖先的所有student
个元素(此祖先不仅可以是直接父级,也可以是直接父级的祖先)。
这里可以编写一个不包含任何反向轴的等效XPath表达式:
//student//name
如果您想要选择其父级为name
元素的所有student
元素,则表达此方法的一种方法是:
//student/name
最后,我建议使用XPath Visualizer(我在12年前创建的)这样的工具,帮助成千上万的人通过玩耍和玩乐来学习XPath 。