|
说到底还是上下文的关系~!
一.例题:
last() 属于聚合运算 他是针对上下文的集合再运算的。
1. xpath: //a/c[last()]
//a/c 就是红色部位,[last()] 针对的的上下文为:只有唯一的元素父节点a 。
所以是兄弟关系的集合中取最后一个,结果为 大福将2
2. xpath: (//a/c)[last()]
[last()] 的上下文是 (//a/c)的集合。 ()是优先运算符,把//a/c作为一个集合然后再在里面找最后一个
结果为:大福将2
3.xpath: //c[last()] [last()] 针对的是每个 //c的同个父节点的儿子的集合,这里可以分成 橙色 和红色两部分
父节点 b和 a,兄弟集合 分别为 【丐帮财经大福将】;【大福将1、大福将2】,分别取最后的节点,结果为: 【丐帮财经大福将】 和 【大福将2】
总的来说,就是分别对每个岔路口重复上下文关系运算。用括号就是把所有的岔路口都归为一个,然后再上下文运算。
二. 对于 最后的例子也是同样的
//b/@甲组[not(.=preceding::b/@甲组)] 、(//b/@甲组)[not(.=preceding::b/@甲组)]
1. //b/@甲组: 这里是【每个b节点下甲组属性值集合(上下文独立的)】组成的
每个b下面有一个集合,即使是一个值。一个集合就是一个上下文。
2. (//b/@甲组) :所有b节点下甲组属性值的集合(是一个整体集合)
后面的谓词运算 【not(.=preceding::b/@甲组)】 都是每个单独历遍并运算 所以 //b/@甲组 和 (//b/@甲组)没有区别。
如果用 //b/@甲组[last()] 和 (//b/@甲组)[last()] 就能看出来 上下文的集合是不一样的。
三. 再来看你的例子
你的疑问: (//b/@甲组)可出结果,而//b/@甲组只返回123,123
参考 二 中的1和2
//b/@甲组 可以看做 数组内分别放着 每个b下的属性为甲组的这样一个集合
{{第一个b属性为甲组的集合},{第二个b属性为的集合},.....}
运算过程:
按顺序取 {第一个b属性为甲组的集合}
=》按照谓词顺序运算并 返回结果,如果谓词为 [1] 那么返回{第一个b属性为甲组的集合}中的第一个,没有符合的则不返回结果(真空)。
按顺序取 {第二个b属性为甲组的集合}
=》按照谓词顺序运算并 返回结果,如果谓词为 [2] 那么返回{第二个b属性为甲组的集合}中的第二个,没有符合的则不返回结果(真空)。
.......
直至结束,最后返回所有结果的集合。
再看下面:
xpath: //b/@甲组[floor("&ROW(1:6)&" div 2+0.5)]
=>{"//b/@甲组[1]";"//b/@甲组[1]";"//b/@甲组[2]";"//b/@甲组[2]";.....}这里是数组
每个都会单独运算,所以分别看每个xpath
"//b/@甲组[1]" 按照【//b/@甲组】上下文的关系,实际结果为一个3个结果的数组。
"//b/@甲组[2]" 按照【//b/@甲组】上下文的关系,都没有第二个袁术。实际结果为真空(返回错误值)。
......所以你说的错误就是这样来的....
同样:
xpath: (//b/@甲组)[floor("&ROW(1:6)&" div 2+0.5)]
(//b/@甲组) 是所有【//b/@甲组】的集合
(//b/@甲组)[1]按照上下文的关系,实际结果为(//b/@甲组)第一个值。
(//b/@甲组)[2]按照上下文的关系,实际结果为(//b/@甲组)第二个值。
.......
所以就满足了你说的都会返回结果的情况。
好像说的好啰嗦哈。
总之重要的话:
上下文
上下文
上下文 |
|