xslt - How to group neighbour-siblings -


i have this:

<root>   <a>foo</a>   <b>bar</b>   <groupme>foobar</groupme>   <groupme>baz</groupme>   <groupme>42</groupme>   <c>abc</c>   <d>def</d>   <groupme>foo</groupme>   <x>xyz</x>   <groupme>bar</groupme>   <groupme>foo</groupme>   <z>thats it</z> </root> 

now need groume's direct neighbours single node like:

<root>   <a>foo</a>   <b>bar</b>   <groupme>foobar baz 42</groupme>   <c>abc</c>   <d>def</d>   <groupme>foo</groupme>   <x>xyz</x>   <groupme>bar foo</groupme>   <z>thats it</z> </root> 

also groupme nodes containing other nodes, i've leave them provide simple example. groupme nodes apear in specific level, no groupme nodes in others root.

any me?

such grouping can achieved approach called "sibling recursion", problem suggest stylesheet follows:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform">  <xsl:strip-space elements="*"/> <xsl:output indent="yes"/>  <xsl:template match="@* | node()">   <xsl:copy>     <xsl:apply-templates select="@* | node()"/>   </xsl:copy> </xsl:template>  <xsl:template match="root/groupme[not(preceding-sibling::*[1][self::groupme])]">   <xsl:copy>     <xsl:apply-templates select="node()"/>     <xsl:apply-templates select="following-sibling::*[1][self::groupme][1]" mode="list"/>   </xsl:copy> </xsl:template>  <xsl:template match="root/groupme[preceding-sibling::*[1][self::groupme]]"/>   <xsl:template match="root/groupme[preceding-sibling::*[1][self::groupme]]" mode="list">   <xsl:text> </xsl:text>   <xsl:apply-templates select="node()"/>   <xsl:apply-templates select="following-sibling::*[1][self::groupme][1]" mode="list"/> </xsl:template>  </xsl:stylesheet> 

when applied input

<root>   <a>foo</a>   <b>bar</b>   <groupme>foobar</groupme>   <groupme>baz</groupme>   <groupme>42</groupme>   <c>abc</c>   <d>def</d>   <groupme>foo</groupme>   <x>xyz</x>   <groupme>bar</groupme>   <groupme>foo</groupme>   <z>thats it</z> </root> 

the result is

<root>   <a>foo</a>   <b>bar</b>   <groupme>foobar baz 42</groupme>   <c>abc</c>   <d>def</d>   <groupme>foo</groupme>   <x>xyz</x>   <groupme>bar foo</groupme>   <z>thats it</z> </root> 

as alternative sibling recursion possible "grab" following siblings key based approach:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform">  <xsl:strip-space elements="*"/> <xsl:output indent="yes"/>  <xsl:key    name="first"   match="root/groupme[preceding-sibling::*[1][self::groupme]]"   use="generate-id(preceding-sibling::groupme[not(preceding-sibling::*[1][self::groupme])][1])"/>  <xsl:template match="@* | node()">   <xsl:copy>     <xsl:apply-templates select="@* | node()"/>   </xsl:copy> </xsl:template>  <xsl:template match="root/groupme[not(preceding-sibling::*[1][self::groupme])]">   <xsl:copy>     <xsl:apply-templates select="node()"/>     <xsl:apply-templates select="key('first', generate-id())" mode="list"/>   </xsl:copy> </xsl:template>  <xsl:template match="root/groupme[preceding-sibling::*[1][self::groupme]]"/>  <xsl:template match="root/groupme" mode="list">   <xsl:text> </xsl:text>   <xsl:apply-templates select="node()"/> </xsl:template>  </xsl:stylesheet> 

Comments

Popular posts from this blog

c# - DetailsView in ASP.Net - How to add another column on the side/add a control in each row? -

javascript - firefox memory leak -

Trying to import CSV file to a SQL Server database using asp.net and c# - can't find what I'm missing -