xsl-list
[Top] [All Lists]

Re: Grouping problem

2005-08-02 06:44:55
Sorry, my mistake - you need to construct a new document that is amenable to processing.

There are a number of ways of doing this, e.g. by creating a result-tree - not strictly standard, I know but it illustrates the method:

<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
   xmlns:ms="urn:schemas-microsoft-com:xslt">
....
<xsl:variable name="g">
<xsl:for-each select="*">
   <group name="{local-name()}" />
</xsl:for-each>
</xsl:variable>

<xsl:apply-templates select="ms:node-set($g)/group">
   <xsl:sort select="@name" />
</xsl:apply-templates>

<xsl:template match="group[(@name = preceding-sibling::group/@name)]" priority="+1" />
<xsl:template match="group">
   <group name="{(_at_)name}" />
</xsl:template>

.....

Alternatives:
1. use a multi-stage pipeline such as Apache Cocoon
2. nested translation in JSP
3. change the input format if you can


Michael Kay wrote:

These seem to be solutions to a different problem. The original XML has no
@name attributes.

Michael Kay
http://www.saxonica.com/


-----Original Message-----
From: Andrew Franz [mailto:afranz0(_at_)optushome(_dot_)com(_dot_)au] Sent: 01 August 2005 22:11
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: Re: [xsl] Grouping problem

Mukul Gandhi wrote:

Thanks Mike for the XSLT 2.0 way to solve the problem. But it was
surprising for me that the problem cannot be solved in XSLT 1.0 using
preceding-sibling axis.

Regards,
Mukul


Solution #1:
<xsl:template match="groups">
   <xsl:for-each select="group">
   <xsl:sort select="@name" />
   <xsl:if test="not(@name = preceding-sibling::group/@name)">
       <group name="{(_at_)name}" />
   </xsl:if>
   </xsl:for-each>
</xsl:template>

Solution #2:
<xsl:template match="groups">
   <xsl:for-each select="group">
   <xsl:sort select="@name" />
       <xsl:apply-templates select="." />
   </xsl:for-each>
</xsl:template>

<xsl:template match="group[(@name = preceding-sibling::group/@name)]" priority="+1" />
<xsl:template match="group">
       <group name="{(_at_)name}" />
</xsl:template>

Solution #3:
<xsl:key name="k2" match="group" use="@name" />

<xsl:template match="groups">
   <xsl:for-each select="group">
   <xsl:sort select="@name" />
       <xsl:apply-templates select="." />
   </xsl:for-each>
</xsl:template>

<xsl:template match="group" priority="-1" />
<xsl:template match="group[generate-id() = generate-id(key('k2', @name)[1])]"> group[<xsl:value-of select="@id" />]=<xsl:value-of select="@name" /><br/>
</xsl:template>



On 8/1/05, Michael Kay <mike(_at_)saxonica(_dot_)com> wrote:


When comparing two node-sets,

X = Y

means "some $x in X equals some $y in Y"

But when you do

name(X) = name(Y)

you are comparing two strings, not two node-sets. If X is a
node-set, then
name(X) is the name of the first node in X, and name(Y) is
the name of the
first node in Y. (In XSLT 2.0, with version="2.0", you
would get an error
trying to apply name() to a node-set containing more than
one node. The
change has been made to catch this common mistake.)

In 2.0 you can write

select="*[not(name() = preceding-sibling::*/name())]"

but of course it would be more efficient to use xsl:for-each-group.

Michael Kay
http://www.saxonica.com/


-----Original Message-----
From: Mukul Gandhi [mailto:gandhi(_dot_)mukul(_at_)gmail(_dot_)com]
Sent: 01 August 2005 07:57
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: [xsl] Grouping problem

I have the following XML file -
<?xml version="1.0" encoding="UTF-8"?>
<root>
 <a>1</a>
 <b>2</b>
 <d>3</d>
 <d>4</d>
 <b>5</b>
 <b>6</b>
 <c>7</c>
 <c>8</c>
 <a>9</a>
</root>

I am trying to do grouping operation with the following XSL -
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

    <xsl:output method="xml" version="1.0" encoding="UTF-8"
indent="yes"/>

    <xsl:template match="/root">
       <groups>
         <xsl:for-each select="*[not(name() =
name(preceding-sibling::*))]">
          <group name="{name()}" />
         </xsl:for-each>
       </groups>
    </xsl:template>

</xsl:stylesheet>

I am expecting output -
<groups>
 <group name="a" />
 <group name="b" />
 <group name="c" />
 <group name="d" />
</groups>

But I get output -
<?xml version="1.0" encoding="UTF-8"?>
<groups>
<group name="a"/>
<group name="b"/>
<group name="d"/>
<group name="d"/>
<group name="b"/>
<group name="b"/>
<group name="c"/>
<group name="c"/>
</groups>

Where is the problem?

This is tested with Xalan-J 2.6.0 and Saxon 8.4

Regards,
Mukul

--~--------------------------------------------------------
----------
XSL-List info and archive:
http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--


--~---------------------------------------------------------
---------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--





--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--





--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--




--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



<Prev in Thread] Current Thread [Next in Thread>