2010-05-18 19 views
1

有沒有什麼辦法來優化這段代碼。選擇建築中的包裝元素。如何提高?

<xsl:choose> 
    <xsl:when test="val1 = val2"> 
     <xsl:apply-templates select="node"/> 
    </xsl:when> 
    <xsl:otherwise> 
     <div> 
      <xsl:apply-templates select="node"/> 
     </div> 
    </xsl:otherwise> 
</xsl:choose> 

我不喜歡必須寫兩次相同<xsl:apply-templates select="node"/>


更新:

的想法是,根據比較結果做的兩件事情一個

  1. 只是打印一些信息(我們之後獲得應用模板<xsl:apply-templates select="node"/>)。

    相同信息,但預先在容器(div例如)「包裹」它
  2. 打印。

+0

一個很好的問題(+1)!查看我的答案,找到只需要發佈一次的簡短解決方案。 :) – 2010-05-18 13:13:55

+0

@Dimitre Novatchev,我一如既往,任務設定不佳。查看有問題的更新。 – Kalinin 2010-05-18 13:26:04

+0

我沒有看到任何更新! ??? – 2010-05-18 13:28:47

回答

0

使用

<xsl:apply-templates select="node"> 
    <xsl:sort select="not(val1 = val2)"/> 
</xsl:apply-templates> 

下面是一個完整的例子。這種轉變:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="/*"> 
    <t> 
     <xsl:apply-templates select="node"> 
      <xsl:sort select="not(val1 = val2)"/> 
     </xsl:apply-templates> 
    </t> 
</xsl:template> 

<xsl:template match="node[not(val1 = val2)]"> 
    <div> 
    <node> 
     <xsl:apply-templates/> 
    </node> 
    </div> 
</xsl:template> 
</xsl:stylesheet> 

當這個XML文檔施加:

<t> 
    <node> 
    <val1>1</val1> 
    <val2>2</val2> 
    </node> 
    <node> 
    <val1>3</val1> 
    <val2>3</val2> 
    </node> 
</t> 

產生想要的,正確的結果:

<t> 
    <node> 
     <val1>3</val1> 
     <val2>3</val2> 
    </node> 
    <div> 
     <node> 
     <val1>1</val1> 
     <val2>2</val2> 
     </node> 
    </div> 
</t> 

解決的說明:

只要<xsl:apply-templates>具有<xsl:sort>孩子,就會根據<xsl:sort>孩子(ren)中提供的數據對所選節點進行排序,並且在每個選定節點上應用模板的結果以該(排序)順序顯示在輸出中 - 不按文件順序。

在上面,我們的改造有:

<xsl:apply-templates select="node"> 
    <xsl:sort select="not(val1 = val2)"/> 
</xsl:apply-templates> 

這意味着應用模板名爲node的元素,它是真實的val1=val2將應用模板來命名的元素的結果之前出現的結果node其中val1=val2不正確。這是因爲falsetrue之前排序。

如果這個解釋不明確,讀者可以閱讀更多有關<xsl:sort>的文章。

+0

我不明白這裏排序發生了什麼。 – Kalinin 2010-05-18 13:41:28

+0

@Kalinin:我用解釋更新了答案。 – 2010-05-18 16:46:01

-1

您在這裏發佈的xslt不是很優化。如果您不想複製的代碼超過兩行,則可以通過創建一個已命名的模板並調用該代碼來進行優化。在這個例子中它確實沒有太大的意義,但你會得到的想法:

<xsl:when test="val1=val2"> 
    <xsl:call-template name="optimized"/> 
</xsl:when> 
<xsl:otherwise> 
    <div> 
    <xsl:call-template name="optimized"/> 
    </div> 
</xsl:otherwise> 

而且模板:

<xsl:template name="optimized"> 
    <xsl:apply-templates select="node"/> 
</xsl:template> 

被叫模板是在相同的上下文中調用代碼,因此您可以將不想複製的代碼複製到指定模板。

0

這是耐寒可能是簡單的例子,但如果包裝代碼的數量和重複的代碼是值得困擾,你有兩個選擇:

  1. 介紹不同模式的模板鏈:

    <!-- instead of choose --> 
    <xsl:apply-template match="." mode="container" /> 
    ... 
    <xsl:template match="container" mode="container"> 
        <xsl:apply-templates select="." mode="dup-group"/> 
    </xsl:template> 
    
    <xsl:template match="container[val1=val2]" mode="container"> 
        <div> 
         <xsl:apply-templates select="." mode="dup-group"/> 
        </div> 
    </xsl:template> 
    
    <xsl:template match="container" mode="dup-group"> 
        <xsl:apply-templates select="node"/> 
        <!-- other duplicate code --> 
        ... 
    </xsl:template> 
    
  2. 移動部分代碼到一個單獨導入的樣式表,並覆蓋在當前樣式表的模板規則:

    <xsl:template match="container[val1=val2]"> 
        <div> 
         <xsl:apply-imports /> 
        </div> 
    </xsl:template>