XSLT - <xsl:number> 元素跳过某些节点
XSLT - <xsl:number> element skip certain nodes
我有一个如下的 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>
我需要通过分析 <para>
元素的 text()
节点将属性名称 type
添加到 <para>
元素。
如果 text()
节点以“§ 9.02A”开头,则类型属性应为 'xxx' 否则类型属性应为从每个级别的数字 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() 函数)来完成,但我确实需要以这种方式来完成。任何人都可以建议我一种方法,我该如何修改以获得正确的输出?
改变
<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"/>
我有一个如下的 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>
我需要通过分析 <para>
元素的 text()
节点将属性名称 type
添加到 <para>
元素。
如果 text()
节点以“§ 9.02A”开头,则类型属性应为 'xxx' 否则类型属性应为从每个级别的数字 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() 函数)来完成,但我确实需要以这种方式来完成。任何人都可以建议我一种方法,我该如何修改以获得正确的输出?
改变
<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"/>