XML Editor
Sign up for a WebBoard account Sign Up Keyword Search Search More Options... Options
Chat Rooms Chat Help Help News News Log in to WebBoard Log in Not Logged in
Show tree view Topic
Topic Page 1 2 3 4 5 6 7 8 9 Go to previous topicPrev TopicGo to next topicNext Topic
Postnext
mike ratzlaffSubject: Create an element with a variable from a for-each loop
Author: mike ratzlaff
Date: 01 Jul 2004 11:50 AM
Hi, I have an XML file, generated by Doxygen, to describe the classes and functions in my C .h library files. It looks something like this:
<doxygenindex ...>
<compound kind='class'><name>MyClass1</name>
<member><name>MyClass1</name></member>
<member><name>~MyClass1</name></member>
<member><name>MyFunction1</name></member>
<member><name>MyFunction2</name></member>
</compound>
<compound kind='class'><name>MyClass2</name>
<member><name>MyClass2</name></member>
<member><name>~MyClass2</name></member>
<member><name>MyFunction1</name></member>
<member><name>MyFunction2</name></member>
</compound>
</doxygenindex>

I have created an XSLT file:
<ProjectName xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xsl:version="1.0">
<xsl:for-each select="/doxygenindex/compound[attribute::kind='class']">
<Class><xsl:value-of select="name" />
<xsl:for-each select="member[attribute::kind='function']">
<Function><xsl:value-of select="name" /></Function>
</xsl:for-each>
</Class>
</xsl:for-each>
</ProjectName>

That spits this out:
<ProjectName>
<Class>MyClass1
<Function>MyClass1</Function>
<Function>~MyClass1</Function>
<Function>MyFunction1</Function>
<Function>MyFunction1</Function>
</Class>
<Class>MyClass1
<Function>MyClass1</Function>
<Function>~MyClass1</Function>
<Function>MyFunction1</Function>
<Function>MyFunction1</Function>
</Class>
</ProjectName>

But now I would like to know how to write an XSLT to spit this out:
<MyProject>
<MyClass1>
<MyClass1/>
<~MyClass1/>
<MyFunction1/>
<MyFunction2/>
</MyClass1>
<MyClass2>
<MyClass2/>
<~MyClass2/>
<MyFunction1/>
<MyFunction2/>
</MyClass2>
</MyProject>

I think I need to use the <xsl:element> instruction, but I can't figure out how at access the select variable for the name. {$select} gives me an error, and {@select} comes up empty. What should I do?

Postnext
Minollo I.Subject: Re: Create an element with a variable from a for-each loop
Author: Minollo I.
Date: 01 Jul 2004 12:34 PM
Something like this should work for you:

<xsl:template match="/">
<MyProject>
<xsl:apply-templates/>
</MyProject>
</xsl:template>

<xsl:template match="compound[@kind='class']">
<xsl:element name="{name}">
<xsl:apply-templates select="member"/>
</xsl:element>
</xsl:template>

<xsl:template match="member">
<xsl:element name="{name}"/>
</xsl:template>

Note that '~' is not a valid character to be used as part of an element
name; you will have to change it into something else, like this:

<xsl:template match="member">
<xsl:element name="translate(name,'~','D')"/>
</xsl:template>

Hope this helps,
Minollo

Postnext
mike ratzlaffSubject: Re: Create an element with a variable from a for-each loop
Author: mike ratzlaff
Date: 01 Jul 2004 01:27 PM
I ended up trying it a little differently, creating an intermediate variable:
<ProjectName xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xsl:version="1.0">
<xsl:for-each select="/doxygenindex/compound[attribute::kind='class']">
<xsl:variable name='classname'><xsl:value-of select="name" /></xsl:variable>
<xsl:element name='{$classname}'>
<xsl:for-each select="member[attribute::kind='function']">
<xsl:variable name='functionname'><xsl:value-of select="name" /></xsl:variable>
<xsl:element name="{translate($functionname,'~','d')}"/>
</xsl:for-each>
</xsl:element>
</xsl:for-each>
</ProjectName>

And you forgot to tell me that I needed to put the translate() function into {}'s, but I got it to go. :)
Thanks for your helpand the quick reply!

The next thing I'm trying to do is instead of translating the tilde to another letter, to replace it completely with a string, such as 'destruct'.
I'm using a choose instruction, but I can't get the comparison to work (concatenating a string (the tilde) to a variable):
<xsl:choose>
<xsl:when test="$functionname=$classname">
<xsl:element name="construct{$classname}"/>
</xsl:when>
<xsl:when test="$functionname='~'$classname">
<xsl:element name="destruct{$classname}"/>
</xsl:when>
<xsl:otherwise>
<xsl:element name="method{$functionname}"/>
</xsl:otherwise>
</xsl:choose>

Postnext
Minollo I.Subject: Re: Create an element with a variable from a for-each loop
Author: Minollo I.
Date: 01 Jul 2004 01:44 PM
>...
>And you forgot to tell me that I needed to put the translate() function
>into {}'s, but I got it to go. :)

Ops, sorry; my mental parsing didn't catch it...

>...
> <xsl:when test="$functionname='~'$classname">
> <xsl:element name="destruct{$classname}"/>
> </xsl:when>

Try this:

<xsl:when test="$functionname=concat('~',$classname)">
<xsl:element name="destruct{$classname}"/>
</xsl:when>

Minollo

Postnext
mike ratzlaffSubject: Re: Create an element with a variable from a for-each loop
Author: mike ratzlaff
Date: 01 Jul 2004 01:56 PM
>Ops, sorry; my mental parsing
>didn't catch it...

It's cool - it forces me to actually read and learn how this works, instead of just copy/pasting your code verbatim.

>Try this:
>
><xsl:when
>test="$functionname=concat('~'
>,$classname)">
><xsl:element
>name="destruct{$classname}"/&g
>t;
></xsl:when>

sweet! That works! Thanks again!

OK, one last thing:
I don't know if this is the nature of XSLT, or just my parser (4xslt command-line for Windows) but the output file doesn't respect my whitespace in the formatting file. Is there a parser option (couldn't find one) or a tag that will force indending (tabs or spaces) and EOLs into the output file?
Right now it's just dumping the entire output end-to-end on a single line, which makes it hard to human-read.

Posttop
Minollo I.Subject: Re: Create an element with a variable from a for-each loop
Author: Minollo I.
Date: 01 Jul 2004 03:10 PM

>...
>I don't know if this is the nature of XSLT, or just my parser (4xslt
>command-line for Windows) but the output file doesn't respect my
>whitespace in the formatting file. Is there a parser option (couldn't
>find one) or a tag that will force indending (tabs or spaces) and EOLs
>into the output file?
>Right now it's just dumping the entire output end-to-end on a single line,
>which makes it hard to human-read.

It is the nature of XSLT.
Adding this to your stylesheet (before defining any xsl:template element)
should help:

<xsl:output method="xml" indent="yes"/>

Minollo

 
Topic Page 1 2 3 4 5 6 7 8 9 Go to previous topicPrev TopicGo to next topicNext Topic
Download A Free Trial of Stylus Studio 6 XML Professional Edition Today! Powered by Stylus Studio, the world's leading XML IDE for XML, XSLT, XQuery, XML Schema, DTD, XPath, WSDL, XHTML, SQL/XML, and XML Mapping!  
go

Log In Options

Site Map | Privacy Policy | Terms of Use | Trademarks
Stylus Scoop XML Newsletter:
W3C Member
Stylus Studio® and DataDirect XQuery ™are from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2016 All Rights Reserved.