tags:

views:

82

answers:

3

I have the following XML:

  <Info>
    <Name>Dan</Name>
    <Age>24</Age>
  </Info>
  <Info>
    <Name>Tom</Name>
    <Age>15</Age>
  </Info>
  <Info>
    <Name>Dan</Name>
    <Age>24</Age>
  </Info>
  <Info>
    <Name>James</Name>
    <Age>18</Age>
  </Info>

And I need to produce the following HTML:

<ul class="data">
<li>Dan</li>
<li>Dan</li>
</ul>

<ul class="data">
<li>James</li>
</ul>

<ul class="data">
<li>Tom</li>
<li>Tom</li>
</ul>

As well as producing the output it needs to sort based on the Name also. Any help appreciated, started by looking at group-by but couldnt work out how to get it finished:

Pretty sure its wrong?

<xsl:for-each-group select="Info" group-by="@Name">??????
<xsl:for-each-group select="current-group()" sort-by="@Name">
A: 

I don't have an xslt 2.0 parser to test this, but at the very least you will need to change "@Name" to just "Name", since it is a subelement not an attribute.

Mike Miller
Im no closer to a solution, Im doing something wrong!
danit
+1  A: 

I'm not sure why your result has two 'Tom' elements, I assume you have an extra node in the XML that you didn't provide in your sample.

Anyway, the XSLT would look something like this:

<xsl:for-each-group select="Info" group-by="Name">
    <xsl:sort select="current-grouping-key()"/>
    <ul class="data">
    <xsl:for-each select="current-group()/Name">
        <li><xsl:value-of select="." /></li>
    </xsl:for-each>
    </ul>
</xsl:for-each-group>

I don't have an XSLT 2.0 parser handy to test it, but I think that should work.

Timothy Walters
+2  A: 

I don't have an XSLT 2.0 parser, but to do it in XSLT 1.0 at least you could use Muenchian Grouping to do this...

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
    <xsl:output encoding="utf-8" method="html" version="1.0"/>

    <xsl:key name="Names" match="Name" use="."/>

    <xsl:template match="/">
     <xsl:for-each select="//Info[generate-id(Name) = generate-id(key('Names', Name)[1])]">
     <xsl:sort select="Name" />
     <ul class="data">
      <xsl:for-each select="key('Names', Name)">
      <li><xsl:value-of select="." /></li>
      </xsl:for-each>
      </ul>
     </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>
Tim C