提问人:Daniel 提问时间:9/19/2023 最后编辑:Siebe JongebloedDaniel 更新时间:9/19/2023 访问量:45
在 XSL FO 中创建多级列表
creating Multi-level lists in XSL FO
问:
我正在尝试创建多级列表输出。im 在 XML 1.0 中使用通过 apache FOP 运行的 XSLT
我使用如下所示的 XML 输入,其中 procedureList 中有许多不同的过程,这些过程有许多步骤。子步骤嵌入在步骤中。
<ProcedureList>
<Procedure title="The First Procedure" type="Removal">
<Steps>
<Step id="1">Step 1 </Step>
<Step id="2">Step 2 </Step>
<Step id="3">Step 3 <Step id="4">Step 4 <Step id="5">Step 5 </Step></Step></Step>
</Steps>
</Procedure>
<Procedure title="The Second Procedure" type="removal">
<Steps>
<Step id="6">Step 6 </Step>
<Step id="7">Step 7 <Step id="8">Step 8</Step></Step>
</Steps>
</Procedure>
</ProcedureList>
之后的输出 IM 是
1. The First Procedure
1.1 Step 1
1.2 Step 2
1.3 Step 3
1.3.a Step 4
1.3.a.i Step 5
2. The Second Procedure
2.1 Step 6
2.2 Step 7
2.2.a Step 8
使用下面的内容,我接近正确的答案(位置作为前导数字传递给模板,具体取决于该过程在文档中发生的位置。
<xsl:template match="Step">
<xsl:param name="position" />
<fo:block >
<xsl:apply-templates select="WCN" />
<xsl:if test="normalize-space(text()) != ''">
<fo:block text-indent='-15mm' start-indent='15mm' xsl:use-attribute-sets="BodyText" wrap-option="wrap" white-space="pre">
<xsl:if test="$position != ''">
<xsl:value-of select="$position"/><xsl:text>.</xsl:text>
</xsl:if>
<xsl:if test="$position = ''">
<xsl:text> </xsl:text>
</xsl:if>
<xsl:number format="1.1.a.i.a.i" count="Step" level="multiple"/><xsl:text> </xsl:text><xsl:apply-templates select="text()"/></fo:block>
</xsl:if>
<xsl:apply-templates select="Step" />
</fo:block>
</xsl:template>
我遇到的问题是当我在文档的一个区域需要两个相同类型的过程时。 我称模板为
<xsl:choose>
<xsl:when test="root/ProcedureList/Procedure[@type='inspection' or @type='repair'] != ''">
<xsl:for-each select="root/ProcedureList/Procedure[@type='inspection' or @type='repair']">
<xsl:apply-templates >
<xsl:with-param name="position" select="8" />
</xsl:apply-templates>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<fo:block xsl:use-attribute-sets="BodyText">Not Applicable</fo:block>
</xsl:otherwise>
</xsl:choose>
我得到这样的输出
1. The First Procedure
1.1 Step 1
1.2 Step 2
1.3 Step 3
1.3.a Step 4
1.3.a.i Step 5
1. The Second Procedure
1.1 Step 6
1.2 Step 7
1.2.a Step 8
答:
0赞
Siebe Jongebloed
9/19/2023
#1
只是改变
<xsl:number format="1.1.a.i.a.i" count="Step" level="multiple"/>
自
<xsl:number format="1.1.a.i.a.i" count="Procedure|Step" level="multiple"/>
评论
0赞
Daniel
9/19/2023
感谢您的回复,但不幸的是,这会从 XML 中提取过程“order”。因此,如果 XML 有 3 个过程,则第 3 个过程将出现 3.1、3.2、3.3 等,但这可能是该类型的第一个过程。如果这有意义
1赞
Siebe Jongebloed
9/19/2023
你能改变你的例子和预期的结果吗?
0赞
John Ernst
9/19/2023
#2
很难直接对你的代码进行评论,因为我没有看到所有的内容,而且你提供的代码不适用于你的示例XML。但是,解决基本问题相当容易。您将需要添加过滤器和格式。并将其应用到您的程序中。如果需要,您可以向模板添加模式并应用模板。
<xsl:template match="ProcedureList">
<xsl:value-of select="' '"/>
<xsl:apply-templates select="Procedure"/>
</xsl:template>
<xsl:template match="Procedure">
<xsl:value-of select="concat(position(), '. ', @title)"/>
<xsl:value-of select="' '"/>
<xsl:apply-templates select="Steps/Step">
<xsl:with-param name="procedure" select="concat(position(), '.')"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="Step">
<xsl:param name="procedure" />
<xsl:value-of select="$procedure"/>
<xsl:number format="1.a.i.a.i" count="Step" level="multiple"/>
<xsl:value-of select="concat(' ', normalize-space(text()))"/>
<xsl:value-of select="' '"/>
<xsl:apply-templates select="Step">
<xsl:with-param name="procedure" select="$procedure"/>
</xsl:apply-templates>
</xsl:template>
评论
0赞
Siebe Jongebloed
9/21/2023
@Daniel说:“不幸的是,这从XML中提取了过程”order”。不是在这种情况下?
0赞
John Ernst
9/22/2023
@SiebeJongebloed 这绝对是按 XML 顺序拉动的。但是,可以通过对 apply-templates 进行排序或多次调用 apply-templates 来更改过程的顺序,每个过程类型一次。
0赞
John Ernst
9/22/2023
<xsl:template match=“ProcedureList”> <xsl:value-of select=“' '”/> <xsl:apply-templates select=“Procedure[@type='Removal']”/> <xsl:apply-templates select=“Procedure[@type='ADifferentType']”/> </xsl:template>
评论