Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > XML > extract element names with XSLT

Reply
Thread Tools

extract element names with XSLT

 
 
Stefan Franke
Guest
Posts: n/a
 
      01-05-2005
Hi,
I've got the following simple XSLT stylesheet, that lists all the values of
the elements of any given XML file.

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlnssl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:for-each select="/">
<xsl:value-of select="current()"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

What I'm trying to find now is a way to extract the element name as well
(e.g. "TITLE" if the element is called <TITLE>).

Does anybody know how to do this?

Thanks,
Stefan


 
Reply With Quote
 
 
 
 
Joris Gillis
Guest
Posts: n/a
 
      01-05-2005
> <?xml version="1.0" encoding="ISO-8859-1"?>
> <xsl:stylesheet version="1.0"
> xmlnssl="http://www.w3.org/1999/XSL/Transform">
> <xsl:template match="/">
> <xsl:for-each select="/">

<xsl:value-of select="local-name()"/>
> <xsl:value-of select="current()"/>
> </xsl:for-each>
> </xsl:template>
> </xsl:stylesheet>



--
Joris Gillis (http://www.ticalc.org/cgi-bin/acct-v...i?userid=38041)
"Quot capita, tot sententiae" - Terentius , Phormio 454
 
Reply With Quote
 
 
 
 
Stefan Franke
Guest
Posts: n/a
 
      01-05-2005
Thanks, but I'm afraid that I was cheering too early. I noticed that
"current()" selects all the values and not only one (so the for-each isn't
necessary).

Is there a way to iterate through the element names and element values one
after the other (without knowing the structure of the XML file)?

Thanks,
Stefan


 
Reply With Quote
 
Joris Gillis
Guest
Posts: n/a
 
      01-05-2005
> Thanks, but I'm afraid that I was cheering too early. I noticed that
> "current()" selects all the values and not only one (so the for-each isn't
> necessary).
>
> Is there a way to iterate through the element names and element values one
> after the other (without knowing the structure of the XML file)?


Yes, but you have to realize that an element's value consist of the concatenation off all child text nodes up to any dept level.

Suppose you have this XML:
<root>
<title>hello</title>
<section>
<node>this is some <i>italic</i> text</node>
</section>
</root>


If you want this output:
root:hellothis is some italic text
title:hello
section:this is some italic text
node:this is some italic text
i:italic

Use:
<xsl:template match="/">
<xsl:for-each select="//*">
<xsl:value-of select="local-name()"/>:<xsl:value-of select="current()"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>

If you'd rather need this output:
root:
title:hello
section:
node:this is some text
i:italic

Use:
<xsl:template match="/">
<xsl:for-each select="//*">
<xsl:value-of select="local-name()"/>:<xsl:apply-templates select="current()/text()"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>


If you need yet another variant, just ask it.

regards,
--
Joris Gillis (http://www.ticalc.org/cgi-bin/acct-v...i?userid=38041)
"Quot capita, tot sententiae" - Terentius , Phormio 454
 
Reply With Quote
 
Stefan Franke
Guest
Posts: n/a
 
      01-08-2005
> If you'd rather need this output:
> root:
> title:hello
> section:
> node:this is some text
> i:italic
>
> Use:
> <xsl:template match="/">
> <xsl:for-each select="//*">
> <xsl:value-of select="local-name()"/>:<xsl:apply-templates
> select="current()/text()"/>
> <xsl:text>
> </xsl:text>
> </xsl:for-each>
> </xsl:template>



Thanks very much for this code. I just wondered if I was on the right path
with this code (acutally the second one) when I need an 'exact copy' of the
XML file. What I'm actually trying to do is to produce a stylesheet, that
just copies the XML file (I mustn't use xsl:copy and xsl:copy-of, though).

I cannot just put this code inside the for-each statement for sure:

<xsl:variable name="localname" value-of="local-name()" />
<xsl:variable name="text" value-of="current()/text()" />

<xsl:element name="%localname;">
<xsl:text>%text;</xsl:text>
</xsl:element>

Could you give me a hint on how to solve that please?

Thanks,
Stefan


 
Reply With Quote
 
Joris Gillis
Guest
Posts: n/a
 
      01-08-2005
Tempore 14:42:52, die Saturday 08 January 2005 AD, hinc in foro {comp.text.xml} scripsit Stefan Franke <(E-Mail Removed)>:

> What I'm actually trying to do is to produce a stylesheet, that
> just copies the XML file (I mustn't use xsl:copy and xsl:copy-of, though).


Why not use them?

> I cannot just put this code inside the for-each statement for sure:
>
> <xsl:variable name="localname" value-of="local-name()" />
> <xsl:variable name="text" value-of="current()/text()" />
>
> <xsl:element name="%localname;">
> <xsl:text>%text;</xsl:text>
> </xsl:element>
>


You might put this:
<xsl:variable name="localname" select="local-name()" />
<xsl:variable name="text" select="current()/text()" />

<xsl:element name="{$localname}">
<xsl:value-of select="text()"/>
</xsl:element>

or more simple:

<xsl:element name="{local-name()}">
<xsl:apply-templates select="current()/text()"/>
</xsl:element>

regards,
--
Joris Gillis (http://www.ticalc.org/cgi-bin/acct-v...i?userid=38041)
Vincit omnia simplicitas
Keep it simple
 
Reply With Quote
 
Stefan Franke
Guest
Posts: n/a
 
      01-08-2005
> <xsl:element name="{local-name()}">
> <xsl:apply-templates select="current()/text()"/>
> </xsl:element>


The problem with this approach is that an element is opened and right
afterwards closed again. So I cannot generate a tree structure with this
code. It's as if there should be some kind of recursive call or something
like that...

regards,
Stefan


 
Reply With Quote
 
Joris Gillis
Guest
Posts: n/a
 
      01-08-2005
Tempore 16:22:40, die Saturday 08 January 2005 AD, hinc in foro {comp.text.xml} scripsit Stefan Franke <(E-Mail Removed)>:

> The problem with this approach is that an element is opened and right
> afterwards closed again. So I cannot generate a tree structure with this
> code.


Yes you can, creating tree strucures is perfectly possible in XSLT.

The 'xsl:apply-templates' will help you achieve it. You should abandon the use of 'xsl:for-each' when you're dealing with recursion.

This code will make a pseudo copy of the input XML (only elements and text nodes are copied):

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlnssl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="node()"/>
</xsl:element>
</xsl:template>

</xsl:stylesheet>


regards,
--
Joris Gillis (http://www.ticalc.org/cgi-bin/acct-v...i?userid=38041)
Vincit omnia simplicitas
Keep it simple
 
Reply With Quote
 
Stefan Franke
Guest
Posts: n/a
 
      01-08-2005
> The 'xsl:apply-templates' will help you achieve it. You should abandon the
> use of 'xsl:for-each' when you're dealing with recursion.



Ah, I see now how that cannot works with 'for-each'. Where I would use
'for-each' though, is when I want to extract the attributes:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlnssl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="*">
<xsl:element name="{local-name()}">

<xsl:for-each select="current()/@*">
<xsl:variable name="i" select="string(current()/@*)" />
<xsl:attribute name="a">$i</xsl:attribute>
</xsl:for-each>

<xsl:apply-templates select="node()"/>
</xsl:element>
</xsl:template>

</xsl:stylesheet>

I've got two problems with this code. Firstly, I cannot get this variable $i
to show its value (I always get '$i' with Saxon 8.2) and secondly, how can I
retrieve the name of the attribute with an XPath query?

Thanks,
Stefan


 
Reply With Quote
 
Joris Gillis
Guest
Posts: n/a
 
      01-08-2005
> <xsl:for-each select="current()/@*">
> <xsl:variable name="i" select="string(current()/@*)" />
> <xsl:attribute name="a">$i</xsl:attribute>
> </xsl:for-each>
>
> I've got two problems with this code. Firstly, I cannot get this variable $i
> to show its value (I always get '$i' with Saxon 8.2)

If you want the value of something... use 'xsl:value-of' ...that does make sense

Use:
<xsl:variable name="i" select="string(.)" />
<xsl:attribute name="a"><xsl:value-of select="$i"/></xsl:attribute>
Or easier:
<xsl:attribute name="a"><xsl:value-of select="."/></xsl:attribute>

> and secondly, how can I
> retrieve the name of the attribute with an XPath query?

use local-name(): it works for attributes as well as elements.


So the whole code is this:
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:for-each select="current()/@*">
<xsl:attribute name="{local-name()}"><xsl:value-of select="."/></xsl:attribute>
</xsl:for-each>
<xsl:apply-templates select="node()"/>
</xsl:element>
</xsl:template>

but tell me, why not use 'xsl:copy-of' or 'xsl:copy'?

regards,
--
Joris Gillis (http://www.ticalc.org/cgi-bin/acct-v...i?userid=38041)
Vincit omnia simplicitas
Keep it simple
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
how to Update/insert an xml element's text----> (<element>text</element>) HANM XML 2 01-29-2008 03:31 PM
How do i extract vidios when winrar wont extract them??? help plzzzzzzzz smuttdog@sc.rr.com Computer Support 2 12-23-2007 07:03 AM
Generating new element names from old element names UpgradeMyBrain@gmail.com XML 2 10-20-2006 08:24 AM
Possible to traverse the children of an element without specifying child element names? Matt XML 2 10-12-2004 08:23 AM
Matching attribute names to element names in a different path Carl XML 0 04-01-2004 01:15 PM



Advertisments