组合处理相同节点的多个XSLT 1.0传递的最佳方法

时间:2011-07-21 09:22:36

标签: xslt exslt

我正在进行一些非常复杂的XSLT 1.0转换(目前使用8次XSLT传递)。我想结合这8个传递而不将它们合并到一个文件中(这太复杂了)。我的解决方案是使用xsl:includeexsl:node-set来合并传递并将临时结果存储在变量中。

但是我有一个问题:我的转换通过复制大多数节点并仅修改某些方面。因此,我需要在每次传递中处理相同的节点,但不同 xsl:template!但是我该怎么做?如何判断第一遍之后我想从其他XSLT样式表中应用模板?

我正在做的非常简单的例子(2次XSLT传递):

来源:

<h>something here</h>

XSLT传递1后:

<h someattribute="1">something here</h>

XSLT传递2之后:

<h someattribute="1" somemoreattribute="2">something here, and even more</h>

我目前的做法是两次调用XSLT处理器并将结果临时保存在磁盘上:

xsltproc stylesheet1.xsl input.xml >temp.xml
xsltproc stylesheet2.xsl temp.xml >finalresult.xml

2 个答案:

答案 0 :(得分:2)

一种可能的解决方案是更改每个样式表以使用不同的mode。然后,您可以将它们全部导入主样式表,并依次使用每种模式应用模板进行多次传递:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:exsl="http://exslt.org/common"
                extension-element-prefixes="exsl"
                version="1.0">

  <xsl:import href="stylesheet1.xsl"/> <!-- assuming mode="stylesheet1" -->
  <xsl:import href="stylesheet2.xsl"/> <!-- assuming mode="stylesheet2" -->
  <xsl:import href="stylesheet3.xsl"/> <!-- assuming mode="stylesheet3" -->

  <xsl:template match="/">
    <xsl:variable name="temp1">
      <xsl:apply-templates select="." mode="stylesheet1"/>
    </xsl:variable>
    <xsl:variable name="temp2">
      <xsl:apply-templates mode="stylesheet2" select="exsl:node-set($temp1)"/>
    </xsl:variable>
    <xsl:apply-templates mode="stylesheet3" select="exsl:node-set($temp2)"/>
  </xsl:template>

</xsl:stylesheet>

缺点是您需要修改原始样式表,为每个modexsl:template添加适当的xsl:apply-templates属性。您仍然可以通过在每个样式中添加这样的额外模板来使样式表独立工作:

<xsl:template match="/">
  <xsl:apply-templates select="." mode="stylesheet1"/>
</xsl:template>

答案 1 :(得分:0)

为什么不使用

<xsl:param name="iteration"/>

并将迭代编号传递给样式表?然后你可以像这样使用它

<xsl:if test="$iteration = 1">
  ...
</xsl:if>

......或在其他情况下

您可以使用

设置参数
javax.xml.transform.Transformer.setParameter("iteration", 1);

或者使用蚂蚁:

<xslt ...>
  <param name="iteration" expression="1"/>
</xslt>