Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > BOOK: XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition ISBN: 978-0-470-19274-0
|
BOOK: XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition ISBN: 978-0-470-19274-0
This is the forum to discuss the Wrox book XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition by Michael Kay; ISBN: 9780470192740
Welcome to the p2p.wrox.com Forums.

You are currently viewing the BOOK: XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition ISBN: 978-0-470-19274-0 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 October 21st, 2010, 03:44 PM
Registered User
 
Join Date: Oct 2010
Posts: 7
Thanks: 0
Thanked 0 Times in 0 Posts
Default select the group of rows based on the three XML fields and with conditions.

I would like to group based on fields of row element (combination of StackNumber,BlockNumber and LocationCode) and select only higher BookVersion (BookVersion) based rows in particular group(combination of StackNumber,BlockNumber and LocationCode) and also to select the rows of DeliveryMode with the value as TRANSIT.

Here is the input document

<?xml version="1.0"?>
<?xml version="1.0"?>
<Output>
<row>
<StackNumber>19</StackNumber>
<BlockNumber>61001</BlockNumber>
<DeliveryMode>TRANSIT</DeliveryMode>
<LocationCode>MON</LocationCode>
<BookVersion>03</BookVersion>
<StoreNumber>1010</StoreNumber>

</row>
<row>
<StackNumber>20</StackNumber>
<BlockNumber>61001</BlockNumber>
<DeliveryMode>TRANSIT</DeliveryMode>
<LocationCode>MON</LocationCode>
<BookVersion>01</BookVersion>
<StoreNumber>1011</StoreNumber>
</row>
<row>
<StackNumber>20</StackNumber>
<BlockNumber>61001</BlockNumber>
<DeliveryMode>TRANSIT</DeliveryMode>
<LocationCode>MON</LocationCode>
<BookVersion>02</BookVersion>
<StoreNumber>1013</StoreNumber>
</row>
<row>
<StackNumber>21</StackNumber>
<BlockNumber>61001</BlockNumber>
<DeliveryMode>RECVD</DeliveryMode>
<LocationCode>MON</LocationCode>
<BookVersion>03</BookVersion>
<StoreNumber>1022</StoreNumber>
</row>
<row>
<StackNumber>21</StackNumber>
<BlockNumber>61001</BlockNumber>
<DeliveryMode>TRANSIT</DeliveryMode>
<LocationCode>MON</LocationCode>
<BookVersion>03</BookVersion>
<StoreNumber>1022</StoreNumber>
</row>
<row>
<StackNumber>22</StackNumber>
<BlockNumber>15098</BlockNumber>
<DeliveryMode>TRANSIT</DeliveryMode>
<LocationCode>MON</LocationCode>
<BookVersion>01</BookVersion>
<StoreNumber>1010</StoreNumber>
</row>
<row>
<StackNumber>22</StackNumber>
<BlockNumber>22456</BlockNumber>
<DeliveryMode>TRANSIT</DeliveryMode>
<LocationCode>MON</LocationCode>
<BookVersion>02</BookVersion>
<StoreNumber>1011</StoreNumber>
</row>
<row>
<StackNumber>22</StackNumber>
<BlockNumber>22456</BlockNumber>
<DeliveryMode>TRANSIT</DeliveryMode>
<LocationCode>MON</LocationCode>
<BookVersion>03</BookVersion>
<StoreNumber>1012</StoreNumber>
</row>
<row>
<StackNumber>22</StackNumber>
<BlockNumber>22456</BlockNumber>
<DeliveryMode>RECVD</DeliveryMode>
<LocationCode>MON</LocationCode>
<BookVersion>02</BookVersion>
<StoreNumber>1021</StoreNumber>
</row>
</Output>

XSL (using saxon 9 parser) that I wrote:



<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" indent="yes"/>

<xsl:key name="transitGroup" match="row" use="concat(StackNumber,BlockNumber,LocationCode)"/>

<xsl:template match="/">
<Output>
<xsl:for-each select="//row[generate-id(.) = generate-id(key('transitGroup',concat(StackNumber,BlockNumb er,LocationCode))[1])]">
<xsl:variable name="BookVersion" select="key('transitGroup',concat(StackNumber,Bloc kNumber,LocationCode))/BookVersion"/>
<xsl:if test="DeliveryMode = 'TRANSIT'">
<row>
<StackNumber>
<xsl:value-of select="StackNumber"/>
</StackNumber>
<BlockNumber>
<xsl:value-of select="BlockNumber"/>
</BlockNumber>
<LocationCode>
<xsl:value-of select="LocationCode"/>
</LocationCode>
<StoreNumber>
<xsl:value-of select="StoreNumber"/>
</StoreNumber>

<xsl:for-each select="$BookVersion">

<xsl:sort select="." data-type="number" order="descending"/>

<xsl:if test="position()=1">
<BookVersion>
<xsl:value-of select="."/>
</BookVersion>
</xsl:if>
</xsl:for-each>
</row>
</xsl:if>
</xsl:for-each>
</Output>
</xsl:template>
</xsl:stylesheet>



I wrote one but can't figure out to select correct store number based on greater value based element 'BookVersion' in each group.


example group must be this .

<row>
<StackNumber>20</StackNumber>
<BlockNumber>61001</BlockNumber>
<LocationCode>MON</LocationCode>
<StoreNumber>1013</StoreNumber>
<BookVersion>02</BookVersion>
</row>

I'm getting wrong store number here for a particular selected group. I'm struck to proceed further here, I will appreciate if some body can lead me the way to write correct it in this XSL.
 
Old October 22nd, 2010, 09:06 AM
Registered User
 
Join Date: Oct 2010
Posts: 7
Thanks: 0
Thanked 0 Times in 0 Posts
Default Solutions

XSL V 1.0 based solution:

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" encoding="utf-8" />
<xsl:key name="transitGroup" match="row[DeliveryMode='TRANSIT']" use="concat(StackNumber,BlockNumber,LocationCode)"/>

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

<xsl:template match="Output">
<Output>
<xsl:apply-templates select="row[DeliveryMode='TRANSIT']" mode="special"/>
</Output>
</xsl:template>

<xsl:template match="row[DeliveryMode='TRANSIT']" mode="special">
<xsl:if test="generate-id(.)=generate-id(key('transitGroup', concat(StackNumber,BlockNumber,LocationCode))[1])">
<xsl:for-each select="key('transitGroup', concat(StackNumber,BlockNumber,LocationCode))">
<xsl:sort select="BookVersion" data-type="number" order="descending" />
<xsl:choose>
<xsl:when test="position() = 1">
<xsl:call-template name="display" />
</xsl:when>
<xsl:otherwise>
<!-- do nothing -->
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:if>
</xsl:template>

<xsl:template name="display">
<row>
<StackNumber>
<xsl:value-of select="StackNumber"/>
</StackNumber>
<BlockNumber>
<xsl:value-of select="BlockNumber"/>
</BlockNumber>
<LocationCode>
<xsl:value-of select="LocationCode"/>
</LocationCode>
<StoreNumber>
<xsl:value-of select="StoreNumber"/>
</StoreNumber>
<BookVersion>
<xsl:value-of select="BookVersion" />
</BookVersion>
</row>
</xsl:template>

</xsl:stylesheet>

2) Version 2.0 Based solution:

<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xsd"
version="2.0">

<xsl:output indent="yes"/>

<xsl:template match="/">
<Output>
<xsl:for-each-group select="*/row[DeliveryMode='TRANSIT']"
group-by="concat(StackNumber,'&#xd;',
BlockNumber,'&#xd;',LocationCode)">
<xsl:for-each select="current-group()
[xsd:decimal(BookVersion)=
max(current-group()/BookVersion/xsd:decimal(.))]
[1]">
<row>
<xsl:copy-of select="* except DeliveryMode"/>
</row>
</xsl:for-each>
</xsl:for-each-group>
</Output>
</xsl:template>

</xsl:stylesheet>





Similar Threads
Thread Thread Starter Forum Replies Last Post
Count rows which meet three conditions ??? Aad Excel VBA 4 February 26th, 2009 10:02 AM
selection based on conditions rajesh_css XSLT 3 October 2nd, 2008 08:06 PM
Default Rows Based Upon Number of XML Attributes. Mr.T Infopath 0 November 5th, 2007 07:29 PM
select rows based on a criteria and paste ashu_gupta75 Excel VBA 2 July 30th, 2004 01:32 AM
Multiple db fields each with different conditions? sfinc Crystal Reports 1 February 27th, 2004 09:46 PM





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