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 July 7th, 2011, 12:00 PM
Registered User
 
Join Date: Apr 2011
Posts: 8
Thanks: 3
Thanked 0 Times in 0 Posts
Default Some advice needed on grouping again

Hi there, I've looked through some of the grouping topics here, but wasn't able to find a real match so i'm hoping for some advice on what I'm doing wrong.

Here's my XML file :

Code:
<Book>
	<File>
		<Para tag="BSub">
			<Content>some data</Content>
		</Para>
		<Para tag="BSub">
			<Content>some data</Content>
		</Para>
		<Para tag="BSub">
			<Content>some data</Content>
		</Para>
		<Para tag="BSub">
			<Content>some data</Content>
		</Para>
		<Para tag="L3">
			<Content>some data</Content>
		</Para>
		<Para tag="BSub">
			<Content>some data</Content>
		</Para>
		<Para tag="BSub">
			<Content>some data</Content>
		</Para>
		<Para tag="BSub">
			<Content>some data</Content>
		</Para>
		<Para tag="L1">
			<Content>some data</Content>
		</Para>
		<Para tag="B_bold">
			<Content>some data</Content>
		</Para>
		<Para tag="BSub">
			<Content>some data</Content>
		</Para>
		<Para tag="B_bold">
			<Content>some data</Content>
		</Para>
	</File>
</Book>
And what I'f like to get is the following ; All Para elements having BSub tag attribute should be renamed to 'li' and grouped in a ul, the rest remains unchanged for now. So below is the outcome I'd like to get :

Code:
<Book>
	<File>
		<ul>
			<li tag="BSub">
				<Content>some data</Content>
			</li>
			<li tag="BSub">
				<Content>some data</Content>
			</li>
			<li tag="BSub">
				<Content>some data</Content>
			</li>
			<li tag="BSub">
				<Content>some data</Content>
			</li>
		</ul>
		<Para tag="L3">
			<Content>some data</Content>
		</Para>
		<ul>
			<li tag="BSub">
				<Content>some data</Content>
			</li>
			<li tag="BSub">
				<Content>some data</Content>
			</li>
			<li tag="BSub">
				<Content>some data</Content>
			</li>
		</ul>
		<Para tag="L1">
			<Content>some data</Content>
		</Para>
		<Para tag="B_bold">
			<Content>some data</Content>
		</Para>
		<ul>
			<li tag="BSub">
				<Content>some data</Content>
			</li>
		</ul>
		<Para tag="B_bold">
			<Content>some data</Content>
		</Para>
	</File>
</Book>
The xslt I use is the following :

Code:
	
<xsl:template match="File">
    <xsl:for-each-group select="Para" group-by="@tag = 'BSub'">
      <xsl:choose>
        <xsl:when test="current-grouping-key()">
          <ul>
			  <xsl:apply-templates select="current-group()"/>
          </ul>
        </xsl:when>
        <xsl:otherwise>
			  <xsl:apply-templates select="current-group()"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:for-each-group>
  </xsl:template>
But this results in following : All my BSub's are grouped in a single node, and all the rest is grouped in a second node. While what I wanted is more like

> Start at first node, as soon as you see BSub's group these till the next none BSub, and continue like this till you reach the end. For some reason I'm not able to grasp the logic behind grouping, and all example on the net are rather simplified. So, if you could tell me how to do it right (and even more important why I need to do it like that) I'd be very grateful.

Code:
<Book>
	<ul>
		<Para tag="BSub">
			<Content>some data</Content>
		</Para>
		<Para tag="BSub">
			<Content>some data</Content>
		</Para>
		<Para tag="BSub">
			<Content>some data</Content>
		</Para>
		<Para tag="BSub">
			<Content>some data</Content>
		</Para>
		<Para tag="BSub">
			<Content>some data</Content>
		</Para>
		<Para tag="BSub">
			<Content>some data</Content>
		</Para>
		<Para tag="BSub">
			<Content>some data</Content>
		</Para>
		<Para tag="BSub">
			<Content>some data</Content>
		</Para>
	</ul>
	<Para tag="L3">
		<Content>some data</Content>
	</Para>
	<Para tag="L1">
		<Content>some data</Content>
	</Para>
	<Para tag="B_bold">
		<Content>some data</Content>
	</Para>
	<Para tag="B_bold">
		<Content>some data</Content>
	</Para>
</Book>
 
Old July 7th, 2011, 12:04 PM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

Use
Code:
<xsl:for-each-group select="*" group-adjacent="@tag = 'BSub'">
  <!-- here you can put the code you have in your posted for-each-group -->
</xsl:for-each-group>
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
The Following User Says Thank You to Martin Honnen For This Useful Post:
wokoman (July 8th, 2011)
 
Old July 8th, 2011, 05:23 AM
Registered User
 
Join Date: Apr 2011
Posts: 8
Thanks: 3
Thanked 0 Times in 0 Posts
Default Thanks ! (and some other question)

Thanks Martin, this does the trick indeed. I do have a small additional question linked to grouping. Does the group-adjacent (or grouping key in general) allow for an 'OR' type of selection ? In my original XML I have several parameters that need to be transformed to the same type, so what I currently do is the following : (simplified xslt)

Code:
<xsl:for-each-group select="current-group()" group-adjacent="@tag = 'BSubMak.bull'">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<ul class="std">
<xsl:apply-templates select="current-group()" mode="List"/>
</ul>
</xsl:when>

<xsl:otherwise>
<xsl:for-each-group select="current-group()" group-adjacent="@tag = 'BMak.bull'">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<ul class="std">
<xsl:apply-templates select="current-group()" mode="List"/>
</ul>
</xsl:when>

<xsl:otherwise>
<!-- next parameter based group and so on ... -->
Where I'd like to get it a bit simpler as I end up with a lot of nestings. Following obviously doesn't work but is shows what I'd like to get

Code:
<xsl:for-each-group select="current-group()" group-adjacent="@tag = 'BSubMak.bull' | @tag = 'BMak.bull'">
so is there any way to work with an or statement as a key or is nesting the only option ?

Thanks again for any advice on this !
 
Old July 8th, 2011, 08:15 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

The boolean "or" operator in XPath is named "or" and not "|", as "|" is the union operator on nodes. So doing
Code:
group-adjacent="@tag = 'BSubMak.bull' or @tag = 'BMak.bull'"
or maybe
Code:
group-adjacent="@tag = ('BSubMak.bull', 'BMak.bull')"
might do what you want.
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
The Following User Says Thank You to Martin Honnen For This Useful Post:
wokoman (July 8th, 2011)





Similar Threads
Thread Thread Starter Forum Replies Last Post
Help & advice needed on database display in *.csv format rachel tong BOOK: Beginning Visual C# 2010 0 February 5th, 2011 01:25 AM
Hello, New to ASP.net, Advice needed Top Hat ASP.NET 3.5 Basics 1 March 23rd, 2010 06:22 AM
Positioning layers? Advice needed. Perkele Dreamweaver (all versions) 1 February 19th, 2007 02:43 PM
advice needed..please see sarah lee ASP.NET 1.0 and 1.1 Basics 1 September 5th, 2006 10:48 AM
Advice Needed Dsypher ASP.NET 2.0 Basics 1 January 31st, 2006 02:09 PM





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