2016-05-31 60 views
2

我試圖把這種XML的相同元素的塊:XSLT - 選擇

<!--- potential other elements before--> 
<li>bla</li> 
<li>bli</li> 
<li>blo</li> 
<anytag/> 
<li>pla</li> 
<li>pli</li> 
<li>plo</li> 

到:

<!--- potential other elements before--> 
<ul> 
<li>bla</li> 
<li>bli</li> 
<li>blo</li> 
</ul> 
<anytag/> 
<ul> 
<li>pla</li> 
<li>pli</li> 
<li>plo</li> 
</ul> 

所以基本上,選擇所有<li>是兄弟姐妹,沒有任何他們之間的其他元素。

我正在使用XSLT 2.0。

所以我想在做類似的:

<xsl:template match="li[1]"> 
    <ul> 
     <li> 
     <xsl:value-of select="." /> 
     </li> 
     <xsl:apply-templates select="following-sibling::li[preceding-sibling::node()][1]" mode="add-to-ul"/> 
    </ul> 
    </xsl:template> 

<xsl:template match="li" mode="add-to-ul"> 
    <li> 
     <xsl:value-of select="." /> 
    </li> 
    </xsl:template> 

    <xsl:template match="li"> 
    </xsl:template> 

首先,這看上去並不是很優雅,而且它並沒有因爲李的工作,如果我有幾個[1]失敗清單,顯然。

有什麼想法?

回答

3

在XSLT 2.0中,您可以使用xsl:for-each-group指令輕鬆進行分組。

例如:

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 

<xsl:template match="root"> 
    <root> 
     <xsl:for-each-group select="*" group-adjacent="boolean(self::li)"> 
      <xsl:choose> 
       <xsl:when test="current-grouping-key()"> 
        <ul> 
         <xsl:copy-of select="current-group()"/> 
        </ul> 
       </xsl:when> 
       <xsl:otherwise> 
        <xsl:copy-of select="current-group()"/> 
       </xsl:otherwise> 
      </xsl:choose> 
     </xsl:for-each-group> 
    </root> 
</xsl:template> 

</xsl:stylesheet> 

注意,這需要從父節點(在你的例子未顯示)的情況下調用。

+0

對於每組來說,好主意,謝謝:) – Flag

3

這裏是純XSLT 1.0溶液(短和更簡單),該可以在任何瀏覽器內執行:

<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:key name="kGroup" match="li" 
      use="generate-id(preceding-sibling::*[not(self::li)][1])"/> 

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

    <xsl:template match="li[not(preceding-sibling::*[1][self::li])]"> 
    <ul> 
     <xsl:copy-of select="key('kGroup', generate-id(preceding-sibling::*[1]))"/> 
    </ul> 
    </xsl:template> 
    <xsl:template match="li"/> 
</xsl:stylesheet> 

當在下面的XML文檔施加這種轉變:

<t> 
    <a/> 
    <b/> 
    <li>bla</li> 
    <li>bli</li> 
    <li>blo</li> 
    <anytag/> 
    <li>pla</li> 
    <li>pli</li> 
    <li>plo</li> 
    <c/> 
</t> 

想要的,正確的結果產生

<t> 
    <a/> 
    <b/> 
    <ul> 
     <li>bla</li> 
     <li>bli</li> 
     <li>blo</li> 
    </ul> 
    <anytag/> 
    <ul> 
     <li>pla</li> 
     <li>pli</li> 
     <li>plo</li> 
    </ul> 
    <c/> 
</t> 

第二部分。流程多層次的嵌套列表

只是一個小的調整改造:

<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:key name="kGroup" match="li" 
     use="concat(generate-id(..), generate-id(preceding-sibling::*[not(self::li)][1]))"/> 

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

    <xsl:template match="li[not(preceding-sibling::*[1][self::li])]"> 
    <ul> 
     <xsl:apply-templates mode="li" select= 
     ". | key('kGroup', concat(generate-id(..), 
          generate-id(preceding-sibling::*[not(self::li)][1])) 
     ) 
      [position() >1]"/> 
    </ul> 
    </xsl:template> 
    <xsl:template match="*" mode="li"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
    </xsl:template> 
    <xsl:template match="li"/> 
</xsl:stylesheet> 

使我們能夠在多個深度正確處理嵌套的列表,這樣

<t> 
    <a/> 
    <b/> 
    <li>bla</li> 
    <li>bli 
     <a> 
      <li>gla</li> 
      <li>gli</li> 
      <d> 
       <li>glo</li> 
      </d> 
     </a> 
    </li> 
    <li>blo</li> 
    <anytag/> 
    <li>pla</li> 
    <li>pli</li> 
    <li>plo</li> 
    <c/> 
</t> 

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

<t> 
    <a/> 
    <b/> 
    <ul> 
     <li>bla</li> 
     <li>bli 
     <a> 
      <ul> 
       <li>gla</li> 
       <li>gli</li> 
      </ul> 
      <d> 
       <ul> 
        <li>glo</li> 
       </ul> 
      </d> 
     </a> 
     </li> 
     <li>blo</li> 
    </ul> 
    <anytag/> 
    <ul> 
     <li>pla</li> 
     <li>pli</li> 
     <li>plo</li> 
    </ul> 
    <c/> 
</t>