Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XSLT
|
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old June 20th, 2006, 06:24 AM
Authorized User
 
Join Date: Jun 2006
Posts: 22
Thanks: 0
Thanked 0 Times in 0 Posts
Default Grouping based on attributes values

Hi there,

I am seriously struggling with XSLT and really appreaciate some pointers.

The following is part of my source XML

<cars>
    <model name="golf" manufacturer="volkswagon"/>
    <model name="camry" manufacturer="toyota"/>
    <model name="focus" manufacturer="ford"/>
    <model name="civic" manufacturer="honda"/>
    <model name="prizm" manufacturer="chevrolet"/>
    <model name="celica" manufacturer="toyota"/>
    <model name="mustang" manufacturer="ford"/>
    <model name="passat" manufacturer="volkswagon"/>
    <model name="accord" manufacturer="honda"/>
    <model name="corvette" manufacturer="chevrolet"/>
</cars>

My desired results is

<cars>
    <model manufacturer="volkswagon">
        <name>passat</name>
        <name>golf</name>
    </model>
    <model manufacturer="toyota">
        <name>celica</name>
        <name>camry</name>
    </model>
    <model manufacturer="ford">
        <name>mustang</name>
        <name>focus</name>
    </model>
    <model manufacturer="honda">
        <name>accord</name>
        <name>civic</name>
    </model>
    <model manufacturer="chevrolet">
        <name>corvette</name>
        <name>prizm</name>
    </model>
</cars>

I am basically trying to group the car names under its manufacturer. Could someone kindly point me to some reading material or is this a trivial task to achieve that it can be shown on this forum? Thanks

 
Old June 20th, 2006, 06:31 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

For XSLT 2.0 it's simply

<xsl:template match="cars">
<cars>
  <xsl:for-each-group select="model" group-by="@manufacturer">
    <model manufacturer="{current-grouping-key()}">
      <xsl:for-each select="current-group()">
        <name><xsl:value-of select="@name"/></name>
      </
    </
  </
</
</xsl:template>

For XSLT 1.0 grouping is rather more difficult, see http://www.jenitennison.com/xslt/grouping (or just search for XSLT grouping).

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old June 20th, 2006, 08:12 PM
Authorized User
 
Join Date: Jun 2006
Posts: 22
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Hi there,

I tried your suggestion as follows

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="2.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="@*|node()|comment()">
 <xsl:copy>
  <xsl:apply-templates select="@*|node()|comment()"/>
 </xsl:copy>
</xsl:template>

<xsl:template match="cars">
 <xsl:copy>
  <xsl:for-each-group select="model" group-by="@manufacturer">
   <model manufacturer="{current-grouping-key()}">
    <xsl:for-each select="current-group()">
     <name><xsl:value-of select="@name"/></name>
    </xsl:for-each>
   </model>
  </xsl:for-each-group>
 </xsl:copy>
</xsl:template>
</xsl:stylesheet>

I end up with the following result:

<root>
  <agent>
   <cars/>
  </agent>
</root>

Appreciate if you could point out whats is wrong with the XSLT?

 
Old June 21st, 2006, 03:08 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

I changed your stylesheet so the xsl:output says version="1.0" (there is no XML version 2.0). Then I ran it against the XML sample given in your original message, using Saxon 8.7.3. The result is:

<?xml version="1.0" encoding="UTF-8"?>
<cars>
   <model manufacturer="volkswagon">
      <name>golf</name>
      <name>passat</name>
   </model>
   <model manufacturer="toyota">
      <name>camry</name>
      <name>celica</name>
   </model>
   <model manufacturer="ford">
      <name>focus</name>
      <name>mustang</name>
   </model>
   <model manufacturer="honda">
      <name>civic</name>
      <name>accord</name>
   </model>
   <model manufacturer="chevrolet">
      <name>prizm</name>
      <name>corvette</name>
   </model>
</cars>

So I don't know what your problem is.

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old June 21st, 2006, 05:51 AM
Authorized User
 
Join Date: Jun 2006
Posts: 22
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thank you so much. It is working now. Dont know why it didnt work previously. cheers.






Similar Threads
Thread Thread Starter Forum Replies Last Post
Default Rows Based Upon Number of XML Attributes. Mr.T Infopath 0 November 5th, 2007 07:29 PM
xslt grouping with attributes Jimi XSLT 4 October 31st, 2007 10:56 AM
need html attribute based on xml attributes charles95621 XSLT 1 May 24th, 2007 05:21 PM
Get distinct values on *second* grouping of nodes. MissHenesy XSLT 4 October 23rd, 2006 10:34 AM
Rules based on attribute values... jacob XML 2 July 6th, 2005 01:50 PM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.