Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bmix/7ccc4bee71e46a81e25cf7c331d60dea to your computer and use it in GitHub Desktop.
Save bmix/7ccc4bee71e46a81e25cf7c331d60dea to your computer and use it in GitHub Desktop.
XSLT Grouping adjacent siblings
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:include href="identity.xsl"/>
<xsl:template match="/*/child"/>
<xsl:template match="/*/parent">
<xsl:variable name="A"
select="
following-sibling::parent[1]/preceding-sibling::*
|
following-sibling::*[count(current()/following-sibling::parent)=0]"/>
<xsl:variable name="B"
select="
following-sibling::*"/>
<xsl:copy>
<xsl:copy-of
select="
$B[count( .|$A ) = count( $A )][not(self::parent)]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:include href="identity.xsl"/>
<xsl:template match="/*/child"/>
<xsl:key name="k_adjChild"
match="/*/child"
use="generate-id(preceding-sibling::parent[1])"
/>
<xsl:template match="/*/parent">
<xsl:copy>
<xsl:copy-of select="key('k_adjChild', generate-id())" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:include href="identity.xsl"/>
<xsl:template match="child"/>
<xsl:template match="/*/parent">
<xsl:copy>
<xsl:copy-of
select="
following-sibling::child
[count( preceding-sibling::parent[1] | current()) = 1]" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:include href="identity.xsl"/>
<xsl:template match="child"/>
<xsl:template match="parent">
<xsl:copy>
<xsl:apply-templates
select=
"following-sibling::*[1][self::child]"
mode="merge"/>
</xsl:copy>
</xsl:template>
<xsl:template match="child" mode="merge">
<xsl:copy-of select="."/>
<xsl:apply-templates
select="
following-sibling::*[1][self::child]"
mode="merge"/>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:include href="identity.xsl"/>
<xsl:template match="child"/>
<xsl:template match="/*">
<xsl:for-each select="parent">
<xsl:copy>
<xsl:copy-of
select="
following-sibling::child
[count( preceding-sibling::parent[1] | current()) = 1]" />
</xsl:copy>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:include href="identity.xsl"/>
<xsl:template match="/*/child"/>
<xsl:template match="/*/parent">
<xsl:copy>
<xsl:variable name="children"
select="following-sibling::child" />
<xsl:for-each select="following-sibling::*">
<xsl:variable name="index"
select="position()"/>
<xsl:if test="
generate-id( . ) = generate-id( $children[$index] )">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
<root>
<parent>A</parent>
<child>1</child>
<child>2</child>
<parent>B</parent>
<child>1</child>
<child>2</child>
<child>3</child>
<parent>C</parent>
<child>1</child>
</root>
<root>
<parent>
<child>1</child>
<child>2</child>
</parent>
<parent>
<child>1</child>
<child>2</child>
<child>3</child>
</parent>
<parent>
<child>1</child>
</parent>
</root>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment