Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > XML > Newbie XSL Question: Comparing to preceding-sibling within for-each

Reply
Thread Tools

Newbie XSL Question: Comparing to preceding-sibling within for-each

 
 
Red
Guest
Posts: n/a
 
      05-09-2007
Hi,

Pretty new to XML, but I have adopted some reports through my job that
I need to work with. I've got some training lined up next month, but
until then I have a few modifications to existing XSL files that I
need to make pretty sharpish.

We have certain reports that contain grouping and sums in the output.
The existing XSL just reads out all rows to html tables. I would like
to make these easier to read by eliminating all duplicates within a
row. At the moment, I dont have the access to change the XML output,
just the XSL. I hope the following example explains it well enough.
Any questions, let me know.

Thanks,

Red.



== XML ===========================================

<?xml version="1.0"?>
<rs:data>
<z:row BRANCH='Birmingham' ACCOUNT_NO='1001001' STATUS='Open'
BALANCE='5380.04'/>
<z:row BRANCH='Birmingham' ACCOUNT_NO='1001002' STATUS='Open'
BALANCE='1281.12'/>
<z:row BRANCH='London' ACCOUNT_NO='1001003' STATUS='Closed'
BALANCE='1015.32'/>
<z:row BRANCH='London' ACCOUNT_NO='1001004' STATUS='Open'
BALANCE='9866.53'/>
<z:row BRANCH='London' ACCOUNT_NO='1001005' STATUS='Open'
BALANCE='1659.55'/>
<z:row BRANCH='Glasgow' ACCOUNT_NO='1001006' STATUS='Open'
BALANCE='6944.21'/>
</rs:data>



== Current XSL ====================================

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlnssl="http://www.w3.org/1999/XSL/
Transform">
<xsl:template match="/">
<table>
<xsl:for-each select="//z:row">
<tr>
<td><xsl:value-of select="@BRANCH"/></td>
<td><xsl:value-of select="@ACCOUNT_NO"/></td>
<td><xsl:value-of select="@STATUS"/></td>
<td><xsl:value-of select="@BALANCE"/></td>
<tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
<!--end-->



== Current Output =================================

Birmingham 1001001 Open 5380.04
Birmingham 1001002 Open 1281.12
London 1001003 Closed 1015.32
London 1001004 Open 9866.53
London 1001005 Open 1659.55
Glasgow 1001006 Open 6944.21


== Required output ================================

Birmingham 1001001 Open 5380.04
1001002 Open 1281.12
London 1001003 Closed 1015.32
1001004 Open 9866.53
1001005 Open 1659.55
Glasgow 1001006 Open 6944.21

 
Reply With Quote
 
 
 
 
Joe Kesselman
Guest
Posts: n/a
 
      05-09-2007
You might want to start by looking at the examples on Dave Pawson's XSLT
FAQ page
http://www.dpawson.co.uk/xsl/sect2/sect21.html

I haven't checked, but I'd be willing to bet that something in the
sorting or grouping category illustrates exactly this test.

(Though you've almost answered your own question: you want to use a
conditional based on the immediately preceeding sibling.)

General reminder: Any time you're thinking about using for-each, you
should seriously consider using apply-templates and a separate template
instead. That's usually a better solution.
 
Reply With Quote
 
 
 
 
Pavel Lepin
Guest
Posts: n/a
 
      05-09-2007
Red <(E-Mail Removed)> wrote in
<(E-Mail Removed) .com>:
> We have certain reports that contain grouping and sums in
> the output. The existing XSL just reads out all rows to
> html tables. I would like to make these easier to read by
> eliminating all duplicates within a row. At the moment, I
> dont have the access to change the XML output, just the
> XSL.
>
> <?xml version="1.0"?>
> <rs:data>


Namespace declarations seem to be missing.

> Birmingham 1001001 Open 5380.04
> 1001002 Open 1281.12
> London 1001003 Closed 1015.32
> 1001004 Open 9866.53
> 1001005 Open 1659.55
> Glasgow 1001006 Open 6944.21


Generalising a bit, it's a trivial grouping problem. The
following is a working example of how it's done:

<xsl:stylesheet version="1.0"
xmlnssl="http://www.w3.org/1999/XSL/Transform"
xmlns:rs="http://example.org/rs"
xmlns:z="http://example.org/z">
<xslutput method="html"/>
<xsl:key name="branch" match="z:row" use="@BRANCH"/>
<xsl:key name="branches" match="z:row"
use="count(.|key('branch',@BRANCH)[1])=1"/>
<xsl:template match="rs:data">
<data>
<xsl:apply-templates
select="key('branches',true())" mode="branch"/>
</data>
</xsl:template>
<xsl:template match="z:row" mode="branch">
<xsl:apply-templates select="key('branch',@BRANCH)"/>
</xsl:template>
<xsl:template
match="z:row[count(.|key('branch',@BRANCH)[1])=1]">
<row>
<cell><xsl:apply-templates select="@BRANCH"/></cell>
<xsl:call-template name="acct-stat-bal"/>
</row>
</xsl:template>
<xsl:template match="z:row">
<row>
<cell></cell>
<xsl:call-template name="acct-stat-bal"/>
</row>
</xsl:template>
<xsl:template name="acct-stat-bal">
<cell>
<xsl:apply-templates select="@ACCOUNT_NO"/>
</cell>
<cell>
<xsl:apply-templates select="@STATUS"/>
</cell>
<cell>
<xsl:apply-templates select="@BALANCE"/>
</cell>
</xsl:template>
</xsl:stylesheet>

It gets a bit hairier if you need to combine grouping and
sorting. On the other hand, if you can use an
XSLT2-compliant processor, everything suddenly becomes very
easy as long as overusing sequences does not lead to
performance issues.

<irony intensity="0.75">

Note that for-each is evil and employing it where unneeded
may darn you to heck. If that training next month doesn't
mention it, I advise accusing your mentors of being
blasphemous for-each-worshippers, then preaching the
virtues of template-based approach. Who knows, they might
not be beyond redemption yet.

</irony>

--
Pavel Lepin
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
xsl to group elements? [xsl newbie] Rob Smegma XML 1 09-26-2005 10:59 AM
XSL Question tp xsl:for-each and xsl:variable schaf@2wire.ch XML 1 05-27-2005 09:25 PM
XSL-1000: (Fatal Error) Error while parsing XSL file (org.apache.xerces.parsers.AbstractSAXParser$AttributesProxy) Kevin Flood Java 0 09-08-2004 02:11 PM
Question :Comparing 2 elements in xsl Ex-Em-El XML 0 08-05-2004 03:51 PM
Comparing strings from within strings Rick C Programming 3 10-21-2003 09:10 AM



Advertisments