[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

RE: creating a head-letter for directory

Subject: RE: creating a head-letter for directory
From: "Robby Pelssers" <robby.pelssers@xxxxxxxxx>
Date: Mon, 18 Jan 2010 10:12:09 +0100
RE:  creating a head-letter for directory
Hi Dorothy,

Based on the input file you gave... the xslt below will do exactly what
you want:

<?xml version="1.0" encoding="UTF-8"?>

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

  <xsl:template match="/">
    <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="root">
    <output>
      <xsl:for-each-group select="data" group-by="substring(name, 1,1)">
        <letter><xsl:value-of select="current-grouping-key()"/></letter>
        <xsl:for-each select="current-group()">
          <name>
            <xsl:value-of select="name"/>
          </name>
        </xsl:for-each>
      </xsl:for-each-group>
    </output>
  </xsl:template>

  <!-- copy all nodes and attributes which are not processed by one of
available templates -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>


Cheers,
Robby Pelssers


-----Original Message-----
From: Hoskins & Gretton [mailto:hoskgret@xxxxxxxxxxxxxxxx]
Sent: Monday, January 18, 2010 6:07 AM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject:  creating a head-letter for directory

HI, I would like to understand, given a flat sort of data extraction,
of the type
<?xml version="1.0" encoding="UTF-8"?>
<root>
     <data>
         <name>Aname</name>
         <!-- other elements such as <location> follow, all related
to the <name> -->
     </data>
     <data>
         <name>Hname</name><!-- other elements such as <location> follow
-->
     </data>
     <data>
         <name>Dname</name><!-- other elements such as <location> follow
-->
     </data>
     <data>
         <name>Wname</name><!-- other elements such as <location> follow
-->
     </data>
     <data>
         <name>Anothername</name><!-- other elements such as
<location> follow -->
     </data>
     <data>
         <name>Whatevername</name><!-- other elements such as
<location> follow -->
     </data>
</root>

what are the groupings and keys needed to accomplish this (even
flatter) output?

<output>
         <letter>A</etter>
         <name>Aname</name><!-- other elements such as <location> follow
-->
         <name>Anothername</name><!-- other elements such as
<location> follow -->
         <letter>D</etter>
         <name>Dname</name><!-- other elements such as <location> follow
-->
         <letter>H</etter>
         <name>Hname</name><!-- other elements such as <location> follow
-->
         <letter>W</etter>
         <name>Wname</name><!-- other elements such as <location> follow
-->
         <name>Whatevername</name><!-- other elements such as
<location> follow -->
<output>

I know that I first need to identify which first letters exist in the
set of <data> elements, and then generate a <letter> element
containing that first letter, followed by all the data elements
children <name> that have a matching first letter. But I'm getting a
<letter> element every time, rather than once for each unique
occurrence, followed by the <name> elements which have a matching
first letter. How do I generate the <letter> once, but follow it with
all of the <name> (and related) elements? I think I need to move the
<leter> element builder up out of the for-each  loop that it is in,
but I don't know how I then would get each letter only once for the
set of all <data> elements.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
     <xsl:template match="/">
         <xsl:variable name="blocks" select="root/data"/>
         <xsl:element name="output">
             <xsl:for-each-group select="$blocks" group-by="name">
                 <xsl:sort select="current-grouping-key()"/>
                 <xsl:variable name="currentGroup"
select="current-grouping-key()"/>
                 <xsl:variable name="headletter"
select="substring($currentGroup,1,1)"/>
                 <xsl:for-each select="."><!-- context here should be
data -->
                     <xsl:element name="letter">
                         <xsl:value-of select="$headletter"/>
                     </xsl:element>
                     <xsl:apply-templates
select="name[substring(.,1,1)=$headletter]"></xsl:apply-templates>
                 </xsl:for-each>
             </xsl:for-each-group>
         </xsl:element>
     </xsl:template>

     <xsl:template match="name">
         <!-- is there a way that I should use the $headletter here? -->
         <xsl:element name="name"><xsl:value-of
select="."/></xsl:element>
     </xsl:template>
</xsl:stylesheet>

output with duplicate <letter> values:
<?xml version="1.0" encoding="UTF-8"?>
<output>
         <letter>A</letter>
         <name>Aname</name>
         <letter>A</letter>
         <name>Anothername</name>
         <letter>D</letter>
         <name>Dname</name>
         <letter>H</letter>
         <name>Hname</name>
         <letter>W</letter>
         <name>Whatevername</name>
         <letter>W</letter>
         <name>Wname</name>
</output>

Regards, Dorothy

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.