2012-05-01 148 views
0

我有一個樣品XSLT計數兄弟

<Root> 
    <A rename="yes,it is option 1"/> 
    <C rename="no"/> 
    <A rename="yes,it is option 2"/> 
    <C rename="no"/> 
    <C rename="yes"/> 
    <C rename="no"/> 
    <A rename="yes,it is option 3"/> 
    <A rename="yes,it is option 4"/> 
    <C rename="no"/> 
    <C rename="yes"/> 
    <C rename="no"/>  
    <C rename="no"/>   
</Root> 

然後我將模板應用於這個樣子

<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="A"> 
      <p><b>option1: <xsl:value-of select="count(following-sibling::C[preceding-sibling::A[1]/@rename[contains(.,'option 1')]])"/></b></p> 
      <p><b>option2: <xsl:value-of select="count(following-sibling::C[preceding-sibling::A[1]/@rename[contains(.,'option 2')]])"/></b></p>    
      <p><b>option3: <xsl:value-of select="count(following-sibling::C[preceding-sibling::A[1]/@rename[contains(.,'option 3')]])"/></b></p> 
      <p><b>option4: <xsl:value-of select="count(following-sibling::C[preceding-sibling::A[1]/@rename[contains(.,'option 4')]])"/></b></p>       
</xsl:template> 
</xsl:stylesheet> 

,但我想輸出這個樣子的,如果沒有下面的兄弟姐妹,我們只是忽略這個one.just打印這些@rename包含「選項」,也包含元素

option1: 1 

option2: 3 

option4: 4 

我所得到的是現在

option1: 1 

option2: 3 

option3: 0 

option4: 4 

option1: 0 

option2: 3 

option3: 0 

option4: 4 

option1: 0 

option2: 0 

option3: 0 

option4: 4 

option1: 0 

option2: 0 

option3: 0 

option4: 4 
+1

現在,這是一個很好的例子,不使用XML。爲什麼在你不給數據任何結構時使用結構化格式? – Tomalak

+0

另外*您沒有真正嘗試*您輸入的顯示XSLT代碼。我幾乎得到你想要的輸出。請在您的問題中多加一些注意,如果您的代碼和問題文本講述了兩個不同的故事,則無法幫助您。 – Tomalak

+0

我只是想簡化我的原始文件 –

回答

1

你指望所有跟隨最近一個元素Ç元素。這可以通過一個鍵來完成,到組中的所有這樣的Ç元件與相關聯的元件

<xsl:key name="lookup" match="C" use="generate-id(preceding-sibling::A[1])" /> 

爲了找到元素爲其以下Ç存在至少一個,那麼你這樣做:

<xsl:apply-templates select="A[key('lookup', generate-id())]" /> 

然後再以數的期權數量,你可以算的元素數量的關鍵,像這樣:

<xsl:value-of select="count(key('lookup', generate-id()))" /> 

當這個應用到你的XML樣本嘗試以下XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text" indent="yes"/> 
    <xsl:key name="lookup" match="C" use="generate-id(preceding-sibling::A[1])" /> 

    <xsl:template match="/Root"> 
     <xsl:apply-templates select="A[key('lookup', generate-id())]" /> 
    </xsl:template> 

    <xsl:template match="A"> 
     <xsl:value-of select="concat(@rename, ': ', count(key('lookup', generate-id())) , '&#13;&#13;')" /> 
    </xsl:template> 
</xsl:stylesheet> 

,下面是輸出:

yes,it is option 1: 1 

yes,it is option 2: 3 

yes,it is option 4: 4 

請注意,如果你想 '選項1',而不是'是的,這是選項1',你可以做concat('option', substring-after(@rename, 'option '))而不是隻是@rename

注意,這個問題可以簡化d,如果你重新構建你的XML。這樣的事情會好得多:

<Root> 
    <A rename="yes,it is option 1"> 
     <C rename="no"/> 
    </A> 
    <A rename="yes,it is option 2"> 
     <C rename="no"/> 
     <C rename="yes"/> 
     <C rename="no"/> 
    </A> 
    <A rename="yes,it is option 3"/> 
    <A rename="yes,it is option 4"> 
     <C rename="no"/> 
     <C rename="yes"/> 
     <C rename="no"/> 
     <C rename="no"/> 
    </A> 
</Root> 
+0

但A和C元素不是父母和孩子,他們只是兄弟姐妹, –

+0

是的,我知道!我只是說如果他們是父母和孩子,編碼XSLT將會很容易。 –

+0

是的,我更加困惑於處理這些兄弟關係 –

0

在XSLT 2.0這個變成一個簡單的分組問題,使用xsl:for-each-group指令。

<xsl:template match="Root"> 
    <xsl:for-each-group group-starting-with="A" select="*"> 
    <xsl:if test="count(current-group()) != 1"> 
     <p>Option <xsl:value-of select="substring-after(current-group()[1]/@rename, 'option ')"/> = <xsl:value-of select="count(current-group())-1"/></p>  </xsl:if> 
    </xsl:for-each-group> 
</xsl:template> 
+0

它似乎很有趣,我在哪裏可以找到更多這樣的例子? –

+0

我從書中學到了關於XSLT 2.0的所有知識,這是Wrox出色的XSLT 2.0程序員參考。 – samjudson

+0

哦,非常感謝你,這是一個XSLT 2.0程序員參考,第3版 邁克爾·凱 ISBN:978-0-7645-6909-8 平裝 960頁2004年8月 查看最近的這個稱號版 –