我想在xslt模板中动态建立匹配。我使用xls fo和apache fop和saxon9he。最好的方式是我想从Java传递参数,但首先我尝试在xslt中设置它。
当我创建这样的变量示例时:
<xsl:variable name="testPath" select="/abc:Files/def:Description" />
如果我尝试在apply-templates中使用它,也可以正常工作:
<xsl:apply-templates select="$testPath/qwe:Test"/>
但是我想动态设置testPath变量。我尝试使用选择标签:
<xsl:variable name="testPath">
<xsl:choose>
<xsl:when test="$versionNo = '2'">
<xsl:value-of select="/abc:Files/def:Description" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="/abc:Files/def:Names" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
但是这种方法不起作用,当我尝试使用此变量时:
<xsl:apply-templates select="$testPath/qwe:Test"/>
我收到此错误:
第82行第21列的错误评估((attr {table-layout = ...},...)) pdf_gen.xsl的编号:SXCH0003:org.apache.fop.fo.ValidationException: “ fo:table-body”缺少子元素。所需内容模型: 标记*(表格行+ |表格单元格+)(请参见位置82:21):
文件:/ C:/Users/SuperUser/workspace/project/xls-editor/target/classes/pdf/xsl/pdf_gen.xsl:82:21: “ fo:table-body”缺少子元素。所需内容模型: 标记*(表格行+ |表格单元格+)(请参见位置82:21)
在最佳选择中,我想从Java传递$ testPath变量作为参数,例如:
transformer.setParameter("testPath ", "/abc:Files/def:Description");
并在xslt中使用
<xsl:param name="testPath "/>
并应用于模板:
<xsl:apply-templates select="$testPath/qwe:Test"/>
但是出现以下错误:
类型错误评估($ testPath)在 xsl:apply-templates / @ select在第74行的第60列 pdf_gen.xsl:XPTY0019:所需的商品类型 “ /”的第一个操作数是node();提供的值
u“ / abc:Files / def:Description”是一个原子值
为什么没有解决方案可以实现它?
答案 0 :(得分:1)
在使用Saxon 9时,您确实至少将XSLT 2与XPath 2一起使用,我建议在XPath中使用例如,实现变量选择。
<xsl:variable name="testPath" select="if ($versionNo = '2') then /abc:Files/def:Description else /abc:Files/def:Names"/>
那样你的
<xsl:apply-templates select="$testPath/qwe:Test"/>
应该可以很好地处理先前选择的qwe:Test
或def:Description
元素的def:Names
个子元素。
当然也可以使用
<xsl:apply-templates select="(if ($versionNo = '2') then /abc:Files/def:Description else /abc:Files/def:Names)/qwe:Test"/>
或例如
<xsl:apply-templates select="(/abc:Files/def:Description[$versionNo = '2'], /abc:Files/def:Names[$versionNo != '2'])/qwe:Test"/>
答案 1 :(得分:0)
我正在处理类似的问题。
在我看来,变量可见性仅在<xsl:choose>
块内,我建议您制作模板块并以这种方式调用它们:
<xsl:choose>
<xsl:when test="$versionNo = '2'" >
<xsl:call-template name="TemplateOne">
<xsl:with-param name="testPath" select="'/abc:Files/def:Description'" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="TemplateTwo">
<xsl:with-param name="testPath" select="'/abc:Files/def:Names'" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
模板定义为:
<xsl:template name="TemplateOne">
<xsl:param name="testPath" />
...
bla bla bla
remember to use variable in this template as "{$testPath}"
...
</xsl:template>