XSLT:整合样式表

时间:2009-07-14 22:56:08

标签: xslt

我目前正在使用两个样式表来获得我的预期输出。第一个样式表(pass1.xsl)执行实际工作,第二个样式表(pass2.xsl)删除重复项,同时提供次要的格式更新。

我的问题是我是否可以在一个样式表中执行这两个操作 当我查看内容时,我无法通过xsl:functions获得印象,因为两个样式表都包含模板匹配,如果我从第二个复制/粘贴到第一个,则会发生冲突。 IE:

pass1.xsl:

<xsl:template match="xs:complexType">
  <xsl:param name="prefix" />       
  <xs:complexType name="{my:updateName($prefix, @name)}">

    <!-- insert xs:sequence ONLY if the child is NOT xs:complexContent -->
    <xsl:choose>
      <xsl:when test="*[name()='xs:complexContent']">
        <xsl:apply-templates select="node()" />
      </xsl:when>
      <xsl:otherwise>
        <xs:sequence>
          <xsl:apply-templates select="node()" />
        </xs:sequence>              
      </xsl:otherwise>
    </xsl:choose>
  </xs:complexType>
  <xsl:apply-templates select=".//xs:element" />
</xsl:template>

pass2.xsl:

<xsl:template match="xs:complexType">
  <xsl:copy>
    <xsl:apply-templates select="*|@*"/>
  </xsl:copy>
</xsl:template>

重申一下 - 目标是只运行一个样式表来产生最终结果。 运行两个并不困难,但不必这样做很好。我是否正在复制/粘贴到原始&amp;使它工作,或进口/包括我应该看什么?我更喜欢只有一个样式表文件 - 以尽量减少有人错误地删除支持文件的可能性。

1 个答案:

答案 0 :(得分:1)

您应该对模板使用不同的modes(这需要在所有modexsl:template语句中添加xsl:apply-templates属性。然后,默认模式下根节点的模板将首先在第一模式下触发根模板,然后在第二模式下将结果传递给根模板。为此,您需要能够将结果树片段(元素构造函数生成的片段)视为节点集(您可以将模板应用于模板并通过XPath进行查询) - 没有标准的方法来执行此操作,但exsl:node-set是事实上的标准(请注意,支持它的处理器的完整列表大于该页面上的处理器 - 例如,.NET XslCompiledTransform支持它)。所以:

<xsl:template match="/">
   <xsl:variable name="round1-output">
     <xsl:apply-templates select="/" mode="round1" />
   </xsl:variable>
   <xsl:apply-templates select="exsl:node-set($round1-output)" mode="round2" />
</xsl:template>

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

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

...

<xsl:template match="xs:complexType" mode="round1">
  <xsl:param name="prefix" />           
  <xs:complexType name="{my:updateName($prefix, @name)}">
    <!-- insert xs:sequence ONLY if the child is NOT xs:complexContent -->
    <xsl:choose>
      <xsl:when test="*[name()='xs:complexContent']">
        <xsl:apply-templates select="node()" mode="round1"/>
      </xsl:when>
      <xsl:otherwise>
        <xs:sequence>
          <xsl:apply-templates select="node()" mode="round1"/>
        </xs:sequence>                          
      </xsl:otherwise>
    </xsl:choose>
  </xs:complexType>
  <xsl:apply-templates select=".//xs:element" mode="round1"/>
</xsl:template>

<xsl:template match="xs:complexType" mode="round2">
  <xsl:copy>
    <xsl:apply-templates select="*|@*" mode="round2"/>
  </xsl:copy>
</xsl:template>