Subject: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?
Subject: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>
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.
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: