Hi Justin,
Please try the XSL -
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xalan="http://xml.apache.org/xalan">
<xsl:output method="xml" version="1.0"
encoding="UTF-8" indent="yes"/>
<xsl:key name="by-restr" match="r_ele" use="restr" />
<xsl:template match="/entry">
<entry>
<xsl:variable name="rtf">
<xsl:for-each select="r_ele">
<r_ele>
<reb>
<xsl:value-of select="reb"/>
</reb>
<restr>
<xsl:for-each select="re_restr">
<xsl:sort select="."/>
<xsl:value-of select="."/>
<xsl:if test="position() != last()">
<xsl:text>,</xsl:text>
</xsl:if>
</xsl:for-each>
</restr>
</r_ele>
</xsl:for-each>
</xsl:variable>
<xsl:for-each select="xalan:nodeset($rtf)/r_ele">
<xsl:if test="generate-id(.) =
generate-id(key('by-restr', restr)[1])">
<group>
<rebs>
<xsl:for-each select="key('by-restr',
restr)">
<reb> <xsl:value-of
select="reb" />
</reb>
</xsl:for-each>
</rebs>
<re_restrs>
<xsl:if test="restr != '' ">
<xsl:call-template name="tokenise-restr">
<xsl:with-param name="str"
select="restr" />
<xsl:with-param name="delim"
select="','" />
</xsl:call-template>
</xsl:if>
</re_restrs>
</group>
</xsl:if>
</xsl:for-each>
</entry>
</xsl:template>
<xsl:template name="tokenise-restr">
<xsl:param name="str" />
<xsl:param name="delim" />
<xsl:if test="not(contains($str, $delim))">
<re_restr>
<xsl:value-of select="$str" />
</re_restr>
</xsl:if>
<xsl:if test="substring-after($str, $delim) != ''
">
<re_restr>
<xsl:value-of select="substring-before($str,
$delim)" />
</re_restr>
<xsl:call-template name="tokenise-restr">
<xsl:with-param name="str"
select="substring-after($str, $delim)" />
<xsl:with-param name="delim" select="$delim"
/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Regards,
Mukul
--- Justin Anderson <justin_anderson(_at_)mac(_dot_)com> wrote:
I'll start this off by mentioning that I started to
learning XSLT a
week ago, so please don't be too harsh with me if
the answer to this
question is obvious.
A description of the source and the desired output
in plain english:
The xml file I'm using is an Asian dictionary in
which different
pronounciations (reb) are limited to specific
characters (re_restr).
Sometimes certain pronounciations have the same set
of restrictions. In
those cases, I'd like to group them together. I made
a dummy entry
below based on numbers. 12 and 21 both contain 'one'
and 'two', so they
should be grouped together. That's what I'm trying
to do.
I'm trying to do single-level Muenchian grouping of
r_ele elements by
their re_restr children, of which there can be 0 to
infinity instances
in any order. I'm not sure if Muenchian grouping
works when the 'use'
element doesn't exist all the time, and I have no
clue how to make the
'use' element consider all of the re_restr children
in an r_ele at the
same time.
I've included a sample of the xml source file, the
xsl file (which I'm
pretty sure isn't anything like I need it to be),
the desired xml
output, and the actual xml output.
Thanks in advance for any light shed on this,
Justin Anderson
XML source file:
<?xml version="1.0" encoding="UTF-8"?>
<entry>
<k_ele>
<keb>one</keb>
</k_ele>
<k_ele>
<keb>two</keb>
</k_ele>
<k_ele>
<keb>three</keb>
</k_ele>
<r_ele>
<reb>12</reb>
<re_restr>one</re_restr>
<re_restr>two</re_restr>
</r_ele>
<r_ele>
<reb>32</reb>
<re_restr>two</re_restr>
<re_restr>three</re_restr>
</r_ele>
<r_ele>
<reb>21</reb>
<re_restr>two</re_restr>
<re_restr>one</re_restr>
</r_ele>
</entry>
XSL file:
<?xml version='1.0' encoding='utf-8' ?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml"/>
<xsl:key name="r_ele-by-re_restr" match="r_ele"
use="re_restr"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="entry">
<entry>
<xsl:for-each
select="r_ele[generate-id(.)=generate-id(key('r_ele-by-
re_restr',re_restr))]">
<xsl:sort select="reb" order="ascending"/>
<group>
<xsl:for-each
select="key('r_ele-by-re_restr',re_restr)">
<xsl:sort select="reb"/>
<rebs>
<reb>
<xsl:value-of
select="reb"/>
</reb>
</rebs>
<re_restrs>
<xsl:for-each select="re_restr">
<xsl:sort select="."
order="ascending" />
<re_restr>
<xsl:value-of
select="."/>
</re_restr>
</xsl:for-each>
</re_restrs>
</xsl:for-each>
</group>
</xsl:for-each>
</entry>
</xsl:template>
</xsl:stylesheet>
Desired results:
<entry>
<group>
<rebs>
<reb>12</reb>
<reb>21</reb>
</rebs>
<re_restrs>
<re_restr>one</re_restr>
<re_restr>two</re_restr>
</re_restrs>
</group>
<group>
<rebs>
<reb>32</reb>
</rebs>
<re_restrs>
<re_restr>two</re_restr>
<re_restr>three</re_restr>
</re_restrs>
</group>
</entry>
Current actual results:
<entry>
<group>
<rebs>
<reb>12</reb>
</rebs>
<re_restrs>
<re_restr>one</re_restr>
<re_restr>two</re_restr>
</re_restrs>
</group>
<group>
<rebs>
<reb>21</reb>
</rebs>
<re_restrs>
<re_restr>one</re_restr>
<re_restr>two</re_restr>
</re_restrs>
</group>
<group>
<rebs>
<reb>32</reb>
</rebs>
<re_restrs>
<re_restr>two</re_restr>
<re_restr>three</re_restr>
</re_restrs>
</group>
</entry>
__________________________________
Do you Yahoo!?
Yahoo! Mail - 50x more storage than other providers!
http://promotions.yahoo.com/new_mail