Xslt 1.0 XSLT 1.0/XSL:FO-如何在发生特定子节点时重置编号
我有包含一系列步骤的XML。我试图在出现标题时重置步骤编号Xslt 1.0 XSLT 1.0/XSL:FO-如何在发生特定子节点时重置编号,xslt-1.0,xsl-fo,Xslt 1.0,Xsl Fo,我有包含一系列步骤的XML。我试图在出现标题时重置步骤编号 每个步骤将包含一个或多个“para”元素 每个步骤可以选择包含一个“title”元素 每个步骤都应收到一个连续的编号,但是当出现标题时,应重新开始步骤编号 这需要使用XSLT1.0/XSL:FO来完成 XML: <top> <Step> <title>Toilet Paper Holder</title> <para>It holds
- 每个步骤将包含一个或多个“para”元素
- 每个步骤可以选择包含一个“title”元素
- 每个步骤都应收到一个连续的编号,但是当出现标题时,应重新开始步骤编号
<top>
<Step>
<title>Toilet Paper Holder</title>
<para>It holds toilet paper.</para>
<para>It holds 1 roll.</para>
</Step>
<Step>
<para>It is red.</para>
</Step>
<Step>
<para>It is metal.</para>
</Step>
<Step>
<title>Toilet</title>
<para>You sit on it.</para>
</Step>
<Step>
<para>It is white.</para>
</Step>
<Step>
<para>It is porcelain.</para>
</Step>
</top>
<xsl:template match="Step">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="title">
<fo:block>
<xsl:apply-templates/>
</fo:block>
</xsl:template>
<xsl:template match="para">
<fo:block>
<xsl:if test="not(preceding-sibling::para)">
<xsl:number count="Step[child::para]" from="top" format="1."/>
</xsl:if>
<xsl:text> </xsl:text>
<xsl:apply-templates/>
</fo:block>
</xsl:template>
Toilet Paper Holder
1. It holds toilet paper.
It holds 1 roll.
2. It is red.
3. It is metal.
Toilet
4. You sit on it.
5. It is white.
6. It is porcelain.
Toilet Paper Holder
1. It holds toilet paper.
It holds 1 roll.
2. It is red.
3. It is metal.
Toilet
1. You sit on it.
2. It is white.
3. It is porcelain.
所需输出:
<top>
<Step>
<title>Toilet Paper Holder</title>
<para>It holds toilet paper.</para>
<para>It holds 1 roll.</para>
</Step>
<Step>
<para>It is red.</para>
</Step>
<Step>
<para>It is metal.</para>
</Step>
<Step>
<title>Toilet</title>
<para>You sit on it.</para>
</Step>
<Step>
<para>It is white.</para>
</Step>
<Step>
<para>It is porcelain.</para>
</Step>
</top>
<xsl:template match="Step">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="title">
<fo:block>
<xsl:apply-templates/>
</fo:block>
</xsl:template>
<xsl:template match="para">
<fo:block>
<xsl:if test="not(preceding-sibling::para)">
<xsl:number count="Step[child::para]" from="top" format="1."/>
</xsl:if>
<xsl:text> </xsl:text>
<xsl:apply-templates/>
</fo:block>
</xsl:template>
Toilet Paper Holder
1. It holds toilet paper.
It holds 1 roll.
2. It is red.
3. It is metal.
Toilet
4. You sit on it.
5. It is white.
6. It is porcelain.
Toilet Paper Holder
1. It holds toilet paper.
It holds 1 roll.
2. It is red.
3. It is metal.
Toilet
1. You sit on it.
2. It is white.
3. It is porcelain.
下面是生成所需输出的xslt XSL:
<xsl:template match="Step">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="title">
<fo:block>
<xsl:apply-templates/>
</fo:block>
</xsl:template>
<xsl:template match="para">
<fo:block>
<xsl:if test="not(preceding-sibling::para)">
<xsl:call-template name="StepNumbering">
<xsl:with-param name="format" select="'1.'"/>
</xsl:call-template>
</xsl:if>
<xsl:text> </xsl:text>
<xsl:apply-templates/>
</fo:block>
</xsl:template>
<xsl:template name="StepNumbering">
<xsl:param name="format" select="'1.'"/>
<xsl:for-each select="parent::Step">
<xsl:choose>
<xsl:when test="title">
<xsl:number value="1" format="{$format}"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="Step_id">
<xsl:for-each select="preceding-sibling::Step[title][1]">
<xsl:value-of select="generate-id(.)"/>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="StepNumber"
select="count(preceding-sibling::Step
[generate-id(preceding-sibling::Step[title][1]) = $Step_id]
| preceding-sibling::Step[title][1])+1"/>
<xsl:number value="$StepNumber" format="{$format}"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>