Re: [xsl] Book recommendation (was: xsl:copy - change attributes and tag name)

Subject: Re: [xsl] Book recommendation (was: xsl:copy - change attributes and tag name)
From: "Carsten Klein" <carstenklein@xxxxxxxx>
Date: Sun, 7 Apr 2002 16:43:37 +0200
Hi Matias,

I see that there is already a post by Joerg, who uses a key to
locate elements in the document.
This is much better, since keys increase overall performance,
especially when dealing with
large documents.

But, after investigating the stuff I wrote (yesterday?), I found out
that it does work at all =), blame
me, didn't test the code I wrote.

Okay, for my minds sake, here is the correct version:

Output by this version

<?xml version="1.0" encoding="UTF-8"?>
<tree>
    <tree IdIndice="1" text="Omint Analisis">
        <tree IdIndice="3" IdRef="1" text="OMINT: Precios"/>
        <tree IdIndice="4" IdRef="1" text="210 / Omint"/>
        <tree IdIndice="7" IdRef="1" text="310 / Omint">
            <tree IdIndice="8" IdRef="7" text="Cobertura"
IdDoc="1"/>
        </tree>
    </tree>
    <tree IdIndice="5" text="Swiss Medical Analisis">
        <tree IdIndice="6" IdRef="5" text="Swiss Precios"/>
    </tree>
</tree>

Stylesheet:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
version="1.0">
<xsl:template match="/">
<tree>
        <xsl:apply-templates select="@*"/>
        <xsl:for-each select="//TreeData/*[not(@IdRef)]">
            <xsl:call-template name="Indice"/>
        </xsl:for-each>
</tree>
</xsl:template>

<xsl:template name="Indice">
    <xsl:element name="tree">
        <xsl:apply-templates select="@*"/>
        <xsl:for-each
select="//TreeData/*[@IdRef=current()/@IdIndice]">
            <xsl:call-template name="Indice"/>
        </xsl:for-each>
    </xsl:element>
</xsl:template>

<xsl:template match="@*">
    <xsl:choose>
        <xsl:when test="local-name()='Nombre'">
            <xsl:attribute name="text"><xsl:value-of
select="@Nombre"/></xsl:attribute>
        </xsl:when>
        <xsl:otherwise>
            <xsl:copy/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>
</xsl:stylesheet>


Notice that you will need to xsl:for-each two times, to get all the
elements needed to build
the tree. template named "Indice" is a recursive template which will
call itself, if there are
any more Indice elements left, which are necessarily a child node
(in result tree) of the current Indice node.

Please note, that I moved the <xsl:attribute name="text"... to the
template dealing with all attribute nodes.
Testing local-name() (or name()) for "Nombre" (should be case
insensitive, though) and then creating
the new attribute node.

Hope this helps, surely it is another approach, but the absolute
references by
select="//TreeData/*..." surely can slow down things a lot,
especially when dealing with large documents.
As I said, the solution by Joerg is definitely the one to prefer.

Bye

Carsten


_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com


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


Current Thread