Connecting Tech Pros Worldwide Forums | Help | Site Map

looping through names of nodes and sub nodes

k.a.bouton@reading.ac.uk
Guest
 
Posts: n/a
#1: Sep 20 '05
I am trying to transform my XML to produce just a tree of the unique
nodes and subnodes and am having no luck.

this is the sample xml

<MyRoot>
<contact>
<name>Jane Doe</name>
<country>USA</country>
</contact>
<magazines>
<magazine>
<magazine_name>Some Magazine</magazine_name>
<year>2004</year>
</magazine>
<magazine>
<magazine_name>Some Magazine</magazine_name>
<year>2004</year>
</magazine>
</magazines>
</MyRoot>

Desired Text Result from transformation
Group: MyRoot
Group:contact
name
country
End_Group:contact
Group:magazines
Group: magazine
magazine_name
year
End_Group:magazines
End_Group:MyRoot

I am getting lost in the looping of it as far as starting and ending
the group notation.

Pointers and suggestions welcome
K


Joris Gillis
Guest
 
Posts: n/a
#2: Sep 20 '05

re: looping through names of nodes and sub nodes


Hi,

Tempore 15:48:16, die Tuesday 20 September 2005 AD, hinc in foro {comp.text.xml} scripsit <k.a.bouton@reading.ac.uk>:
[color=blue]
> <MyRoot>
> <contact>
> <name>Jane Doe</name>
> <country>USA</country>
> </contact>
> <magazines>
> <magazine>
> <magazine_name>Some Magazine</magazine_name>
> <year>2004</year>
> </magazine>
> <magazine>
> <magazine_name>Some Magazine</magazine_name>
> <year>2004</year>
> </magazine>
> </magazines>
> </MyRoot>
>
> Desired Text Result from transformation
> Group: MyRoot
> Group:contact
> name
> country
> End_Group:contact
> Group:magazines
> Group: magazine
> magazine_name
> year
> End_Group:magazines
> End_Group:MyRoot[/color]

Try:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>

<xsl:key name="element" match="*" use="name()"/>

<xsl:template match="*">
<xsl:if test="generate-id()=generate-id(key('element',name())[1])">
<xsl:for-each select="ancestor::*">
<xsl:text> </xsl:text>
</xsl:for-each>
<xsl:if test="not(*)">
<xsl:value-of select="name()"/>
<xsl:text> </xsl:text>
</xsl:if>
<xsl:if test="*">
<xsl:text/>Group: <xsl:value-of select="name()"/>
<xsl:text> </xsl:text>
<xsl:apply-templates select="*"/>
<xsl:for-each select="ancestor::*">
<xsl:text> </xsl:text>
</xsl:for-each>
<xsl:text/>End_Group: <xsl:value-of select="name()"/>
<xsl:text> </xsl:text>
</xsl:if>
</xsl:if>
</xsl:template>

</xsl:stylesheet>

This might become rather tough when the real structure contains identically named nodes in another context.

regards,
--
Joris Gillis (http://users.telenet.be/root-jg/me.html)
Don't send spam. I don't like it and it is illegal.
bouton
Guest
 
Posts: n/a
#3: Sep 20 '05

re: looping through names of nodes and sub nodes


that seems to work prefect.Thanks. it was the generate_id where I got
lost. thanks again
K

bouton
Guest
 
Posts: n/a
#4: Sep 22 '05

re: looping through names of nodes and sub nodes


OK - now I'd like to get fancy...
Is there anyway, if there are nodes which are repeated to indicate it?
eg
if if node names has multiple name under it
<magazines>
<magazine>some mag</magazine>
<magazine>another mag</magazine>
</magazines>

to print out
+ Group: magazines
Thanks
K

Joris Gillis
Guest
 
Posts: n/a
#5: Sep 22 '05

re: looping through names of nodes and sub nodes


Hi,

Tempore 17:37:44, die Thursday 22 September 2005 AD, hinc in foro {comp.text.xml} scripsit bouton <k.a.bouton@reading.ac.uk>:
[color=blue]
> Is there anyway, if there are nodes which are repeated to indicate it?
> eg
> if if node names has multiple name under it
> <magazines>
> <magazine>some mag</magazine>
> <magazine>another mag</magazine>
> </magazines>[/color]

Try adding:
<xsl:if test="count(../*[name()=name(current())]) &gt; 1">+</xsl:if>

like in this stylesheet:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>

<xsl:key name="element" match="*" use="name()"/>

<xsl:template match="*">
<xsl:if test="generate-id()=generate-id(key('element',name())[1])">
<xsl:variable name="indent">
<xsl:for-each select="ancestor::*">
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="$indent"/>
<xsl:if test="count(../*[name()=name(current())]) &gt; 1">+</xsl:if>
<xsl:if test="not(*)">
<xsl:value-of select="name()"/>
<xsl:text> </xsl:text>
</xsl:if>
<xsl:if test="*">
<xsl:text/>Group: <xsl:value-of select="name()"/>
<xsl:text> </xsl:text>
<xsl:apply-templates select="*"/>
<xsl:value-of select="$indent"/>
<xsl:text/>End_Group: <xsl:value-of select="name()"/>
<xsl:text> </xsl:text>
</xsl:if>
</xsl:if>
</xsl:template>

</xsl:stylesheet>

regards,
--
Joris Gillis (http://users.telenet.be/root-jg/me.html)
«Error, keyboard not found— press F1 to continue» , BIOS
bouton
Guest
 
Posts: n/a
#6: Sep 22 '05

re: looping through names of nodes and sub nodes


perfect- thanks
K

Closed Thread


Similar .NET Framework bytes