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 May 14th, 2007, 05:23 PM
Authorized User
 
Join Date: May 2007
Posts: 79
Thanks: 0
Thanked 0 Times in 0 Posts
Default Grouping using tokenized strings

I am trying to group using <xsl:for-each-group> and tokenize() but have am not achieving the desired results. Better to look at the code.

Source XML:
<worksheet name="users">
  <user index="1">
    <cell name="User Name">Suzy Smith</cell>
    <cell name="role">developer</cell>
  </user>
  <user index="2">
    <cell name="User Name">Tom Case</cell>
    <cell name="role">project_manager;team_leader</cell>
  </user>
  <user index="3">
    <cell name="User Name">Ian Lloyd</cell>
    <cell name="role">project_manager;team_leader</cell>
  </user>
  <user index="4">
    <cell name="User Name">John Gerrard</cell>
    <cell name="role">project_manager;developer</cell>
  </user>
</worksheet>

I want to generate the following code, where users are grouped according to their role. For each role (project_manager, developer or team_leader), the result will be a group of users.

Desired Result XML:

<list>
<group>developer</group>
<user>Suzy Smith</user>
<user>John Gerrard</user>
</list>

The problem I am having is this. If all cell[@name='role'] values are delimited lists, then it works fine. Or if there is one value, but it is followed with a ';', it will be included in the same group the tokenized values. But when the value is a single role, it is processed separately and not included in the 'group'.

So what I am getting is something like this:

<list>
<group>developer</group>
<user>Suzy Smith</user>
</list>

<list>
<group>developer</group>
<user>John Gerrard</user>
</list>

The simplified version of the XSLT is:

<xsl:for-each-group select="user" group-by="tokenize(cell[@name='role'],';')">

  <xsl:element name="list">

    <xsl:element name="group">
      <xsl:value-of select="current-grouping-key()" />
    </xsl:element>


    <xsl:for-each select="current-group()/cell[@name='User Name'] ">
      <xsl:element name="user">
        <xsl:value-of select="." />
      </xsl:element>
    </xsl:for-each>

  </xsl:element>

</xsl:for-each-group>

I am using saxon 8. If anyone has any idea, would greatly appreciated it.
 
Old May 15th, 2007, 06:20 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

Your code works for me. With this stylesheet, using Saxon 8.9.0.3

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                version="2.0">

<xsl:template match="worksheet">
    <xsl:for-each-group select="user" group-by="tokenize(cell[@name='role'],';')">

      <xsl:element name="list">

        <xsl:element name="group">
          <xsl:value-of select="current-grouping-key()" />
        </xsl:element>

        <xsl:for-each select="current-group()/cell[@name='User Name'] ">
          <xsl:element name="user">
            <xsl:value-of select="." />
          </xsl:element>
        </xsl:for-each>
      </xsl:element>
    </xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>

I get this output:

<?xml version="1.0" encoding="UTF-8"?>
<list>
   <group>developer</group>
   <user>Suzy Smith</user>
   <user>John Gerrard</user>
</list>
<list>
   <group>project_manager</group>
   <user>Tom Case</user>
   <user>Ian Lloyd</user>
   <user>John Gerrard</user>
</list>
<list>
   <group>team_leader</group>
   <user>Tom Case</user>
   <user>Ian Lloyd</user>
</list>

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old May 15th, 2007, 01:06 PM
Authorized User
 
Join Date: May 2007
Posts: 79
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Sorry, I cleaned up the XML input, and I should not have. I think it is a white space issue. Is there any way to normalize-space when tokenizing?

<xsl:for-each-group select="row" group-by="tokenize(cell[@name='gdmsrole'],';')">

 
Old May 15th, 2007, 01:19 PM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

>Is there any way to normalize-space when tokenizing?

You can apply normalize-space() to the input before tokenizing but that will leave single spaces. If you simply want to ignore whitespace after the semicolon, then include it in the regex: tokenize($in, ';\s*')

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old May 15th, 2007, 01:40 PM
Authorized User
 
Join Date: May 2007
Posts: 79
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Forgive me for not fully understanding how to control this just yet. The input varies, therefore, I can't include whitespace handling in the regex.

One node:

<cell name="role" index="3">
coordinators;project_manager
</cell>

Another node to match for group (coordinators)

<cell name="role" index="3">
coordinators
</cell>

If I were to normalize-space on the input, just where would that fit into the stylesheet?






Similar Threads
Thread Thread Starter Forum Replies Last Post
strings RoniR VB.NET 2002/2003 Basics 1 May 4th, 2007 02:55 PM
strings bschleusner C# 2005 3 February 27th, 2007 11:46 PM
Protect cells and allow grouping/un-grouping sfreuden Excel VBA 4 December 14th, 2006 08:01 AM
Strings ldoodle Classic ASP Basics 0 June 28th, 2005 09:26 AM
strings Moharo Pro PHP 2 May 17th, 2004 06:15 AM





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