XSLT - <xsl:number>元素跳过某些节点

时间:2016-01-26 11:33:39

标签: xml xslt xslt-2.0

我有一个xsl,如下,

<doc>
    <sec>
        <para>para</para>
        <para>para</para>
        <para>§ 9.02A spara</para>
        <para>para</para>
        <para>para</para>
    </sec>
    <sec>
        <para>para</para>
        <para>para</para>
        <para>para</para>
        <para>para</para>
        <para>para</para>
    </sec>
    <sec>
        <para>para</para>
        <para>para</para>
        <para>para</para>
        <para>para</para>
        <para>para</para>
    </sec>
</doc>

我需要通过分析type元素的<para>节点,将属性名称text()添加到<para>元素。

如果text()节点以'§9.02A'开头,那么type属性应该是'xxx',否则type属性应该是从每个级别的数字1开始的顺序号值,所以预期的输出应该是,

<doc>
    <sec>
        <para type="1">para</para>
        <para type="2">para</para>
        <para type="XXX">§ 9.02A spara</para>
        <para type="3">para</para>
        <para type="4">para</para>
    </sec>
    <sec>
        <para type="1">para</para>
        <para type="2">para</para>
        <para type="3">para</para>
        <para type="4">para</para>
        <para type="5">para</para>
    </sec>
    <sec>
        <para type="1">para</para>
        <para type="2">para</para>
        <para type="3">para</para>
        <para type="4">para</para>
        <para type="5">para</para>
    </sec>
</doc>

我已经编写了xsl来执行此操作,如下所示,

<xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="para">
        <xsl:variable name="position" as="xs:string">
            <xsl:number count="para" level="single" select=". except para[matches(.,'§\s\d+\.\d+[A-Z]')]"/>
        </xsl:variable>

        <para>
            <xsl:if test="matches(.,'§\s\d+\.\d+[A-Z]')">
                <xsl:attribute name="type">
                    <xsl:value-of select="'XXX'"/>
                </xsl:attribute>
                <xsl:apply-templates/>
            </xsl:if>
            <xsl:if test="not(matches(.,'§\s\d+\.\d+[A-Z]'))">
                <xsl:attribute name="type">
                    <xsl:value-of select="$position"/>
                </xsl:attribute>
                <xsl:apply-templates/>
            </xsl:if>

        </para>
    </xsl:template>

这里的问题是,当text()从'§ 9.02A'开始时,该属性没有滑过该级别,(参见生成的输出的第一级<para> ..当前值为1,2, XXX,4,5。它应该是1,2,XXX,3,4)

当前输出,

<doc>
    <sec>
        <para type="1">para</para>
        <para type="2">para</para>
        <para type="XXX">§ 9.02A spara</para>
        <para type="4">para</para>
        <para type="5">para</para>
    </sec>
    <sec>
        <para type="1">para</para>
        <para type="2">para</para>
        <para type="3">para</para>
        <para type="4">para</para>
        <para type="5">para</para>
    </sec>
    <sec>
        <para type="1">para</para>
        <para type="2">para</para>
        <para type="3">para</para>
        <para type="4">para</para>
        <para type="5">para</para>
    </sec>
</doc>

这可以通过使用其他方法如count()函数来完成,但我真的需要这样做。任何人都可以建议我一个方法如何修改以获得正确的输出?

1 个答案:

答案 0 :(得分:3)

变化

<xsl:number count="para" level="single" select=". except para[matches(.,'§\s\d+\.\d+[A-Z]')]"/>

<xsl:number count="para[not(matches(.,'§\s\d+\.\d+[A-Z]+'))]" level="single"/>