有条件地分配变量以匹配xslt模板中的路径

时间:2019-01-24 11:11:03

标签: java pdf xslt conditional variable-assignment

我想在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”是一个原子值

为什么没有解决方案可以实现它?

2 个答案:

答案 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:Testdef: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>