Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > XML > Combining XML elements with XSL

Reply
Thread Tools

Combining XML elements with XSL

 
 
mikea_59
Guest
Posts: n/a
 
      02-15-2005
I am having trouble combining similar elements. Elements can be
combined if they have the same name and the same attribute values. I
can handle single level elements but am having problems with
multi-level elments (level of element nesting is unbound). I cannot
rely on fixed element names in the translator code since the translator
will be general purpose, elements names are not fixed.

Example input

<test>
<A x="0">
<B>1</B>
</A>
<A x="0">
<C>2</C>
</A>
<A x="0">
<D x="0">
<E>3</E>
</D>
</A>
<A x="0">
<D x="0">
<E>3</E>
</D>
</A>
<A x="0">
<D x="1">
<E>5</E>
</D>
</A>
<A x="1">
<B>4</B>
</A>
</test>

example output:

<test>
<A x="0">
<B>1</B>
<C>2</C>
<D x="0">
<E>3</E>
</D>
<D x="1">
<E>5</E>
</D>
</A>
<A x="1">
<B>4</B>
</A>
</test>

Any help would be greatly appreciated - still an XSL newbie

 
Reply With Quote
 
 
 
 
Joris Gillis
Guest
Posts: n/a
 
      02-17-2005
On 15 Feb 2005 13:50:10 -0800, mikea_59 <(E-Mail Removed)> wrote:

> I am having trouble combining similar elements. Elements can be
> combined if they have the same name and the same attribute values. I
> can handle single level elements but am having problems with
> multi-level elments (level of element nesting is unbound). I cannot
> rely on fixed element names in the translator code since the translator
> will be general purpose, elements names are not fixed.

Hi,

I'm afraid you'll have to use an 'xx:node-set' extension function to solve
this (in XSLT1.0).

Here's one solution (tested with Saxon), gives correct output for your
input.


<xsl:stylesheet xmlnssl="http://www.w3.org/1999/XSL/Transform"
version="1.0" xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">

<xslutput method="xml" indent="yes"/>

<xsl:strip-space elements="*"/>
<xsl:key name="element" match="*" use="concat(local-name(),@*)"/>

<xsl:template match="*">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:variable name="set">
<xsl:copy-of select="key('element',concat(local-name(),@*))/*"/>
</xsl:variable>
<xsl:apply-templates select="text()"/>
<xsl:apply-templates
select="exsl:node-set($set)/*[generate-id()=generate-id(key('element',concat(local-name(),@*)))]"/>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>

regards,
Joris Gillis
--
Using Opera's revolutionary e-mail client: http://www.opera.com/m2/
 
Reply With Quote
 
 
 
 
mikea_59
Guest
Posts: n/a
 
      02-17-2005

That worked - thanks a lot! What a great NG.

So, is this strictly a 1.0 solution? Doesn't 2.0 eliminate the need
to use node-set() by enabling temporary templates? Is node-set() even
available in 2.0 - in Saxon? How would I change this for 2.0?

Sorry for all the ???

Thanks again
mikea

 
Reply With Quote
 
Joris Gillis
Guest
Posts: n/a
 
      02-17-2005
On 17 Feb 2005 11:56:09 -0800, mikea_59 <(E-Mail Removed)> wrote:

> So, is this strictly a 1.0 solution?

Everything that can be achieved in XSLT1.0 certainly can in XSLT2.0, isn't
that logic

> Doesn't 2.0 eliminate the need
> to use node-set() by enabling temporary templates?

Excerpt form the latest XSLT2.0 working draft:
"The result tree fragment data-type is eliminated. A variable-binding
element with content (and no as attribute) now constructs a temporary
tree, and the value of the variable is the root node of this tree (see 9.3
Values of Variables and Parameters). With an as attribute, a
variable-binding element may be used to construct an arbitrary sequence.
These features eliminate the need for the xx:node-set extension function
provided by many XSLT 1.0 implementations."

> available in 2.0 - in Saxon? How would I change this for 2.0?


I don't have experience with 2.0, but I guess writing '$set' in stead of
'exsl:node-set($set)' will do...


regards,
Joris Gillis
--
Using Opera's revolutionary e-mail client: http://www.opera.com/m2/
 
Reply With Quote
 
mikea_59
Guest
Posts: n/a
 
      02-17-2005

Joris Gillis wrote:
> On 17 Feb 2005 11:56:09 -0800, mikea_59 <(E-Mail Removed)> wrote:
>
> > So, is this strictly a 1.0 solution?

> Everything that can be achieved in XSLT1.0 certainly can in XSLT2.0,

isn't
> that logic


Yes, very logical, but when I set stylesheet to version=2.0 and
re-run the translation in Saxon, I get an error:

"A sequence of more than one item is not allowed as the first
argument of generate-id()"

I guess it's not related to node-set()

>
> > Doesn't 2.0 eliminate the need
> > to use node-set() by enabling temporary templates?

> Excerpt form the latest XSLT2.0 working draft:
> "The result tree fragment data-type is eliminated. A variable-binding


> element with content (and no as attribute) now constructs a temporary


> tree, and the value of the variable is the root node of this tree

(see 9.3
> Values of Variables and Parameters). With an as attribute, a
> variable-binding element may be used to construct an arbitrary

sequence.
> These features eliminate the need for the xx:node-set extension

function
> provided by many XSLT 1.0 implementations."
>
> > available in 2.0 - in Saxon? How would I change this for 2.0?

>
> I don't have experience with 2.0, but I guess writing '$set' in stead

of
> 'exsl:node-set($set)' will do...
>
>
> regards,
> Joris Gillis
> --
> Using Opera's revolutionary e-mail client: http://www.opera.com/m2/


 
Reply With Quote
 
Joris Gillis
Guest
Posts: n/a
 
      02-17-2005
On 17 Feb 2005 13:21:49 -0800, mikea_59 <(E-Mail Removed)> wrote:

> "A sequence of more than one item is not allowed as the first
> argument of generate-id()"


Really? Then they have changed the behaviour of generate-id().

Solution:
change
<xsl:apply-templates
select="exsl:node-set($set)/*[generate-id()=generate-id(key('element',concat(local-name(),@*)))]"/>
into
<xsl:apply-templates
select="exsl:node-set($set)/*[generate-id()=generate-id(key('element',concat(local-name(),@*))[1])]"/>

--
Using Opera's revolutionary e-mail client: http://www.opera.com/m2/
 
Reply With Quote
 
David Carlisle
Guest
Posts: n/a
 
      02-17-2005

> Really? Then they have changed the behaviour of generate-id().


it's a more or less pervasive change, as part of the stricter tying
introduced in 2 most instances of functions that expect a single node
complain if given more than one node rather than silently taking the
first in doc order.

David
 
Reply With Quote
 
mikea_59
Guest
Posts: n/a
 
      02-17-2005

It looks like that did the trick, thanks a lot. I'm still not sure I
follow the syntax of the select attribute, I guess I'll go back to my
Kay book...

Thanks again,
mikea

 
Reply With Quote
 
Joris Gillis
Guest
Posts: n/a
 
      02-17-2005
Tempore 23:15:45, die Thursday 17 February 2005 AD, hinc in foro {comp.text.xml} scripsit mikea_59 <(E-Mail Removed)>:

>
> It looks like that did the trick, thanks a lot. I'm still not sure I
> follow the syntax of the select attribute


you mean this line?

<xsl:apply-templates select="$set/*[generate-id()=generate-id(key('element',concat(local-
name(),@*))[1])]"/>

well, the trick is to let the xslt processor create a key lookup table based on the node-set in the variable in stead of a lookup table indexing all nodes in the input XML document.

The 'generate-id()' + 'key()' stuff is just basic Muenchian grouping technique...

--
Joris Gillis (http://www.ticalc.org/cgi-bin/acct-v...i?userid=38041)
"Φιλήκοον ειναι μαλλον η Ï*ιλόλαλον" - Κλεόβουλος
 
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
Combining Hash elements to produce single line output Paul Ruby 5 04-13-2007 10:06 PM
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
Re: XSLT - Combining elements based on their content Peter Flynn XML 0 04-11-2004 02:23 PM
XML/XSLT Combining queries into XML ? BaKMaN XML 0 01-30-2004 11:01 AM



Advertisments