xslt
  • xpath
  • 2013-10-31 155 views 1 likes 
    1

    我有一種情況,我必須根據變量的內容進行排序。If Else If Else sort XSLT1.0

    在XSLT 2.0我做的:

    <xsl:sort select=" 
         if ($column = 'name') then name 
         else if ($column = 'score') then count(//scores/score[@id=current()/@id]) 
         else if ($column = 'rating) then count(//ratings/rating[@id=current()/@id]) 
         else name" 
         order={$sort}" /> 
    

    但我需要1.0版本做的,我無法找到一個替代。我應該怎麼做?

    回答

    3

    可以定義多個排序鍵,並安排他們中的一些是無效的(通過給所有節點該排序鍵的值相同)

    <xsl:sort select="name[$column = 'name']"/> 
    <xsl:sort select="count(/self::node() 
          [$column = 'score']/scores/score[@id=current()/@id])"/> 
    <xsl:sort select="count(/self::node() 
          [$column = 'rating']/ratings/rating[@id=current()/@id])"/> 
    <xsl:sort select="name"/> 
    
    +0

    非常酷。那些「無效」的類別通常是O(1)還是O(N)? – harpo

    +0

    我希望大多數實現只執行一種排序,可能會評估每個元素的所有排序鍵,然後比較鍵直到找到一個不同的鍵。因此,與2.0解決方案相比,評估和比較排序鍵肯定會有額外的成本,但可能不是很高。任何體面的處理器都會有一種性能爲O(N log N)的排序。 –

    0

    當我在XSLT 1.0中遇到這種情況時,我使用了xsl:choose。當然,這意味着你必須重複你正在分類的東西(apply-templatesfor-each),這是次優的。

    如果你真的不想這樣做,你也可以創建一個包含排序鍵的節點集。這需要在大多數實現中支持的node-set()擴展函數(我已經使用過)。

    在XPath 1.0中有用於執行內聯條件的構造:請參閱this answer from Tomalak。即使是在二元條件下,我也沒有使用它,我擔心任何使用它的人有三種情況。但這是你的電話。

    1

    這肯定是醜陋的,但可能是更緊湊的方式之一,以退出這個功能:

    <xsl:key name="score" match="scores/score" use="@id" /> 
        <xsl:key name="rating" match="ratings/rating" use="@id" /> 
    
        <!-- ... --> 
    
        <xsl:variable name="useName" 
           select="$column != 'score' and $column != 'rating'" /> 
        <xsl:apply-templates select="something"> 
        <xsl:sort order="{$sort}" 
           data-type="{substring('numbertext', 1 + 6 * $useName, 6)}" 
           select="concat(
             substring(count(key('score', @id])), 1, 
                100 * ($column = 'score')), 
             substring(count(key('rating', @id])), 1, 
                100 * ($column = 'rating')), 
             substring(name, 1, 100 * $useName) 
            )" 
           /> 
        </xsl:apply-templates> 
    
    相關問題