2016-05-31 40 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>