2014-09-23 114 views
5

我有以下XML源:構建XML結構

<element not-relevant="true" bold="true" superscript="true" subscript="false" text="stuff"/> 

以任何順序,我需要通過特定的屬性環路(即這是有關我正在創建的HTML唯一:加粗/標/下標等),並在其中一個屬性的計算結果爲「真」,輸出嵌套元素得到以下的輸出:

<strong> 
    <sup> 
     stuff 
    </sup> 
</strong> 

我有一種感覺,我需要使用某種形式的遞歸如下所示(當然沒有無限循環):

<xsl:template match="element"> 
    <xsl:call-template name="content"> 
     <xsl:with-param name="text" select="@text"/> 
    </xsl:call-template> 
</xsl:template> 

<xsl:template name="content"> 
    <xsl:param name="text"/> 
    <xsl:choose> 
     <xsl:when test="@bold = 'true'"> 
      <strong> 
       <xsl:copy> 
        <xsl:call-template name="content"> 
         <xsl:with-param name="text" select="$text"/> 
        </xsl:call-template> 
       <xsl:copy> 
      </strong> 
     </xsl:when> 
     <xsl:when test="@subscript = 'true'"> 
      <sub> 
       <xsl:copy> 
        <xsl:call-template name="content"> 
         <xsl:with-param name="text" select="$text"/> 
        </xsl:call-template> 
       <xsl:copy> 
      </sub> 
     </xsl:when> 
     <xsl:when test="@superscript = 'true'"> 
      <sup> 
       <xsl:copy> 
        <xsl:call-template name="content"> 
         <xsl:with-param name="text" select="$text"/> 
        </xsl:call-template> 
       <xsl:copy> 
      </sup> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="$text" disable-output-escaping="yes"/> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

任何想法?我正在尋找最乾淨的XSLT 2.0解決方案,並感謝您的幫助。

感謝,

回答

6

這是一個很好的用例<xsl:next-match/>

<xsl:template match="element" priority="1"> 
    <xsl:value-of select="@text" /> 
</xsl:template> 

<xsl:template match="element[@superscript = 'true']" priority="2"> 
    <sup><xsl:next-match/></sup> 
</xsl:template> 

<xsl:template match="element[@subscript = 'true']" priority="3"> 
    <sub><xsl:next-match/></sub> 
</xsl:template> 

<xsl:template match="element[@bold = 'true']" priority="4"> 
    <strong><xsl:next-match/></strong> 
</xsl:template> 

當您應用模板的element元素,它會先觸發優先級最高的匹配模板,如果模板使用next-match它將委託給下一個最高優先級等。在問題中,您的示例element與上面的第一個,第二個和第四個模板相匹配,所以最初將選擇「粗體」模板,然後委派給「上標」模板,最後到通用element one,產生<strong><sup>stuff</sup></strong>

從這個例子中可以看出,優先級數字決定了嵌套的順序 - 如果第二個和第四個模板的優先級顛倒過來,你會得到<sup><strong>stuff</strong></sup>

+0

從來不知道這存在 - 美妙的解決方案。謝謝! – Aaron 2014-09-24 08:51:57