2009-07-14 61 views
0

我目前正在使用兩個樣式表來獲取我的預期輸出。第一個樣式表(pass1.xsl)完成真正的工作,第二個樣式表(pass2.xsl)刪除重複項,同時提供較小的格式更新。XSLT:合併樣式表

我的問題是我是否可以在單個樣式表中執行這兩個操作。
當我在看內容時,我不能通過xsl:函數得到我的印象,因爲這兩個樣式表都包含模板匹配,如果從第二個複製/粘貼到第一個樣式表中,這些模板匹配會發生衝突。 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> 

要重申 - 我們的目標是隻運行一個樣式表來產生最終結果。 運行兩次並不困難,但不必非得非常高興。我在複製/粘貼到原始&使其工作,還是進口/包括我應該看什麼?我寧願只有一個樣式表文件 - 以最大限度地減少有人錯誤地刪除支持文件的機會。

回答

1

對於模板,您應該使用不同的modes(這將需要爲所有xsl:templatexsl:apply-templates語句添加mode屬性)。然後,默認模式下根節點的模板將首先在第一模式下觸發根模板,然後將結果傳遞到第二模式下的根模板。爲此,您需要能夠將結果樹片段(這是構造函數生成的元素)作爲節點集合處理(這就是您可以將模板應用於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>