使用参数作为 XSL 选择语句的参数
Posted
技术标签:
【中文标题】使用参数作为 XSL 选择语句的参数【英文标题】:Using a param as the argument to XSL select statement 【发布时间】:2021-08-01 07:55:33 【问题描述】:我正在使用 apache fop 生成 PDF,我有一个生成表格的 XSL-FO 模板,我希望能够使用不同的选择参数多次调用该模板。
这是我的 xsl 样式表
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:fox="http://xmlgraphics.apache.org/fop/extensions"
version="1.0">
<xsl:output method="html"/>
<xsl:template name="checklist">
<xsl:param name="H1"/>
<xsl:param name="H2"/>
<xsl:param name="H3"/>
<xsl:param name="src"/>
<fo:block >
<fo:table font-size="8pt" table-layout="fixed" >
<fo:table-column column-/>
<fo:table-column column-/>
<fo:table-column column-/>
<fo:table-header font-weight="bold" background-color="lightgrey">
<fo:table-row>
<fo:table-cell>
<fo:block><xsl:value-of select="$H1"/></fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block text-align="center"><xsl:value-of select="$H2"/></fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block><xsl:value-of select="$H3"/></fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-header>
<fo:table-body>
<xsl:apply-templates select="$src" />
</fo:table-body>
</fo:table>
</fo:block>
</xsl:template>
<xsl:template match="item">
<fo:table-row line-stacking-strategy="line-height" margin="0mm" space-before="1mm" background-color="white">
<xsl:variable name="hdr" select="hdr"/>
<xsl:choose>
<xsl:when test="$hdr = 'y'">
<fo:table-cell number-columns-spanned="3" background-color="lightgrey" border="1px solid #b8b6b6">
<fo:block>
<fo:inline>
<xsl:value-of select="id"/> 
<xsl:value-of select="description"/>
</fo:inline>
</fo:block>
</fo:table-cell>
</xsl:when>
<xsl:otherwise>
<fo:table-cell border="1px solid #b8b6b6" vertical-align="middle" text-align="center">
<fo:block line->
<xsl:value-of select="id"/>
</fo:block>
</fo:table-cell>
<fo:table-cell border="1px solid #b8b6b6" padding-left="3pt">
<fo:block>
<xsl:value-of select="description"/>
</fo:block>
</fo:table-cell>
<fo:table-cell border="1px solid #b8b6b6" text-align="center" padding-right="3pt">
<xsl:variable name="outcome" select="outcome"/>
<fo:block color="white">
<!--<fo:external-graphic src="file:///F:/Projects/Active/eCert/src/resources/c1.svg" content- content-/>-->
<xsl:choose>
<xsl:when test="$outcome = 'ok'">
<fo:external-graphic src="file:///F:/Projects/Active/eCert/src/resources/c1n.svg" vertical-align="middle" content-/>
</xsl:when>
<xsl:when test="$outcome = 'c1'">
<fo:external-graphic src="file:///F:/Projects/Active/eCert/src/resources/ok.svg" vertical-align="middle" content-/>
</xsl:when>
<xsl:when test="$outcome = 'c2'">
<fo:external-graphic src="file:///F:/Projects/Active/eCert/src/resources/c2.svg" vertical-align="middle" content-/>
</xsl:when>
<xsl:when test="$outcome = 'c3'">
<fo:external-graphic src="file:///F:/Projects/Active/eCert/src/resources/c3.svg" vertical-align="middle" content-/>
</xsl:when>
<xsl:when test="$outcome = 'fi'">
<fo:external-graphic src="file:///F:/Projects/Active/eCert/src/resources/fi.svg" vertical-align="middle" content-/>
</xsl:when>
<xsl:when test="$outcome = 'nv'">
<fo:external-graphic src="file:///F:/Projects/Active/eCert/src/resources/nv.svg" vertical-align="middle" content-/>
</xsl:when>
<xsl:when test="$outcome = 'na'">
<fo:external-graphic src="file:///F:/Projects/Active/eCert/src/resources/na.svg" vertical-align="middle" content-/>
</xsl:when>
<xsl:when test="$outcome = 'lim'">
<fo:external-graphic src="file:///F:/Projects/Active/eCert/src/resources/lim.svg" vertical-align="middle" content-/>
</xsl:when>
</xsl:choose>
</fo:block>
</fo:table-cell>
</xsl:otherwise>
</xsl:choose>
</fo:table-row>
</xsl:template>
</xsl:stylesheet>
这是调用模板的流程之一
<fo:flow flow-name="xsl-region-body">
<fo:block />
<xsl:call-template name="checklist">
<xsl:with-param name="H1" select="'Item No.'"/>
<xsl:with-param name="H2" select="'Description'"/>
<xsl:with-param name="H3" select="'Outcome'"/>
<xsl:with-param name="src" select="'eicr/checklist/item'"/>
</xsl:call-template>
</fo:flow>
当我执行 FOP 时,我收到以下错误 ** 无法将 #STRING 转换为 NodeList!** 参数 H1、H2 和 H3 用作列标题,该部分工作正常 src 参数应该用于从 xml 列表中选择项目。
我是新的 xsl fo,所以任何可以帮助我实现预期结果的帮助或文档指针都将不胜感激。
非常感谢
【问题讨论】:
您的错误很可能在这里: “src” 表示从外部传递到 XSLT 的参数。这始终是一个字符串。您需要使用 xslt 扩展将字符串“src”解析为节点集之前 @KevinBrown 在上面的代码中,$src
是内部传递给被调用模板的参数——它可以是任何数据类型。
你是对的。需要在电脑上而不是手机上阅读这些内容。
【参考方案1】:
删除eicr/checklist/item
周围的单引号。 'eicr/checklist/item'
是字符串文字; eicr/checklist/item
是一个位置路径,它将选择相对于上下文节点的元素。
我试图避免的替代方法(因为它更冗长)是在调用模板之前或作为调用模板的一部分应用模板,然后将结果复制到结果树:
<xsl:with-param name="src">
<xsl:apply-templates select="eicr/checklist/item" />
</xsl:with-param>
<fo:table-body>
<xsl:copy-of select="$src" />
</fo:table-body>
这是您在 DocBook XSLT 1.0 样式表中看到的一种技术,例如:
https://github.com/docbook/xslt10-stylesheets/blob/6ff683948c5a85949e4b7661f302e8b5f12f7bf2/xsl/fo/block.xsl#L181
【讨论】:
我试过不带单引号以上是关于使用参数作为 XSL 选择语句的参数的主要内容,如果未能解决你的问题,请参考以下文章
如何在选择语句的“NOT IN”子句中使用逗号分隔的字符串列表作为 pl/sql 存储的函数参数