Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Westi on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

xslt to restructure xml 1

Status
Not open for further replies.

sergivs

Programmer
May 18, 2007
6
US
Hi,

I need to write am xslt stylesheet that would convert a document structure like

<foo a="x">
...
</foo>

to

<bar b="x">
<foo>
...
</foo>
</bar>

Could someone help me with this or point me somewhere where I could find a relevant example?

Many thanks in advance.
 
This is how (with some detailed considerations, otherwise can even be simplified.)
[tt]
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="<xsl:eek:utput method="xml" version="1.0" encoding="utf-8" indent="yes" />
<xsl:template match="/">
<xsl:apply-templates select="*" />
</xsl:template>
<xsl:template match="foo">
<bar>
<xsl:apply-templates select="node()|text()|@*" />
</bar>
</xsl:template>
<xsl:template match="foo/@*[name() != 'a']">
<xsl:copy-of select="." />
</xsl:template>
<xsl:template match="foo/@*[name() = 'a']">
<xsl:attribute name="b">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:template>
<xsl:template match="node()|text()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|text()|@*" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
[/tt]
 
Amendment - Further notes

Overlooked that you want to keep the "foo" tag all the same, only to move its attribute "a" up to bar. A couple of changes would be needed to supplement the above. Here is a re-take.
[tt]
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="<xsl:eek:utput method="xml" version="1.0" encoding="utf-8" indent="yes" />
<xsl:template match="/">
<xsl:apply-templates select="*" />
</xsl:template>
<xsl:template match="foo">
<bar>
[blue]<xsl:apply-templates select="@a" />
<xsl:copy>[/blue]
<xsl:apply-templates select="node()|text()|@*[blue][name() != 'a'][/blue]" />
[blue]</xsl:copy>[/blue]
</bar>
</xsl:template>
<xsl:template match="foo/@*[name() != 'a']">
<xsl:copy-of select="." />
</xsl:template>
<xsl:template match="foo/@*[name() = 'a']">
<xsl:attribute name="b">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:template>
<xsl:template match="node()|text()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|text()|@*" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
[/tt]
 
tsuji, thanks once again, it works great.

the formatting is a little weird:

<bar b="x">
<foo>
....
</foo>
</bar>

Do you know how I could fix that?
 
By the way, how could I just rename a certain attribute in a specific node? In all nodes?

e.g.

<foobar c="x"/>
<barfoo c="x"/>

would become

<foobar d="x"/>
<barfoo d="x"/>

Sorry about all the stupid questions...
 
[1]
>the formatting is a little weird:
><bar b="x">
><foo>
You posted the question with that requirement, and now you say it is weird? How can I know?

[2]> how could I just rename a certain attribute in a specific node? In all nodes?
Like this.
[tt]
<xsl:template match="foobar/@c|barfoo/@c">
<xsl:attribute name="d">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:template>
[/tt]
[2.1] For all @c, just replace the tmeplate match by match="@c"
[tt] <xsl:template match="@c">[/tt]

[3] You can make up thousands and thousands of variations. Just do not use recipe-appraoch, no. I recognize there is a genuine difficulty to get started thinking xslt-way that's why I may show how. With one or two concrete demos, I would expect people should feel the proper way to think xslt and ready to look for public tutorial to learn the detail.
 
>the formatting is a little weird:
><bar b="x">
><foo>
You posted the question with that requirement, and now you say it is weird? How can I know?

The structure is exactly what I needed, thanks again. I mean the indentation is weird. I can see it in Firefox but not in IE. Maybe it's spaces vs tabs, I don't know. In any case, if you can't see what I mean in your browser, <bar> and </foo> are indented further to the right than <foo> and </bar>. It's not very important, but if you know how to fix it, please share.

I recognize there is a genuine difficulty to get started thinking xslt-way that's why I may show how. With one or two concrete demos, I would expect people should feel the proper way to think xslt and ready to look for public tutorial to learn the detail.

I agree completely, although it may seem like I'm looking for recipes.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top