xml - How to use XSL 1.0 to Group Elements by Content -
so need group content using xsl 1.0. in specific use case, need convert following:
<elementfoo name='1'> <bar>groupa</bar> </elementfoo> <elementfoo name='2'> <bar>groupb</bar> </elementfoo> <elementfoo name='3'> <bar>groupc></bar> </elementfoo> <elementfoo name='4'> <bar>groupa</bar> </elementfoo> <elementfoo name='5'> <bar>groupa</bar> </elementfoo> <elementfoo name='6'> <bar>groupc></bar> </elementfoo>
and need output this:
group a:
foo 1
foo 4
foo 5
group b:
foo 2
group c:
foo 3
foo 6
basically, need order things according content in specific child element, i'm not entirely sure how without bunch of if statements. there can large number of groups, , number of groups not known.
the following xsl
should group foo's
requested, , don't need bother pesky keys
! modified xml
(to add root
element, , fix name of groupc
), , made assumption how want output xml. let me know if helps:
source xml
<root> <elementfoo name='1'> <bar>groupa</bar> </elementfoo> <elementfoo name='2'> <bar>groupb</bar> </elementfoo> <elementfoo name='3'> <bar>groupc</bar> </elementfoo> <elementfoo name='4'> <bar>groupa</bar> </elementfoo> <elementfoo name='5'> <bar>groupa</bar> </elementfoo> <elementfoo name='6'> <bar>groupc</bar> </elementfoo> </root>
xsl transformation
<xsl:template match="/root"> <root> <xsl:for-each select="//bar[not(.=preceding::*)]"> <xsl:variable name="groupname" select="." /> <xsl:element name="{$groupname}"> <xsl:for-each select="//elementfoo[bar=$groupname]"> <foo><xsl:value-of select="@name" /></foo> </xsl:for-each> </xsl:element> </xsl:for-each> </root> </xsl:template>
output xml
<root xmlns="http://www.w3.org/1999/xhtml"> <groupa> <foo>1</foo> <foo>4</foo> <foo>5</foo> </groupa> <groupb> <foo>2</foo> </groupb> <groupc> <foo>3</foo> <foo>6</foo> </groupc> </root>
a quick explanation:
- the first
for-each
, iterates on each distinctbar
value once (i.e. 'groupa', 'groupb', 'groupc') - the variable
groupname
, stores group's name (e.g. 'groupa') - the
element
tag, creates element group (e.g.<groupa>
) - the second
for-each
, iterates onelementfoo's
have bar value equal$groupname
- and finally,
value-of
prints out@name
currentelementfoo
simple enough?
Comments
Post a Comment