2010-07-02 108 views
6
<xsl:choose> 
    <xsl:when test="long convoluted expression"> 
     <xsl:element name="Class">123</xsl:element> 
     <a lot more xsl:elements> 
    </xsl:when> 
    <xsl:when test="next very long expression"> 
     <xml:element name="Class">124</xsl:element> 
     <a lot more xsl:elements> 
    </xsl:when> 
    <tens of more similar xsl:when> 
</xsl:choose> 

有沒有一種方法來簡化上面的代碼與條件?對於給定對象的每個類值,都會有數十行附加屬性。這些屬性根據類的值形成集合。 0-99級有一組額外標籤,每秒100-199級,當這些額外標籤集中的一個發生變化時形成維護噩夢。XSLT條件/變量範圍

我正在考慮這樣一個解決方案:

<xsl:choose> 
    <xsl:when test="long convoluted expression"> 
     <xml:element name="Class">123</xsl:element> 
     <xsl:variable name="outputclass" select="123"> 
    </xml:when> 
    <xsl:when test="next very long expression"> 
     <xml:element name="Class">124</xsl:element> 
     <xsl:variable name="outputclass" select="124"> 
    </xsl:when> 
</xsl:choose> 
<xsl:choose> 
    <xsl:when test="$outputclass > 99"> 
     <xml:elements for classes 100-199 here> 
    </xsl:when> 
<xsl:choose> 

但當然這失敗,因爲OutputClass類變量不是在同一範圍內。任何方式來解決這個問題?

+0

這很混亂。如果您添加示例輸入和輸出文檔,它可能會變得更清晰。 – 2010-07-02 12:31:33

+0

好問題(+1)。在我的答案中看到* real * best解決方案 - 完整的代碼和解釋。 :) – 2010-07-02 13:28:34

回答

6

解決這個問題的最佳解決方案是知名

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

<xsl:template match="/"> 
    <xsl:variable name="voutType"> 
     <xsl:choose> 
     <xsl:when test="long convoluted expression">123</xsl:when> 
     <xsl:when test="next very long expression">124</xsl:when> 
     <!-- Etcetera ... --> 
     </xsl:choose> 
    </xsl:variable> 

    <Class><xsl:value-of select="$voutType"</Class> 
     <xsl:choose> 
      <xsl:when test="not($voutType > 99)"> 
       <!-- elements for classes 0 - 99 here --> 
      </xsl:when> 
      <xsl:otherwise> 
       <!-- elements for classes 100-199 here --> 
      </xsl:otherwise> 
     <xsl:choose> 
</xsl:template> 
</xsl:stylesheet> 

請注意

  1. 爲了給值的變量($voutType),<xsl:choose>指令必須是裏面的機體的<xsl:variable>

  2. 您只需指定<Class>元素一次 - 在其他任何位置之外。

  3. 如果元件名稱已知,則不必使用<xsl:element>

+0

這是一個美麗的解決方案。與其他解決方案一樣易於維護,但更短。你可以在一個我不知道的變量中嵌套選擇。謝謝! – diskis 2010-07-02 13:52:20

+0

@diskis:我很高興你不接受我的回答。這似乎不夠,但我認爲這可能會讓你朝着正確的方向前進。這絕對是更好的方式。 – MJB 2010-07-02 14:09:02

+0

什麼使得任何解決方案「衆所周知」? – n611x007 2015-05-08 11:00:39

0

我只做過幾次XSLT,但每次看起來像是一個巨大的維護噩夢。無論如何,我認爲你可以設置一個變量來說明這個類是什麼,然後調用一個函數作爲xsl:template作爲arg與類匹配。您會將該函數聲明爲xsl:template name,因爲您不想自動匹配它。在函數內部,你應該能夠編寫這100個值。不確定這是否有幫助,但它可能以某種方式組織代碼。

+0

是的,謝謝。快速測試表明,這將完全符合我的目的。現在只需要學習xml:with-param語法,而且我會少花一些模板。 – diskis 2010-07-02 13:11:26

1

如果你想可以很容易地指定了一堆屬性(!標籤又名元素),那麼它聽起來好像屬性集是你需要什麼,你可能不需要變量:

http://www.w3.org/TR/xslt#attribute-sets

這假定屬性值本身不依賴於類的值;只有他們的存在。

如果元素真的是你的意思,請嘗試使用具有輸入參數的命名模板。在你的樣式表的頂層:

<xsl:template name="classdef"> 
    <xsl:param name="classid"/> 
    <!-- Note: I put the class elem in here so I don't have to 
     write individual class ids more than once --> 
    <xsl:element name="Class"><xsl:value-of select="$classid"/></xsl:element> 
    <xsl:choose> 
    <xsl:when test="$classid > 99"> 
     ... 
    </xsl:when> 
    </xsl:choose> 
</xsl:template> 

,並在其他的模板:

<xsl:call-template name="classdef"> 
    <xsl:with-param name="classid">124</xsl:with-param> 
</xsl:call-template> 

對PARAMS更多信息請參見http://www.w3.org/TR/xslt#variables

+0

謝謝,這與MJB發佈的解決方案基本相同,並且可以完美滿足我的需求。 我會回來給你一個upvote當我得到足夠的聲譽做到這一點:) – diskis 2010-07-02 13:16:17