1

XPath通俗教程

出处:http://www.zvon.org/xxl/XPath...

实例 1

基本的XPath语法类似于在一个文件系统中定位文件,如果路径以斜线 / 开始, 那么该路径就表示到一个元素的绝对路径

选择根元素AAA,/AAA

<AAA>
    <BBB/>
    <CCC/>
    <BBB/>
    <BBB/>
    <DDD>
        <BBB/>
    </DDD>
    <CCC/>
</AAA>

选择AAA的所有CCC子元素/AAA/CCC

<AAA>
    <BBB/>
    <CCC/>
    <BBB/>
    <BBB/>
    <DDD>
        <BBB/>
    </DDD>
    <CCC/>
</AAA>

选择AAA的子元素DDD的所有子元素/AAA/DDD/BBB

<AAA>
    <BBB/>
    <CCC/>
    <BBB/>
    <BBB/>
    <DDD>
        <BBB/>
    </DDD>
    <CCC/>
</AAA>

实例 2

如果路径以双斜线 // 开头, 则表示选择文档中所有满足双斜线//之后规则的元素(无论层级关系)

选择所有BBB元素//BBB

<AAA>
    <BBB/>
    <CCC/>
    <BBB/>
    <DDD>
        <BBB/>
    </DDD>
    <CCC>
        <DDD>
            <BBB/>
            <BBB/>
        </DDD>
    </CCC>
</AAA>

选择所有父元素是DDD的BBB元素//DDD/BBB

<AAA>
    <BBB/>
    <CCC/>
    <BBB/>
    <DDD>
        <BBB/>
    </DDD>
    <CCC>
        <DDD>
            <BBB/>
            <BBB/>
        </DDD>
    </CCC>
</AAA>

实例 3

星号 * 表示选择所有由星号之前的路径所定位的元素

选择所有路径依附于/AAA/CCC/DDD的元素/AAA/CCC/DDD/*

<AAA>
    <XXX>
        <DDD>
            <BBB/>
            <BBB/>
            <EEE/>
            <FFF/>
        </DDD>
    </XXX>
    <CCC>
        <DDD>
            <BBB/>
            <BBB/>
            <EEE/>
            <FFF/>
        </DDD>
    </CCC>
    <CCC>
        <BBB>
            <BBB>
                <BBB/>
            </BBB>
        </BBB>
    </CCC>
</AAA>

选择所有的有3个祖先元素的BBB元素/*/*/*/BBB

<AAA>
    <XXX>
        <DDD>
            <BBB/>
            <BBB/>
            <EEE/>
            <FFF/>
        </DDD>
    </XXX>
    <CCC>
        <DDD>
            <BBB/>
            <BBB/>
            <EEE/>
            <FFF/>
        </DDD>
    </CCC>
    <CCC>
        <BBB>
            <BBB>
                <BBB/>
            </BBB>
        </BBB>
    </CCC>
</AAA>

选择所有元素//*

<AAA>
    <XXX>
        <DDD>
            <BBB/>
            <BBB/>
            <EEE/>
            <FFF/>
        </DDD>
    </XXX>
    <CCC>
        <DDD>
            <BBB/>
            <BBB/>
            <EEE/>
            <FFF/>
        </DDD>
    </CCC>
    <CCC>
        <BBB>
            <BBB>
                <BBB/>
            </BBB>
        </BBB>
    </CCC>
</AAA>

实例 4

方块号里的表达式可以进一步的指定元素, 其中数字表示元素在选择集里的位置, 而last()函数则表示选择集中的最后一个元素.

选择AAA的第一个BBB子元素/AAA/BBB[1]

<AAA>
    <BBB/>
    <BBB/>
    <BBB/>
    <BBB/>
</AAA>

选择AAA的最后一个BBB子元素/AAA/BBB[last()]

<AAA>
    <BBB/>
    <BBB/>
    <BBB/>
    <BBB/>
</AAA>

实例 5

选择所有的id属性//@id

<AAA>
    <BBB id="b1" />
    <BBB id="b2" />
    <BBB name="bbb" />
    <BBB/>
</AAA>

选择有id属性的BBB元素//BBB[@id]

<AAA>
    <BBB id="b1" />
    <BBB id="b2" />
    <BBB name="bbb" />
    <BBB/>
</AAA>

选择有name属性的BBB元素//BBB[@name]

<AAA>
    <BBB id="b1" />
    <BBB id="b2" />
    <BBB name="bbb" />
    <BBB/>
</AAA>

选择有任意属性的BBB元素//BBB[@*]

<AAA>
    <BBB id="b1" />
    <BBB id="b2" />
    <BBB name="bbb" />
    <BBB/>
</AAA>

选择没有属性的BBB元素//BBB[not(@*)]

<AAA>
    <BBB id="b1" />
    <BBB id="b2" />
    <BBB name="bbb" />
    <BBB/>
</AAA>

实例 6

属性的值可以被用来作为选择的准则, normalize-space函数删除了前部和尾部的空格, 并且把连续的空格串替换为一个单一的空格

选择含有属性id且其值为'b1'的BBB元素//BBB[@id='b1']

<AAA>
    <BBB id="b1" />
    <BBB name=" bbb " />
    <BBB name="bbb" />
</AAA>

选择含有属性name且其值为'bbb'的BBB元素//BBB[@name='bbb']

<AAA>
    <BBB id="b1" />
    <BBB name=" bbb " />
    <BBB name="bbb" />
</AAA>

选择含有属性name且其值(在用normalize-space函数去掉前后空格后)为'bbb'的BBB元素//BBB[normalize-space(@name)='bbb']

<AAA>
    <BBB id="b1" />
    <BBB name=" bbb " />
    <BBB name="bbb" />
</AAA>

实例 7

count()函数可以计数所选元素的个数

选择含有2个BBB子元素的元素//*[count(BBB)=2]

<AAA>
    <CCC>
        <BBB/>
        <BBB/>
        <BBB/>
    </CCC>
    <DDD>
        <BBB/>
        <BBB/>
    </DDD>
    <EEE>
        <CCC/>
        <DDD/>
    </EEE>
</AAA>

选择含有2个子元素的元素//*[count(*)=2]

<AAA>
    <CCC>
        <BBB/>
        <BBB/>
        <BBB/>
    </CCC>
    <DDD>
        <BBB/>
        <BBB/>
    </DDD>
    <EEE>
        <CCC/>
        <DDD/>
    </EEE>
</AAA>

选择含有3个子元素的元素//*[count(*)=3]

<AAA>
    <CCC>
        <BBB/>
        <BBB/>
        <BBB/>
    </CCC>
    <DDD>
        <BBB/>
        <BBB/>
    </DDD>
    <EEE>
        <CCC/>
        <DDD/>
    </EEE>
</AAA>

实例 8

name()函数返回元素的名称, start-with()函数在该函数的第一个参数字符串是以第二个参数字符开始的情况返回true, contains()函数当其第一个字符串参数包含有第二个字符串参数时返回true.

选择所有名称为BBB的元素(这里等价于//BBB)//*[name()='BBB']

<AAA>
    <BCC>
        <BBB/>
        <BBB/>
        <BBB/>
    </BCC>
    <DDB>
        <BBB/>
        <BBB/>
    </DDB>
    <BEC>
        <CCC/>
        <DBD/>
    </BEC>
</AAA>

选择所有名称以"B"起始的元素//*[starts-with(name(),'B')]

<AAA>
    <BCC>
        <BBB/>
        <BBB/>
        <BBB/>
    </BCC>
    <DDB>
        <BBB/>
        <BBB/>
    </DDB>
    <BEC>
        <CCC/>
        <DBD/>
    </BEC>
</AAA>

选择所有名称包含"C"的元素//*[contains(name(),'C')]

<AAA>
    <BCC>
        <BBB/>
        <BBB/>
        <BBB/>
    </BCC>
    <DDB>
        <BBB/>
        <BBB/>
    </DDB>
    <BEC>
        <CCC/>
        <DBD/>
    </BEC>
</AAA>

实例 9

string-length函数返回字符串的字符数,你应该用<替代<, 用>代替>

选择名字长度为3的元素//*[string-length(name()) = 3]

<AAA>
    <Q/>
    <SSSS/>
    <BB/>
    <CCC/>
    <DDDDDDDD/>
    <EEEE/>
</AAA>

选择名字长度小于3的元素//*[string-length(name()) < 3]

<AAA>
    <Q/>
    <SSSS/>
    <BB/>
    <CCC/>
    <DDDDDDDD/>
    <EEEE/>
</AAA>

选择名字长度大于3的元素选择名字长度大于3的元素

<AAA>
    <Q/>
    <SSSS/>
    <BB/>
    <CCC/>
    <DDDDDDDD/>
    <EEEE/>
</AAA>

实例 10

多个路径可以用分隔符 | 合并在一起

选择所有的CCC和BBB元素//CCC | //BBB

<AAA>
    <BBB/>
    <CCC/>
    <DDD>
        <CCC/>
    </DDD>
    <EEE/>
</AAA>

选择所有的BBB元素和所有是AAA的子元素的EEE元素/AAA/EEE | //BBB

<AAA>
    <BBB/>
    <CCC/>
    <DDD>
        <CCC/>
    </DDD>
    <EEE/>
</AAA>

可以合并的路径数目没有限制/AAA/EEE | //DDD/CCC | /AAA | //BBB

<AAA>
    <BBB/>
    <CCC/>
    <DDD>
        <CCC/>
    </DDD>
    <EEE/>
</AAA>

实例 11

child轴(axis)包含上下文节点的子元素, 作为默认的轴,可以忽略不写.

等价于 /child::AAA/AAA

<AAA>
    <BBB/>
    <CCC/>
</AAA>

等价于/AAA/child::AAA

<AAA>
    <BBB/>
    <CCC/>
</AAA>

等价于/child::AAA/child::BBB/AAA/BBB

<AAA>
    <BBB/>
    <CCC/>
</AAA>

等价于/AAA/BBB/child::AAA/child::BBB

<AAA>
    <BBB/>
    <CCC/>
</AAA>

二者都可以被合并/child::AAA/BBB

<AAA>
    <BBB/>
    <CCC/>
</AAA>

实例 12

descendant (后代)轴包含上下文节点的后代,一个后代是指子节点或者子节点的子节点等等, 因此descendant轴不会包含属性和命名空间节点.

选择文档根元素的所有后代.即所有的元素被选择/descendant::*

<AAA>
    <BBB>
        <DDD>
            <CCC>
                <DDD/>
                <EEE/>
            </CCC>
        </DDD>
    </BBB>
    <CCC>
        <DDD>
            <EEE>
                <DDD>
                    <FFF/>
                </DDD>
            </EEE>
        </DDD>
    </CCC>
</AAA>

选择/AAA/BBB的所有后代元素/AAA/BBB/descendant::*

<AAA>
    <BBB>
        <DDD>
            <CCC>
                <DDD/>
                <EEE/>
            </CCC>
        </DDD>
    </BBB>
    <CCC>
        <DDD>
            <EEE>
                <DDD>
                    <FFF/>
                </DDD>
            </EEE>
        </DDD>
    </CCC>
</AAA>

选择在祖先元素中有CCC的所有元素//CCC/descendant::*

<AAA>
    <BBB>
        <DDD>
            <CCC>
                <DDD/>
                <EEE/>
            </CCC>
        </DDD>
    </BBB>
    <CCC>
        <DDD>
            <EEE>
                <DDD>
                    <FFF/>
                </DDD>
            </EEE>
        </DDD>
    </CCC>
</AAA>

选择所有以CCC为祖先元素的DDD元素//CCC/descendant::DDD

<AAA>
    <BBB>
        <DDD>
            <CCC>
                <DDD/>
                <EEE/>
            </CCC>
        </DDD>
    </BBB>
    <CCC>
        <DDD>
            <EEE>
                <DDD>
                    <FFF/>
                </DDD>
            </EEE>
        </DDD>
    </CCC>
</AAA>

实例 13

parent轴(axis)包含上下文节点的父节点, 如果有父节点的话

选择DDD元素的所有父节点//DDD/parent::*

<AAA>
    <BBB>
        <DDD>
            <CCC>
                <DDD/>
                <EEE/>
            </CCC>
        </DDD>
    </BBB>
    <CCC>
        <DDD>
            <EEE>
                <DDD>
                    <FFF/>
                </DDD>
            </EEE>
        </DDD>
    </CCC>
</AAA>

实例 14

ancestor轴(axis)包含上下节点的祖先节点, 该祖先节点由其上下文节点的父节点以及父节点的父节点等等诸如此类的节点构成,所以ancestor轴总是包含有根节点,除非上下文节点就是根节点本身.

选择一个绝对路径上的所有节点/AAA/BBB/DDD/CCC/EEE/ancestor::*

<AAA>
    <BBB>
        <DDD>
            <CCC>
                <DDD/>
                <EEE/>
            </CCC>
        </DDD>
    </BBB>
    <CCC>
        <DDD>
            <EEE>
                <DDD>
                    <FFF/>
                </DDD>
            </EEE>
        </DDD>
    </CCC>
</AAA>

选择FFF元素的祖先节点//FFF/ancestor::*

<AAA>
    <BBB>
        <DDD>
            <CCC>
                <DDD/>
                <EEE/>
            </CCC>
        </DDD>
    </BBB>
    <CCC>
        <DDD>
            <EEE>
                <DDD>
                    <FFF/>
                </DDD>
            </EEE>
        </DDD>
    </CCC>
</AAA>

实例 15

following-sibling轴(axis)包含上下文节点之后的所有兄弟节点

/AAA/BBB/following-sibling::*

<AAA>
    <BBB>
        <CCC/>
        <DDD/>
    </BBB>
    <XXX>
        <DDD>
            <EEE/>
            <DDD/>
            <CCC/>
            <FFF/>
            <FFF>
                <GGG/>
            </FFF>
        </DDD>
    </XXX>
    <CCC>
        <DDD/>
    </CCC>
</AAA>

//CCC/following-sibling::*

<AAA>
    <BBB>
        <CCC/>
        <DDD/>
    </BBB>
    <XXX>
        <DDD>
            <EEE/>
            <DDD/>
            <CCC/>
            <FFF/>
            <FFF>
                <GGG/>
            </FFF>
        </DDD>
    </XXX>
    <CCC>
        <DDD/>
    </CCC>
</AAA>

实例 16

preceding-sibling 轴(axis)包含上下文节点之前的所有兄弟节点

/AAA/XXX/preceding-sibling::*

<AAA>
    <BBB>
        <CCC/>
        <DDD/>
    </BBB>
    <XXX>
        <DDD>
            <EEE/>
            <DDD/>
            <CCC/>
            <FFF/>
            <FFF>
                <GGG/>
            </FFF>
        </DDD>
    </XXX>
    <CCC>
        <DDD/>
    </CCC>
</AAA>

//CCC/preceding-sibling::*

<AAA>
    <BBB>
        <CCC/>
        <DDD/>
    </BBB>
    <XXX>
        <DDD>
            <EEE/>
            <DDD/>
            <CCC/>
            <FFF/>
            <FFF>
                <GGG/>
            </FFF>
        </DDD>
    </XXX>
    <CCC>
        <DDD/>
    </CCC>
</AAA>

实例 17

following轴(axis)包含同一文档中按文档顺序位于上下文节点之后的所有节点, 除了祖先节点,属性节点和命名空间节点

/AAA/XXX/following::*

<AAA>
    <BBB>
        <CCC/>
        <ZZZ>
            <DDD/>
            <DDD>
                <EEE/>
            </DDD>
        </ZZZ>
        <FFF>
            <GGG/>
        </FFF>
    </BBB>
    <XXX>
        <DDD>
            <EEE/>
            <DDD/>
            <CCC/>
            <FFF/>
            <FFF>
                <GGG/>
            </FFF>
        </DDD>
    </XXX>
    <CCC>
        <DDD/>
    </CCC>
</AAA>

//ZZZ/following::*

<AAA>
    <BBB>
        <CCC/>
        <ZZZ>
            <DDD/>
            <DDD>
                <EEE/>
            </DDD>
        </ZZZ>
        <FFF>
            <GGG/>
        </FFF>
    </BBB>
    <XXX>
        <DDD>
            <EEE/>
            <DDD/>
            <CCC/>
            <FFF/>
            <FFF>
                <GGG/>
            </FFF>
        </DDD>
    </XXX>
    <CCC>
        <DDD/>
    </CCC>
</AAA>

实例 18

preceding轴(axis)包含同一文档中按文档顺序位于上下文节点之前的所有节点, 除了祖先节点,属性节点和命名空间节点

/AAA/XXX/preceding::*

<AAA>
    <BBB>
        <CCC/>
        <ZZZ>
            <DDD/>
        </ZZZ>
    </BBB>
    <XXX>
        <DDD>
            <EEE/>
            <DDD/>
            <CCC/>
            <FFF/>
            <FFF>
                <GGG/>
            </FFF>
        </DDD>
    </XXX>
    <CCC>
        <DDD/>
    </CCC>
</AAA>

//GGG/preceding::*

<AAA>
    <BBB>
        <CCC/>
        <ZZZ>
            <DDD/>
        </ZZZ>
    </BBB>
    <XXX>
        <DDD>
            <EEE/>
            <DDD/>
            <CCC/>
            <FFF/>
            <FFF>
                <GGG/>
            </FFF>
        </DDD>
    </XXX>
    <CCC>
        <DDD/>
    </CCC>
</AAA>

实例 19

descendant-or-self 轴(axis)包含上下文节点本身和该节点的后代节点

/AAA/XXX/descendant-or-self::*

<AAA>
    <BBB>
        <CCC/>
        <ZZZ>
            <DDD/>
        </ZZZ>
    </BBB>
    <XXX>
        <DDD>
            <EEE/>
            <DDD/>
            <CCC/>
            <FFF/>
            <FFF>
                <GGG/>
            </FFF>
        </DDD>
    </XXX>
    <CCC>
        <DDD/>
    </CCC>
</AAA>

//CCC/descendant-or-self::*

<AAA>
    <BBB>
        <CCC/>
        <ZZZ>
            <DDD/>
        </ZZZ>
    </BBB>
    <XXX>
        <DDD>
            <EEE/>
            <DDD/>
            <CCC/>
            <FFF/>
            <FFF>
                <GGG/>
            </FFF>
        </DDD>
    </XXX>
    <CCC>
        <DDD/>
    </CCC>
</AAA>

实例 20

ancestor-or-self 轴(axis)包含上下文节点本身和该节点的祖先节点

/AAA/XXX/DDD/EEE/ancestor-or-self::*

<AAA>
    <BBB>
        <CCC/>
        <ZZZ>
            <DDD/>
        </ZZZ>
    </BBB>
    <XXX>
        <DDD>
            <EEE/>
            <DDD/>
            <CCC/>
            <FFF/>
            <FFF>
                <GGG/>
            </FFF>
        </DDD>
    </XXX>
    <CCC>
        <DDD/>
    </CCC>
</AAA>

//GGG/ancestor-or-self::*

<AAA>
    <BBB>
        <CCC/>
        <ZZZ>
            <DDD/>
        </ZZZ>
    </BBB>
    <XXX>
        <DDD>
            <EEE/>
            <DDD/>
            <CCC/>
            <FFF/>
            <FFF>
                <GGG/>
            </FFF>
        </DDD>
    </XXX>
    <CCC>
        <DDD/>
    </CCC>
</AAA>

实例 21

ancestor, descendant, following, preceding 和self轴(axis)分割了XML文档(忽略属性节点和命名空间节点), 不能交迭, 而一起使用则包含所有节点

//GGG/ancestor::*

<AAA>
    <BBB>
        <CCC/>
        <ZZZ/>
    </BBB>
    <XXX>
        <DDD>
            <EEE/>
            <FFF>
                <HHH/>
                <GGG>
                    <JJJ>
                        <QQQ/>
                    </JJJ>
                    <JJJ/>
                </GGG>
                <HHH/>
            </FFF>
        </DDD>
    </XXX>
    <CCC>
        <DDD/>
    </CCC>
</AAA>

//GGG/descendant::*

<AAA>
    <BBB>
        <CCC/>
        <ZZZ/>
    </BBB>
    <XXX>
        <DDD>
            <EEE/>
            <FFF>
                <HHH/>
                <GGG>
                    <JJJ>
                        <QQQ/>
                    </JJJ>
                    <JJJ/>
                </GGG>
                <HHH/>
            </FFF>
        </DDD>
    </XXX>
    <CCC>
        <DDD/>
    </CCC>
</AAA>

//GGG/following::*

<AAA>
    <BBB>
        <CCC/>
        <ZZZ/>
    </BBB>
    <XXX>
        <DDD>
            <EEE/>
            <FFF>
                <HHH/>
                <GGG>
                    <JJJ>
                        <QQQ/>
                    </JJJ>
                    <JJJ/>
                </GGG>
                <HHH/>
            </FFF>
        </DDD>
    </XXX>
    <CCC>
        <DDD/>
    </CCC>
</AAA>

//GGG/preceding::*

<AAA>
    <BBB>
        <CCC/>
        <ZZZ/>
    </BBB>
    <XXX>
        <DDD>
            <EEE/>
            <FFF>
                <HHH/>
                <GGG>
                    <JJJ>
                        <QQQ/>
                    </JJJ>
                    <JJJ/>
                </GGG>
                <HHH/>
            </FFF>
        </DDD>
    </XXX>
    <CCC>
        <DDD/>
    </CCC>
</AAA>

//GGG/self::*

<AAA>
    <BBB>
        <CCC/>
        <ZZZ/>
    </BBB>
    <XXX>
        <DDD>
            <EEE/>
            <FFF>
                <HHH/>
                <GGG>
                    <JJJ>
                        <QQQ/>
                    </JJJ>
                    <JJJ/>
                </GGG>
                <HHH/>
            </FFF>
        </DDD>
    </XXX>
    <CCC>
        <DDD/>
    </CCC>
</AAA>

//GGG/ancestor::* | //GGG/descendant::* | //GGG/following::* | //GGG/preceding::* | //GGG/self::*

<AAA>
    <BBB>
        <CCC/>
        <ZZZ/>
    </BBB>
    <XXX>
        <DDD>
            <EEE/>
            <FFF>
                <HHH/>
                <GGG>
                    <JJJ>
                        <QQQ/>
                    </JJJ>
                    <JJJ/>
                </GGG>
                <HHH/>
            </FFF>
        </DDD>
    </XXX>
    <CCC>
        <DDD/>
    </CCC>
</AAA>

实例 22

div运算符做浮点除法运算, mod运算符做求余运算, floor函数返回不大于参数的最大整数(趋近于正无穷), ceiling返回不小于参数的最小整数(趋近于负无穷)

选择偶数位置的BBB元素//BBB[position() mod 2 = 0 ]

<AAA>
    <BBB/>
    <BBB/>
    <BBB/>
    <BBB/>
    <BBB/>
    <BBB/>
    <BBB/>
    <BBB/>
    <CCC/>
    <CCC/>
    <CCC/>
</AAA>

选择中间的BBB元素//BBB[ position() = floor(last() div 2 + 0.5) or position() = ceiling(last() div 2 + 0.5) ]

<AAA>
    <BBB/>
    <BBB/>
    <BBB/>
    <BBB/>
    <BBB/>
    <BBB/>
    <BBB/>
    <BBB/>
    <CCC/>
    <CCC/>
    <CCC/>
</AAA>

选择中间的CCC元素//CCC[ position() = floor(last() div 2 + 0.5) or position() = ceiling(last() div 2 + 0.5) ]

<AAA>
    <BBB/>
    <BBB/>
    <BBB/>
    <BBB/>
    <BBB/>
    <BBB/>
    <BBB/>
    <BBB/>
    <CCC/>
    <CCC/>
    <CCC/>
</AAA>

XPath


唠唠叨叨
83 声望1 粉丝

引用和评论

0 条评论