XSLT: selecting the maximal from all counts(newbie)

R

R

Hello everybody.

I've got a problem with selecting the maximal value of few counts.
I want to count how many nodes are inside the <group> nodes and select
the maximal value.

Given XML:
<root id="123">
<group>
<field>qwq</field>
<field>lala</field>
</group>
<sample>tekst</sample>
<group>
<sample>qwq</sample>
<sample>lala</sample>
<sample>lala2</sample>
</group>
<field>sth else</field>
</root>

If I do sth like this:
<xsl:variable name="Elements" select="count(root/group/*)"/>
the variable's Elements value is 5 - aggregate 'count' of all nodes
inside all the groups.

how should I write my count statement to select ony the maximal value
of nodes in specific group?

thanks in advance
best regards R
 
E

Ed Beroset

R said:
Hello everybody.

I've got a problem with selecting the maximal value of few counts.
I want to count how many nodes are inside the <group> nodes and select
the maximal value.

Given XML:
<root id="123">
<group>
<field>qwq</field>
<field>lala</field>
</group>
<sample>tekst</sample>
<group>
<sample>qwq</sample>
<sample>lala</sample>
<sample>lala2</sample>
</group>
<field>sth else</field>
</root>

If I do sth like this:
<xsl:variable name="Elements" select="count(root/group/*)"/>
the variable's Elements value is 5 - aggregate 'count' of all nodes
inside all the groups.

how should I write my count statement to select ony the maximal value
of nodes in specific group?

Here's one way to do it:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"<xsl:eek:utput method="xml" indent="yes"/>

<xsl:template match="/">
<xsl:apply-templates select="root/group">
<xsl:sort select="count(./*)" order="descending" />
</xsl:apply-templates>
</xsl:template>

<xsl:template match="group">
<xsl:if test="position()=1">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:template>

</xsl:stylesheet>

With your input data (with the missing <?xml version=1.0"?> line
supplied), this XSLT produces:

<?xml version="1.0"?>
<group>
<sample>qwq</sample>
<sample>lala</sample>
<sample>lala2</sample>
</group>

Ed
 
R

R

well...
it is a small missunderstanding
I only needed the maximal count() of nodes inside all the 'group'
nodes, in my example the answer is 3.
That was all ;)

Your XSLT transfomed them into new XML but how can it be modified so
that I can have 'the answer' in e.g. variable: <xsl:variable
name="Elements" select="..." />

thanks in advance for further explanations(just a newbie - sorry)
best regards R
 
E

Ed Beroset

R said:
well...
it is a small missunderstanding
I only needed the maximal count() of nodes inside all the 'group'
nodes, in my example the answer is 3.
That was all ;)

Your XSLT transfomed them into new XML but how can it be modified so
that I can have 'the answer' in e.g. variable: <xsl:variable
name="Elements" select="..." />

thanks in advance for further explanations(just a newbie - sorry)

No problem. I'm sorry I misunderstood your question. Here's a
modification to the originally posted XSLT:

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"<xsl:eek:utput method="text" indent="yes"/>

<xsl:template match="/">
<xsl:apply-templates select="root/group">
<xsl:sort select="count(./*)" order="descending" />
</xsl:apply-templates>
</xsl:template>

<xsl:template match="group">
<xsl:if test="position()=1">
<xsl:value-of select="count(./*)"/>
</xsl:if>
</xsl:template>

</xsl:stylesheet>

This one produces just "3" as output. The changes are only that the
output method is now text instead of xml, and instead of <xsl:copy-of
select="."/> it's now <xsl:value-of select="count(./*)"/>

Ed
 
E

Ed Beroset

Ed said:
No problem. I'm sorry I misunderstood your question.

Rereading my answer, it could be that I've omitted a step which might
not be obvious to somebody new to XSLT; namely how to get a result
fragment into a variable. This is just a part of the XSLT, the rest is
as before:

<xsl:template match="/">
<xsl:variable name="Elements">
<xsl:apply-templates select="root/group">
<xsl:sort select="count(./*)" order="descending" />
</xsl:apply-templates>
</xsl:variable>
<xsl:text>The maximum depth is </xsl:text>
<xsl:value-of select="$Elements"/>
</xsl:template>

Ed
 
?

=?ISO-8859-1?Q?J=FCrgen_Kahrs?=

I understood that an XSLT is sought, but I could
not resist and write a solution in XMLgawk:

BEGIN { XMLMODE=1 }
XMLSTARTELEM == "group" { count = 0 ; next }
XMLSTARTELEM { count ++ }
XMLENDELEM == "group" && count > max { max = count }
END { print max }
Rereading my answer, it could be that I've omitted a step which might
not be obvious to somebody new to XSLT; namely how to get a result
fragment into a variable. This is just a part of the XSLT, the rest is
as before:

What I learn from this is that XSLT has some subtle edges.
<xsl:template match="/">
<xsl:variable name="Elements">
<xsl:apply-templates select="root/group">
<xsl:sort select="count(./*)" order="descending" />
</xsl:apply-templates>
</xsl:variable>
<xsl:text>The maximum depth is </xsl:text>
<xsl:value-of select="$Elements"/>
</xsl:template>

As you said, this is only part of your solution.
I am still unconvinced that it is a good idead
to have markup blocks in the source code of a
script language.
 
E

Ed Beroset

Jürgen Kahrs said:
Ed Beroset wrote:




As you said, this is only part of your solution.

The whole solution is here; the difference is only a few lines:

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"<xsl:eek:utput method="text" indent="yes"/>

<xsl:template match="/">
<xsl:variable name="Elements">
<xsl:apply-templates select="root/group">
<xsl:sort select="count(./*)" order="descending" />
</xsl:apply-templates>
</xsl:variable>
<xsl:text>The maxiumum depth is </xsl:text>
<xsl:value-of select="$Elements"/>
</xsl:template>

<xsl:template match="group">
<xsl:if test="position()=1">
<xsl:value-of select="count(./*)"/>
</xsl:if>
</xsl:template>

I am still unconvinced that it is a good idea
to have markup blocks in the source code of a
script language.

Maybe it would help if instead you thought of it as markup language in
the middle of markup blocks. XSLT is not a script language!

Ed
 
?

=?ISO-8859-1?Q?J=FCrgen_Kahrs?=

Ed said:
Maybe it would help if instead you thought of it as markup language in
the middle of markup blocks.

The problem for me is not so much the markup blocks and their nesting.
The problem for me is that the syntax is ugly, hard
to read and hard to debug.
XSLT is not a script language!

OK, XSLT is not a scripting language.
But this property of XSLT (*not* being
a scripting language) limits its range
of application even further.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,900
Latest member
Nell636132

Latest Threads

Top