[XSL样式表]xPath学习

5 篇文章 0 订阅

 

 

test1.xml:

<?xml version="1.0" encoding="utf-8"?>
<?xml:stylesheet type="text/xsl" href="test3.xsl"?>
<root>
    <e1>
        <e1-1>
            <e1-1-1>
                1231.23
            </e1-1-1>
        </e1-1>
        <e1-2>
            4564.56
        </e1-2>
    </e1>
    <e2>
        <e2-1>
            789.789
        </e2-1>
        <e2-2>
            <e2-2-1>
                0120.12
            </e2-2-1>
        </e2-2>
        <e2-3>
            3453.45
        </e2-3>
    </e2>
    <e3>
        <e3-1>
            <e3-1-1>
                6.78678
            </e3-1-1>
            <e3-1-2>
                <e3-1-2-1>
                    9019.01
                </e3-1-2-1>
            </e3-1-2>
        </e3-1>
        <e3-2>
            <e3-2-1>
                234.234
            </e3-2-1>
        </e3-2>
    </e3>
</root>

 

test1.xsl:

 

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <xsl:template match="/">
        <html><body>
        <xsl:apply-templates select="root/e2"/>
        </body></html>
    </xsl:template>
    <xsl:template name="temp1" match="root/e2">
        [preceding::root/e2/]
        <xsl:for-each select="preceding::node()">
            [<xsl:value-of select="local-name()"/>]
        </xsl:for-each>
        <hr/>
        [following::root/e2/]
        <xsl:for-each select="following::node()">
            [<xsl:value-of select="local-name()"/>]
        </xsl:for-each>
        <hr/>
        [preceding-sibling::root/e2/]
        <xsl:for-each select="preceding-sibling::node()">
            [<xsl:value-of select="local-name()"/>]
        </xsl:for-each>
        <hr/>
        [following-sibling::root/e2/]
        <xsl:for-each select="following-sibling::node()">
            [<xsl:value-of select="local-name()"/>]
        </xsl:for-each>
        <hr/>
        [descendant::root/e2/]
        <xsl:for-each select="descendant::node()">
            [<xsl:value-of select="local-name()"/>]
        </xsl:for-each>
        <hr/>
        [ancestor::root/e2/]
        <xsl:for-each select="ancestor::node()">
            [<xsl:value-of select="local-name()"/>]
        </xsl:for-each>
        <hr/>
        [descendant-or-self::root/e2/]
        <xsl:for-each select="descendant-or-self::node()">
            [<xsl:value-of select="local-name()"/>]
        </xsl:for-each>
        <hr/>
        [ancestor-or-self:root/e2/]
        <xsl:for-each select="ancestor-or-self::node()">
            [<xsl:value-of select="local-name()"/>]
        </xsl:for-each>
        <hr/>
        [parent::root/e2/]
        <xsl:for-each select="parent::node()">
            [<xsl:value-of select="local-name()"/>]
        </xsl:for-each>
        <hr/>
        [child::root/e2/]
        <xsl:for-each select="child::node()">
            [<xsl:value-of select="local-name()"/>]
        </xsl:for-each>
        <hr/>
        [self::root/e2/]
        [<xsl:value-of select="local-name(self::node())"/>]
        <hr/>
    </xsl:template>
</xsl:stylesheet>

 

结果:下图中的[]代表textNode()。因为node()方法包含所有类型的节点。因此使用该方法时应该留意对类型进行过滤。

 

[preceding::root/e2/] [xml:stylesheet] [e1] [e1-1] [e1-1-1] [] [e1-2] []
[following::root/e2/] [e3] [e3-1] [e3-1-1] [] [e3-1-2] [e3-1-2-1] [] [e3-2] [e3-2-1] []
[preceding-sibling::root/e2/] [e1]
[following-sibling::root/e2/] [e3]
[descendant::root/e2/] [e2-1] [] [e2-2] [e2-2-1] [] [e2-3] []
[ancestor::root/e2/] [] [root]
[descendant-or-self::root/e2/] [e2] [e2-1] [] [e2-2] [e2-2-1] [] [e2-3] []
[ancestor-or-self:root/e2/] [] [root] [e2]
[parent::root/e2/] [root]
[child::root/e2/] [e2-1] [e2-2] [e2-3]
[self::root/e2/] [e2]

 

test2.xsl:

 

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <xsl:template match="/">
        <html><body>
        <xsl:apply-templates select="root/e2"/>
        </body></html>
    </xsl:template>
    <xsl:template match="root/e2">
        [root/e2/e2-1][ceiling(
        <xsl:value-of select="child::node()[local-name()='e2-1']"/>
        )=<xsl:value-of select="ceiling(child::node()[local-name()='e2-1'])"/>]
        <hr/>
        [root/e2/e2-2/e2-2-1][floor(
        <xsl:value-of select="descendant::node()[local-name()='e2-2-1']"/>
        )=<xsl:value-of select="floor(descendant::node()[local-name()='e2-2-1'])"/>]
        <hr/>
        [root/e1/e1-1-1 + root/e3/e3-1-1][
        <xsl:value-of select="preceding::node()[local-name()='e1-1-1']"/>
        +
        <xsl:value-of select="following::node()[local-name()='e3-1-1']"/>
        =
        <xsl:value-of select="preceding::node()[local-name()='e1-1-1'] + following::node()[local-name()='e3-1-1']"/>]
        <hr/>
        [root/e2/e2-2/e2-2-1][round(
        <xsl:value-of select="descendant::node()[local-name()='e2-2-1']"/>
        )=
        <xsl:value-of select="round(descendant::node()[local-name()='e2-2-1'])"/>]
        <hr/>
        [root/e2 counts of descendants]
        [count(nodes)=
        <xsl:value-of select="count(descendant::node())"/>]
        [count(elements)=
        <xsl:value-of select="count(descendant::node()[boolean(local-name())])"/>]
        [count(texts)=
        <xsl:value-of select="count(descendant::node()[boolean(text())])"/>]
        <hr/>
        [root/e2][number(text())=
        <xsl:value-of select="number(self::node()/text())"/>]
        [number(boolean(text()))=
        <xsl:value-of select="number(boolean(self::node()/text()))"/>]
        [number(string(text()))=
        <xsl:value-of select="number(string(self::node()/text()))"/>]
        <hr/>
    </xsl:template>
   
</xsl:stylesheet>

 

结果:这一部分测试xPath中数值函数的运用,几点结论:

一、当任意类型之间用+相加时,相加之前元素会先转换为number类型。

二、形如0120.12这样以零开头的字串,转换成number型时不会报错。

三、可以用boolean(local-name())和boolean(text())的方式过滤节点类型。

四、对于不含textNode的元素或父元素,number()并不将其转换为0,而是转换为NaN。对于这些节点,可以用number(boolean(text())的方式转换为。

 

[root/e2/e2-1][ceiling( 789.789 )=790]
[root/e2/e2-2/e2-2-1][floor( 0120.12 )=120]
[root/e1/e1-1-1 + root/e3/e3-1-1][ 1231.23 + 6.78678 = 1238.01678]
[root/e2/e2-2/e2-2-1][round( 0120.12 )= 120]
[root/e2 counts of descendants] [count(nodes)= 7] [count(elements)= 4] [count(texts)= 3]
[root/e2][number(text())= NaN] [number(boolean(text()))= 0] [number(string(text()))= NaN]

 

test3.xsl:

 

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <xsl:template match="/">
        <html><body>
            <xsl:apply-templates select="root/e2"/>
        </body></html>
    </xsl:template>
    <xsl:template match="root/e2">
       
        [root/e2][starts-with(
        <xsl:value-of select="descendant::node()[local-name()='e2-2-1']"/>
        ,'01')=
        <xsl:value-of select="starts-with(descendant::node()[local-name()='e2-2-1'],'01')"/>]
        [root/e2][starts-with(normalize-space(
        <xsl:value-of select="descendant::node()[local-name()='e2-2-1']"/>)
        ,'01')=
        <xsl:value-of select="starts-with(normalize-space(descendant::node()[local-name()='e2-2-1']),'01')"/>]
        [starts-with(number(
        <xsl:value-of select="descendant::node()[local-name()='e2-2-1']"/>)
        ,'1')=
        <xsl:value-of select="starts-with(number(descendant::node()[local-name()='e2-2-1']),'1')"/>]
       
        <hr/>
        [root/e2][starts-with(
        0120.12,01)=
        <xsl:value-of select="starts-with(0120.12, 01)"/>]
        [starts-with(
        '0120.12','01')=
        <xsl:value-of select="starts-with('0120.12', '01')"/>]
        [starts-with(
        0120.12,1)=
        <xsl:value-of select="starts-with(0120.12, 1)"/>]
        [starts-with(
        0120.12,00001)=
        <xsl:value-of select="starts-with(0120.12, 00001)"/>]
        <hr/>
        [starts-with(string(
        <xsl:value-of select="child::node()[local-name()='e2-3']"/>),'345')=
        <xsl:value-of select="starts-with(string(child::node()[local-name()='e2-3']), '345')"/>]
        [starts-with(number(
        <xsl:value-of select="child::node()[local-name()='e2-3']"/>),'345')=
        <xsl:value-of select="starts-with(number(child::node()[local-name()='e2-3']), '345')"/>]
        [starts-with(
        <xsl:value-of select="local-name()"/>,'e')=
        <xsl:value-of select="starts-with(local-name(), e)"/>]
        <hr/>
       
    </xsl:template>
</xsl:stylesheet>

 

结果:这一部分测试字串函数,几点结论:

一、在使用字串函数时,如果参数是节点或节点集要小心地处理空白,否则会产生令你嗔目结舌的结果。很多人习惯在XML文件的编辑软件如UE等中设定将Tab转换为空白,应记得先调用normalize-space()函数去掉不需要的空白。

二、但字串函数的参数不是节点或节点集而需要类型转换时,XSL是依照boolean->number->string的次序进行转换的。

所以对于下图中的0120.12实际上先被转换成120.12,然后被转换成'120.12',00001先转换成1,然后被转换成'1'。

三、substring()以1为头一个字符的索引值

四、translate()函数提供了一种高效、便捷地替换字符的方法,为了达到预定效果,应确保该函数的第二个和第三个参数的字符长度总是相等,因为长度不一时,较长参数的多余字符将被自动截掉。

 

 

[root/e2][starts-with( 0120.12 ,'01')= false] [root/e2][starts-with(normalize-space( 0120.12 ) ,'01')= true] [starts-with(number( 0120.12 ) ,'1')= true]



[root/e2][starts-with( 0120.12,01)= true] [starts-with( 0120.12,'01')= false] [starts-with( 0120.12,1)= true] [starts-with( 0120.12,00001)= true]



[starts-with(string( 3453.45 ),'345')= false] [starts-with(number( 3453.45 ),'345')= true] [starts-with( e2,'e')= true]



[string-length( 789.789 )= 29] [string-length(normalize-space( 789.789 ))= 7]
[contains( 789.789 , 789)= true]
[substring('substring',3,4)= bstr] [substring(123456, 2,10)= 23456] [substring(123456, -2,4)= 1] [substring(123456, 5,-2)= ]
[substring-after('12-34-56', '-')= 34-56] [substring-after('12-34-56', '')= 12-34-56]
[substring-before('12-34-56', '-')= 12] [substring-before('12-34-56', '')= ]
[translate('12a34b56c', 'abc', 'xyz')= 12x34y56z] [translate('12a34b56c', 'abcdefg', 'xyz')= 12x34y56z] [translate('12a34b56c', 'abc', 'xyzlmn')= 12x34y56z] [translate('12a34b56c78a90b12c', 'abc', 'xyz')= 12x34y56z78x90y12z]

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值