472,791 Members | 1,164 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,791 software developers and data experts.

XSLT reduce or count number of matching output elements


Hi,

Does anyone have a clue how to reduce the number of nodes using XSLT?
When outputing all nodes in order I could just use
<xsl:for-each select="name[position & $someNumber]">

But what if I, besides sorting and grouping, I also output
conditionally?

<xsl:for-each
select="//name[generate-id(.)=generate-id(key('names',city))]">
<strong><xsl:value-of select="city"/></strong>
<xsl:for-each select="key('names',city)">
<xsl:sort select="date" order="ascending"/>
<xsl:if test="translate(date, '-', '') &gt; translate($afterDate, '-',
'')">
<xsl:value-of select="name"/><br>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
With this transformation I can get the names of people who's birthday
is after a given date. The names are sorted by date and grouped by the
city.

What to do if I only want a total of $maximum result??

gratefull for anyhelp.

Marcel.
Jul 20 '05 #1
5 3496

"Marcel Akkerman" <m.********@NOSPAM.cs.utwente.nl> wrote in message
news:i9********************************@4ax.com...

Hi,

Does anyone have a clue how to reduce the number of nodes using XSLT?
Yes, you can reduce it completely by having:

<xsl:template match="/" />

When outputing all nodes in order I could just use
<xsl:for-each select="name[position & $someNumber]">
This is not well-formed xml -- what do you want to say?


But what if I, besides sorting and grouping, I also output
conditionally?

<xsl:for-each
select="//name[generate-id(.)=generate-id(key('names',city))]">
<strong><xsl:value-of select="city"/></strong>
<xsl:for-each select="key('names',city)">
<xsl:sort select="date" order="ascending"/>
<xsl:if test="translate(date, '-', '') &gt; translate($afterDate, '-',
'')">
<xsl:value-of select="name"/><br>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
With this transformation I can get the names of people who's birthday
is after a given date. The names are sorted by date and grouped by the
city.
No, what would be output as result depends completely on the source xnl
document, which you haven't shown to us.


What to do if I only want a total of $maximum result??


What does "a total of $maximum result" mean?

Please, alawys formulate well your problem if you really want to be
understood so that somebody could help.

A well-formulated problem includes the source xml document, the wanted
result of the transformation, (these two should completely describe the
problem, but be with minimal possible length and well indented so that they
are readable and understandable), a description of the desired properties of
the transformation.
Cheers,

Dimitre Novatchev [XML MVP],
FXSL developer, XML Insider,

http://fxsl.sourceforge.net/ -- the home of FXSL
Resume: http://fxsl.sf.net/DNovatchev/Resume/Res.html
Jul 20 '05 #2
On Sun, 22 Feb 2004 09:57:51 +0100, "Dimitre Novatchev [MVP XML]"
<dn********@yahoo.com> wrote:

"Marcel Akkerman" <m.********@NOSPAM.cs.utwente.nl> wrote in message
news:i9********************************@4ax.com.. .

Hi,

Does anyone have a clue how to reduce the number of nodes using XSLT?


Yes, you can reduce it completely by having:

<xsl:template match="/" />

When outputing all nodes in order I could just use
<xsl:for-each select="name[position & $someNumber]">


This is not well-formed xml -- what do you want to say?

sorry
it just a fragment and supposed to be:
<xsl:for0each select="name[position $lt; %someNumber]">

But what if I, besides sorting and grouping, I also output
conditionally?

<xsl:for-each
select="//name[generate-id(.)=generate-id(key('names',city))]">
<strong><xsl:value-of select="city"/></strong>
<xsl:for-each select="key('names',city)">
<xsl:sort select="date" order="ascending"/>
<xsl:if test="translate(date, '-', '') &gt; translate($afterDate, '-',
'')">
<xsl:value-of select="name"/><br>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
With this transformation I can get the names of people who's birthday
is after a given date. The names are sorted by date and grouped by the
city.


No, what would be output as result depends completely on the source xnl
document, which you haven't shown to us.


Fine, here's one with the irellevant data left out.

<people>
<person>
<name>Johnson</name>
<city>Boston</city>
<date>1965-02-05</date>
</person>
<person>
<name>Smit</name>
<city>Lutjebroek</city>
<date>1975-04-06</date>
</person>

<!-- etc. -->

</people>
Desired output (I get it this far)

Boston
Johnons
Peterson
Ackerman

Lutjebroek
Smit
Timmerman
de la Frost
Bos

Amsterdam
Lubbers
Veensma

This goes on as long as there are nodes in the original XML
What I want is to reduce the number names output to, let's say 5 in
total. This would look like:

Boston
Johnons
Peterson
Ackerman

Lutjebroek
Smit
Timmerman

An maybe reduce it to 2 per city. Which will look like:

Boston
Johnons
Peterson

Lutjebroek
Smit
Timmerman

Amsterdam
Lubbers
Veensma

-- hope you know what I'm after now :-D
-- thanks for any help.

Marcel.
Jul 20 '05 #3
On Sun, 22 Feb 2004 12:10:30 +0100, Marcel Akkerman
<m.********@NOSPAM.cs.utwente.nl> wrote:
On Sun, 22 Feb 2004 09:57:51 +0100, "Dimitre Novatchev [MVP XML]"
<dn********@yahoo.com> wrote:

"Marcel Akkerman" <m.********@NOSPAM.cs.utwente.nl> wrote in message
news:i9********************************@4ax.com. ..

Hi,

Does anyone have a clue how to reduce the number of nodes using XSLT?


Yes, you can reduce it completely by having:

<xsl:template match="/" />

When outputing all nodes in order I could just use
<xsl:for-each select="name[position & $someNumber]">


This is not well-formed xml -- what do you want to say?

sorry
it just a fragment and supposed to be:

<xsl:for-each select="name[position() &lt; $someNumber]">
Jul 20 '05 #4
> Fine, here's one with the irellevant data left out.

<people>
<person>
<name>Johnson</name>
<city>Boston</city>
<date>1965-02-05</date>
</person>
<person>
<name>Smit</name>
<city>Lutjebroek</city>
<date>1975-04-06</date>
</person>

<!-- etc. -->

</people>
Desired output (I get it this far)

Boston
Johnons
Peterson
Ackerman

Lutjebroek
Smit
Timmerman
de la Frost
Bos

Amsterdam
Lubbers
Veensma

This goes on as long as there are nodes in the original XML
What I want is to reduce the number names output to, let's say 5 in
total. This would look like:

Boston
Johnons
Peterson
Ackerman

Lutjebroek
Smit
Timmerman

An maybe reduce it to 2 per city. Which will look like:

Boston
Johnons
Peterson

Lutjebroek
Smit
Timmerman

Amsterdam
Lubbers
Veensma

This transformation:

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

<xsl:output method="text"/>

<xsl:key name="kdistCity" match="city" use="."/>
<xsl:key name="kNamesByCity" match="name" use="../city"/>

<xsl:template match="/">
<xsl:variable name="vCities" select=
"/*/*/city[generate-id()
=
generate-id(key('kdistCity', .)[1])
]"/>
<xsl:call-template name="dispNames">
<xsl:with-param name="pCities" select="$vCities"/>
<xsl:with-param name="pBornAfter" select="19650201"/>
<xsl:with-param name="pMaxNames" select="6"/>
<xsl:with-param name="pMaxNamesPerCity" select="2"/>
</xsl:call-template>
</xsl:template>

<xsl:template name="dispNames">
<xsl:param name="pCities" select="/.."/>
<xsl:param name="pBornAfter" select="0"/>
<xsl:param name="pMaxNames" select="1000"/>
<xsl:param name="pMaxNamesPerCity" select="100"/>
<xsl:param name="ptotalDisplayed" select="0"/>

<xsl:variable name="vmore2Display"
select="$pMaxNames - $ptotalDisplayed"/>

<xsl:variable name="vthisCity" select="$pCities[1]"/>

<xsl:variable name="vnamesInThisCity" select=
"key('kNamesByCity', $vthisCity)
[translate(../date, '-', '')

$pBornAfter
]"/>
<xsl:variable name="vcntNamesInCity"
select="count($vnamesInThisCity)"/>

<xsl:if test="$vmore2Display > 0 and $pCities">
<xsl:variable name="vdispLimit" select=
"$pMaxNamesPerCity * ($vmore2Display > $pMaxNamesPerCity)
+
$vmore2Display * (not($vmore2Display > $pMaxNamesPerCity))
"/>

<xsl:value-of select="concat('&#xA;&#xA;', $vthisCity)"/>

<xsl:for-each select="$vnamesInThisCity">
<xsl:sort select="translate(../date, '-', '')"/>

<xsl:if test="position() &lt;= $vdispLimit">
<xsl:value-of select="concat('&#xA; ', .)"/>
</xsl:if>
</xsl:for-each>

<xsl:call-template name="dispNames">
<xsl:with-param name="pCities" select="$pCities[position() > 1]"/>
<xsl:with-param name="pBornAfter" select="$pBornAfter"/>
<xsl:with-param name="pMaxNames" select="$pMaxNames"/>
<xsl:with-param name="pMaxNamesPerCity" select="$pMaxNamesPerCity"/>
<xsl:with-param name="ptotalDisplayed" select=
"$ptotalDisplayed
+ $vdispLimit * ($vcntNamesInCity > $vdispLimit )
+ $vcntNamesInCity *(not($vcntNamesInCity > $vdispLimit))"/>

</xsl:call-template>

</xsl:if>

</xsl:template>
</xsl:stylesheet>

when applied on this source.xml:

<people>
<person>
<name>Johnson</name>
<city>Boston</city>
<date>1965-02-05</date>
</person>
<person>
<name>Smit</name>
<city>Lutjebroek</city>
<date>1975-04-06</date>
</person>
<person>
<name>Peterson</name>
<city>Boston</city>
<date>1965-02-05</date>
</person>
<person>
<name>Ackerman</name>
<city>Boston</city>
<date>1965-02-05</date>
</person>
<person>
<name>Timmerman</name>
<city>Lutjebroek</city>
<date>1975-04-06</date>
</person>
<person>
<name>de la Frost</name>
<city>Lutjebroek</city>
<date>1975-04-06</date>
</person>
<person>
<name>Bos</name>
<city>Lutjebroek</city>
<date>1975-04-06</date>
</person>
<person>
<name>Lubbers</name>
<city>Amsterdam</city>
<date>1975-04-06</date>
</person>
<person>
<name>Veensma</name>
<city>Amsterdam</city>
<date>1975-04-06</date>
</person>

<!-- etc. -->

</people>

produces the wanted result:

Boston
Johnson
Peterson

Lutjebroek
Smit
Timmerman

Amsterdam
Lubbers
Veensma

It has a total limit of 6 names and a limit of maximum 2 names per city.
Hope this helped.

Cheers,

Dimitre Novatchev [XML MVP],
FXSL developer, XML Insider,

http://fxsl.sourceforge.net/ -- the home of FXSL
Resume: http://fxsl.sf.net/DNovatchev/Resume/Res.html
Jul 20 '05 #5

It has a total limit of 6 names and a limit of maximum 2 names per city.
Hope this helped.


It sure does. Thanksalot!

Marcel
Jul 20 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: rush | last post by:
I have a DTD that defines new elements "mytextfield" and "mysn", and does it as an extension to XHTML. The idea is that my XML markup is actually valid XHTML according to my DTD. This all works...
4
by: Chris Kettenbach | last post by:
Hi Peter, I get error when processing the stylesheet. It errors here. <xsl:for-each select="registration)=1]"> specifically: Expression does not return a DOM node. registration)=1]<--
4
by: gualtmacchi | last post by:
I'm processing an XML input file getting a plain text file where from M nodes I got N output lines... It's not relevant but the input file is a recordset coming from a database and the output is...
4
by: Adrian von Bidder | last post by:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Yo! Mostly as a finger-exercise (and because I'm annoyed again and again how bad the existing solutions are), I'm hacking up a web-based forum...
0
by: DAnne | last post by:
Hi, I'm very new to xslt and this is my first time posting to a Forum so please forgive me if I transgress any protocols. I have to do a tally report. This report is divided up into sections....
4
by: J | last post by:
I've spent most of the day on this, and I just can't seem to find a solution, please help me! :) I'm recieving XML that I can't modify that looks like: <?xml version="1.0"?> <Doc> <Page>...
2
by: manishj | last post by:
Hello! I m trying to transform a XML file into new XML file . Description: Each unique value from the <name> elements in the input record are to be uniqued, alphabetized and stored with a...
2
jkmyoung
by: jkmyoung | last post by:
Here's a short list of useful xslt general tricks that aren't taught at w3schools. Attribute Value Template Official W3C explanation and example This is when you want to put dynamic values...
3
by: z1 | last post by:
hi- i am fooling around with soap and weather templates. for some reason either this if or select is failing. i am very new to xml and found this code at another site. i can show you the xml...
0
by: erikbower65 | last post by:
Using CodiumAI's pr-agent is simple and powerful. Follow these steps: 1. Install CodiumAI CLI: Ensure Node.js is installed, then run 'npm install -g codiumai' in the terminal. 2. Connect to...
0
linyimin
by: linyimin | last post by:
Spring Startup Analyzer generates an interactive Spring application startup report that lets you understand what contributes to the application startup time and helps to optimize it. Support for...
0
by: erikbower65 | last post by:
Here's a concise step-by-step guide for manually installing IntelliJ IDEA: 1. Download: Visit the official JetBrains website and download the IntelliJ IDEA Community or Ultimate edition based on...
14
DJRhino1175
by: DJRhino1175 | last post by:
When I run this code I get an error, its Run-time error# 424 Object required...This is my first attempt at doing something like this. I test the entire code and it worked until I added this - If...
5
by: DJRhino | last post by:
Private Sub CboDrawingID_BeforeUpdate(Cancel As Integer) If = 310029923 Or 310030138 Or 310030152 Or 310030346 Or 310030348 Or _ 310030356 Or 310030359 Or 310030362 Or...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
0
by: lllomh | last post by:
How does React native implement an English player?
0
by: Mushico | last post by:
How to calculate date of retirement from date of birth
2
by: DJRhino | last post by:
Was curious if anyone else was having this same issue or not.... I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.