By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,077 Members | 1,309 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,077 IT Pros & Developers. It's quick & easy.

Group and Sequence combination in xslt 2.0

P: n/a
Dear ALL,
I need some help on xsl:sequence. I'm using the Altova XSLT processor,
but I'm quite confident it is not an processor issue. It's probably my
bad knowledge of xslt 2.0.
I have probably put more that required in the test case, but it
basically covers my more complex code.

Here is the xml example source:
<?xml version="1.0" encoding="UTF-8"?>
<SeqTest>
<Item>otto_L</Item>
<Item>otto_L</Item>
<Item>otto_R</Item>
<Item>otto_L</Item>
<Item>karl_L</Item>
<Item>karl_R</Item>
<Item>nepumuk_L</Item>
</SeqTest>
My xslt
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" >
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/
>
<xsl:template match="/">
<DEBUG>
<xsl:for-each select="SeqTest/Item">
<ForeEach Pos="{position()}" Name="{.}"/>
</xsl:for-each>
<xsl:variable name="vSeq">
<xsl:for-each-group select="SeqTest/Item"
group-by="substring(.,1,string-length(.)-2)">
<xsl:variable name="vBaseName" s
elect="substring(.,1,string-length(.)-2)"/>
<xsl:if test="$vBaseName != 'nepumuk'">
<xsl:sequence select="$vBaseName"/>
</xsl:if>
</xsl:for-each-group>
</xsl:variable>
<Seq>
<xsl:for-each select="$vSeq">
<Item BaseName="{.}"/>
</xsl:for-each>
</Seq>
</DEBUG>
</xsl:template>
</xsl:stylesheet>
The UNEXPECTED result
<?xml version="1.0" encoding="UTF-8"?>
<DEBUG xmlns:xs="http://www.w3.org/2001/XMLSchema">
<ForeEach Pos="1" Name="otto_L"/>
<ForeEach Pos="2" Name="otto_L"/>
<ForeEach Pos="3" Name="otto_R"/>
<ForeEach Pos="4" Name="otto_L"/>
<ForeEach Pos="5" Name="karl_L"/>
<ForeEach Pos="6" Name="karl_R"/>
<ForeEach Pos="7" Name="nepumuk_L"/>
<Seq>
<Item BaseName="ottokarl"/>
</Seq>
</DEBUG>

As you can see the result element Item is only once there.
For me it meas that I have not build a sequnce of simple string values
over which I want to iterate.
(Please see attribute BaseName="otokarl" which indictes that too )

WHAT IS WRONG HERE ?

Any help is welcome

Rolf
Oct 9 '08 #1
Share this Question
Share on Google+
2 Replies


P: n/a
RolfK wrote:
<xsl:variable name="vSeq">
<xsl:for-each-group select="SeqTest/Item"
group-by="substring(.,1,string-length(.)-2)">
<xsl:variable name="vBaseName" s
elect="substring(.,1,string-length(.)-2)"/>
<xsl:if test="$vBaseName != 'nepumuk'">
<xsl:sequence select="$vBaseName"/>
</xsl:if>
</xsl:for-each-group>
</xsl:variable>
<Seq>
<xsl:for-each select="$vSeq">
<Item BaseName="{.}"/>
</xsl:for-each>
</Seq>
<Seq>
<Item BaseName="ottokarl"/>
</Seq>
</DEBUG>

As you can see the result element Item is only once there.
For me it meas that I have not build a sequnce of simple string values
over which I want to iterate.
The variable is currently a temporary tree. If you want a sequence of
strings then you need to use the 'as' attribute as follows:
<xsl:variable name="vSeq" as="xs:string*">
<xsl:for-each-group select="SeqTest/Item"
group-by="substring(.,1,string-length(.)-2)">
<xsl:variable name="vBaseName"
select="substring(.,1,string-length(.)-2)"/>
<xsl:if test="$vBaseName != 'nepumuk'">
<xsl:sequence select="$vBaseName"/>
</xsl:if>
</xsl:for-each-group>
</xsl:variable>
Not related to your problem is the following suggestion: instead of
computing the "base name" again and again you can simply call the
current-grouping-key() function e.g.

<xsl:for-each-group select="SeqTest/Item"
group-by="substring(.,1,string-length(.)-2)">
<xsl:variable name="vBaseName" select="current-grouping-key()"/>
<xsl:if test="$vBaseName != 'nepumuk'">
<xsl:sequence select="$vBaseName"/>
</xsl:if>
</xsl:for-each-group>

or you could get rid of the variable completely:

<xsl:for-each-group select="SeqTest/Item"
group-by="substring(.,1,string-length(.)-2)">
<xsl:if test="current-grouping-key() != 'nepumuk'">
<xsl:sequence select="current-grouping-key()"/>
</xsl:if>
</xsl:for-each-group>
--

Martin Honnen
http://JavaScript.FAQTs.com/
Oct 9 '08 #2

P: n/a
On 9 Okt., 12:55, Martin Honnen <mahotr...@yahoo.dewrote:
RolfK wrote:
* * * * * * * * * *<xsl:variable name="vSeq">
* * * * * * * * * * * * * *<xsl:for-each-group select="SeqTest/Item"
* * * * * * * * * * * * * * * * * *group-by="substring(.,1,string-length(.)-2)">
* * * * * * * * * * * * * * * * * *<xsl:variable name="vBaseName" s
* * * * * * * * * * * * * * * * * *elect="substring(.,1,string-length(.)-2)"/>
* * * * * * * * * * * * * * * * * *<xsl:if test="$vBaseName != 'nepumuk'">
* * * * * * * * * * * * * * * * * ** * * *<xsl:sequence select="$vBaseName"/>
* * * * * * * * * * * * * * * * * *</xsl:if>
* * * * * * * * * * * * * *</xsl:for-each-group>
* * * * * * * * * *</xsl:variable>
* * * * * * * * * *<Seq>
* * * * * * * * * * * * * *<xsl:for-each select="$vSeq">
* * * * * * * * * * * * * * * * * *<Item BaseName="{.}"/>
* * * * * * * * * * * * * *</xsl:for-each>
* * * * * * * * * *</Seq>
* *<Seq>
* * * * * *<Item BaseName="ottokarl"/>
* *</Seq>
</DEBUG>
As you can see the result element Item is only once there.
For me it meas that I have not build a sequnce of simple string values
over which I want to iterate.

The variable is currently a temporary tree. If you want a sequence of
strings then you need to use the 'as' attribute as follows:

* * * * * * * * * * * * <xsl:variable name="vSeq" as="xs:string*">
* * * * * * * * * * * * * * * * <xsl:for-each-group select="SeqTest/Item"
* * * * * * * * * * * * * * * * * * * * group-by="substring(.,1,string-length(.)-2)">
* * * * * * * * * * * * * * * * * * * * <xsl:variable name="vBaseName"
select="substring(.,1,string-length(.)-2)"/>
* * * * * * * * * * * * * * * * * * * * <xsl:if test="$vBaseName != 'nepumuk'">
* * * * * * * * * * * * * * * * * * * * * * * * <xsl:sequence select="$vBaseName"/>
* * * * * * * * * * * * * * * * * * * * </xsl:if>
* * * * * * * * * * * * * * * * </xsl:for-each-group>
* * * * * * * * * * * * </xsl:variable>

Not related to your problem is the following suggestion: instead of
computing the "base name" again and again you can simply call the
current-grouping-key() function e.g.

<xsl:for-each-group select="SeqTest/Item"
* * * * * * * * * * * * * * * * * * * * group-by="substring(.,1,string-length(.)-2)">
* * * * * * * * * * * * * * * * * * * * <xsl:variable name="vBaseName" select="current-grouping-key()"/>
* * * * * * * * * * * * * * * * * * * * <xsl:if test="$vBaseName != 'nepumuk'">
* * * * * * * * * * * * * * * * * * * * * * * * <xsl:sequence select="$vBaseName"/>
* * * * * * * * * * * * * * * * * * * * </xsl:if>
* * * * * * * * * * * * * * * * </xsl:for-each-group>

or you could get rid of the variable completely:

<xsl:for-each-group select="SeqTest/Item"
* * * * * * * * * * * * * * * * * * * * group-by="substring(.,1,string-length(.)-2)">
* * * * * * * * * * * * * * * * * * * * <xsl:if test="current-grouping-key() != 'nepumuk'">
* * * * * * * * * * * * * * * * * * * * * * * * <xsl:sequence select="current-grouping-key()"/>
* * * * * * * * * * * * * * * * * * * * </xsl:if>
* * * * * * * * * * * * * * * * </xsl:for-each-group>
--

* * * * Martin Honnen
* * * *http://JavaScript.FAQTs.com/- Zitierten Text ausblenden -

- Zitierten Text anzeigen -
Dear Martin,

Thanks a lot for this substancial and quick help !
I guess it will improve my code and even the key might inprove the
overall performance.

Rolf
Oct 9 '08 #3

This discussion thread is closed

Replies have been disabled for this discussion.