[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: flatten a hierachy and change positions

Subject: Re: flatten a hierachy and change positions
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Thu, 25 Sep 2003 10:18:18 +0100
xsl flatten
Hi Andreas,

> I have to make some suppositions first, however...
>
> You have:
>>
>   <root>
>> <g1>
>> <u1><s></s></u1>
>   </g1>   <!-- I presume... -->
>> <g2>
>> <u2></u2>
>> </g2>
>   </root>
>
>>
> You need:
>>
>> <u1></u1>
>> <s></s>
>> <g1></g1>
>> <u2></u2>
>> <g2></g2>
>   <root></root>
>
> Correct? Needs some kind of a recursive template, I think.

You *could* also do it by iterating through all the elements in the
document, after collecting them with the path "//*":

  <xsl:for-each select="//*">
    <xsl:copy />
  </xsl:for-each>

This gives the output:

<root />
<g1 />
<u1 />
<s />
<g2 />
<u2 />

Now there's some reordering to do. I don't think that the order that
Elke originally asked for is derivable from the order of the elements
in the document, but the ordering that your recursive template gave
is: it's the order in which the end tags appear, which is the same as
the number of preceding elements + the number of descendant elements.
So you could order them with:

  <xsl:for-each select="//*">
    <xsl:sort select="count(preceding::* | descendant::*)"
              data-type="number" />
    <xsl:copy />
  </xsl:for-each>

Having said that, sorting on a count of preceding and descendant
elements is going to be pretty inefficient if you have a document of
any size, so a recursive approach similar to yours is likely to be
better. I'd do it with the single template:

<xsl:template match="*">
  <xsl:apply-templates select="*" />
  <xsl:copy />
</xsl:template>

Which says that to process an element, you process its children first
and then create a copy of the element itself.

> Needs some adjustments, as I received error messages complaining
> about 'Illegal values being used for attribute name' (Xalan-J
> 2.5.1).

The error occurs when you call the 'another' template:

> <xsl:template name="another">
>   <xsl:param name="parname" select="empty"/>
> 
>   <xsl:element name="{$parname}">
>     <xsl:value-of select="$parname"/>
>   </xsl:element>
> </xsl:template>

with an empty string as the value of the $parname parameter. If
$parname is an empty string then name="{$parname}" resolves to
name="", which means that you're not supplying a name for the element
that you want created. This is an error, but an XSLT processor can
recover from it by not creating the element.

The reason that $parname is an empty string is that in the 'one'
template, you're iterating over all the children of the $parnode
using:

>  <xsl:for-each select="$parnode/node()">
>    <xsl:call-template name="one">
>      <xsl:with-param name="parnode" select="."/>
>    </xsl:call-template>
>    <xsl:call-template name="another">
>      <xsl:with-param name="parname" select="name(.)"/>
>    </xsl:call-template>
>  </xsl:for-each>

Some of the children of $parnode are likely to be text nodes; text
nodes don't have names. If you only select the element children of the
$parnode instead, with $parnode/*, then you don't get the error.

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.