XSLT: Choose a great one, but slightly different from other examples.

I have the following XML:

<a> <b> <d>D1 content (can include child nodes)</d> </b> <b> <c>C1 content (can include child nodes)</c> </b> <b> <e>E1 content (can include child nodes)</e> </b> <b> <c>C2 content (can include child nodes)</c> </b> </a> 

Using XSLT 1.0, I just need to produce this: "cde"; that is, a separate list of immediate child names / a / b / ordered by node name. Each b has exactly one child of any name.

I can create "ccde":

 <xsl:for-each select="/a/b/*"> <xsl:sort select="name(.)"/> <xsl:value-of select="name(.)" /> </xsl:for-each> 

I tried using the usual previous-sibling :: comparison, but since each b has only one child, the previous brother is always nothing.

+2
xslt distinct
Nov 28 '09 at 18:23
source share
2 answers

First add this key element at the beginning of XSL: -

 <xsl:key name="tagNames" match="/a/b/*" use="name()" /> 

Now yours for each cycle may look like this: -

 <xsl:template match="/*"> <xsl:for-each select="/a/b/*[count(. | key('tagNames', name())[1]) = 1]"> <xsl:sort select="name()" /> <xsl:value-of select="name()" /> </xsl:for-each> </xsl:template> 
+1
Nov 28 '09 at 18:40
source share

You can use the Muenchian method:

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:key name="groupIndex" match="*" use="name()" /> <xsl:template match="/"> <xsl:apply-templates select="a/b"/> </xsl:template> <xsl:template match="b"> <xsl:apply-templates select="*[1][generate-id(.) = generate-id(key('groupIndex', name())[1])]" mode="group" /> </xsl:template> <xsl:template match="*" mode="group"> <xsl:value-of select="name()"/> </xsl:template> </xsl:stylesheet> 
0
Nov 28 '09 at 19:03
source share



All Articles