2012-11-26 23 views
0

這個問題從查詢如下上XSLT: Sorting based on sum of values from other nodesXSLT:路徑的替代部分取決於參數

我已經修飾以接收參數「步態」,其可以具有值I有這片的XSLT(感謝德米特) 'P'(PACE), 'T'(小跑)或 'A'(全部):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:key name="kOffspring" match="Horse" use="SireID"/> 
<xsl:param name="Gait"/> 

<xsl:template match="/*"> 
    <xsl:apply-templates select="Sires/Sire"> 
    <xsl:sort select="sum(key('kOffspring', ID)/*/Stakes)" 
      data-type="number" order="descending"/> 
    </xsl:apply-templates> 
</xsl:template> 

<xsl:template match="Sire"> 
    Sire <xsl:value-of select="concat(ID,' (', Name, ') Stakes: ')"/> 
    <xsl:value-of select="sum(key('kOffspring', ID)/*/Stakes)"/> 
</xsl:template> 
<xsl:template match="text()"/> 
</xsl:stylesheet> 

在上面的代碼是這塊

sum(key('kOffspring', ID)/*/Stakes 

有一種方法來替代星號部分與xml樹中節點的名稱取決於爲步態傳入的值?

超級簡單的XML是:

<t> 
    <Horses> 
     <Horse> 
      <ID>5</ID> 
      <Name>hrsE</Name> 
      <SireID>101</SireID> 
      <Pace> 
       <Stakes>100</Stakes> 
      </Pace> 
      <Trot> 
       <Stakes>300</Stakes> 
      </Trot> 
     </Horse> 
    </Horses> 
    <Sires> 
     <Sire> 
      <ID>101</ID> 
      <Name>srA</Name> 
      <LiveFoalsALL>117</LiveFoalsALL> 
     </Sire> 
    </Sires> 
</t> 

當$步態是 'A' 我想總和(鍵( 'kOffspring',ID)/ * /錦標(看在馬的所有子節點)

當$步態是 'P' 我想總和(鍵( 'kOffspring',ID)/佩斯/錦標(看在佩斯節點才發現錦標)

當$步態「 T'我想要sum(key('k後代',ID)/小跑/籌碼(在Trot節點中查找只能找到Stakes)

所以這是超簡化的例子。我試圖停止重複上百行代碼來迎合$ Gait的不同值。我在嘗試使用變量時玩過,但在路徑中使用密鑰時看不到如何更改節點路徑的值。我看到我可能在'match =「/ *」'模板中使用了一個選擇語句,但這只是用於排序,當我到達'Sire'模板時我仍然卡住 - 不想將'選擇'圍繞我所擁有的所有'選擇'值'的陳述'。

感謝您的任何建議。 Regards, Bryce Stenberg。

回答

2

只需使用

sum(key('kOffspring', ID)/*[name()=$Gait]/Stakes 
+0

嗨邁克爾,那看起來不錯。當我試圖在Pace和Trot節點上匹配時,我只是不知道設置$ Gait的值是多少?我嘗試了空字符串和'*'作爲值,但沒有奏效。我看到我可以使用像Pacers和Trotters這樣的兩個參數,它們在頂層適當設置(值或null)並使用'sum(key('kOffspring',ID)/ * [name()= $ Pacers和name()= $如果你有一個更好的方法,乾杯,布萊斯 – user1840734

+0

woops - 那應該是'或',如:sum(key('kOffspring',ID)/ * [name( )= $ Pacers或name()= $ Trotters]/Stakes' :-) ....'以'更好的方式'我的意思是隻用一個參數來做,因爲一些我更復雜的xslt/xml有5個不同的可能節點參與 – user1840734

+0

你可以定義一個變量$ Gaits,它是一串字符串,然後[name()= $ Gaits]將是真的,如果這個名字等於它們中的任何一個 –

1
<xsl:value-of select="sum(key('kOffspring', ID)/*/Stakes)" /> 

有沒有辦法來代替在XML樹,具體取決於所傳遞的步態什麼值的節點 名星號部分?

是......一個辦法是有XPath表達式內的「switch語句」:

sum(key('kOffspring', ID)/*[ 
    $Gait = 'A' or 
    (local-name() = (if ($Gait = 'P') then 'Pace' else 
         if ($Gait = 'T') then 'Trot')) 
    ]/Stakes) 

或者,你可以寫三個不同版本的<xsl:value-of>,一個對每個可能值$步態,並使用<xsl:choose>來選擇使用哪一個:

<xsl:choose> 
    <xsl:when test="$Gait = 'A'"> 
     <xsl:value-of select="sum(key('kOffspring', ID)/*/Stakes)" /> 
    </xsl:when> 
    <xsl:when test="$Gait = 'P'"> 
     <xsl:value-of select="sum(key('kOffspring', ID)/Pace/Stakes)" /> 
    </xsl:when> 
    etc. 

<xsl:choose>似乎更可讀的我,可能更有效,這取決於處理器;但這主要是一個偏好問題。

+0

嗨拉斯,感謝您的回覆。只是爲了澄清你的答案,在'Sires'模板中,我是否必須重複'選擇'或爲包含路徑的每個'select-value-value'切換語句(真正的xslt中有大約30個這樣的語句)?我猜想我希望可能有一些語法允許沿着' user1840734

+0

@OP:我很快就讀完了這個長長的問題,並沒有注意到表達式也被用到了。我的錯。很抱歉,沒有這樣的語法,你希望。我想知道你是否可以有用地定義考慮到「$步態」值的鍵......但我需要睡覺。 :-) – LarsH