.Re: how to copy XML and change attributes?

  • Thread starter Dimitre Novatchev
  • Start date
D

Dimitre Novatchev

I'm trying to copy a node and all its descendants and also change all the id
attributes.

<book>
<chapter id="c1">
<verse id="v1">Hello World</verse>
<verse id="v2">Goodbye World</verse>
</chapter>
<biblio id="b1">
<ref>reference one</ref>
</biblio>
</book>

I've been working on this little sample and can't get anywhere. I'd like to
be able to copy the chapter and make it output this:

<chapter id="c1-1">
<verse id="v1-1">Hello World</verse>
<verse id="v2-1">Goodbye World</verse>
</chapter>

This is something very fundamental in XSLT.

Use the identity transform and override it for "id" attributes.

The solution looks like this:

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

<xsl:eek:utput omit-xml-declaration="yes"/>

<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>

<xsl:template match="@id">
<xsl:attribute name="id">
<xsl:value-of select="concat(., '-1')"/>
</xsl:attribute>
</xsl:template>

<xsl:template match="/">
<xsl:apply-templates select="/*/chapter"/>
</xsl:template>
</xsl:stylesheet>

When this transformation is applied on your source.xml:

<book>
<chapter id="c1">
<verse id="v1">Hello World</verse>
<verse id="v2">Goodbye World</verse>
</chapter>
<biblio id="b1">
<ref>reference one</ref>
</biblio>
</book>

the wanted result is produced:

<chapter id="c1-1">
<verse id="v1-1">Hello World</verse>
<verse id="v2-1">Goodbye World</verse>
</chapter>


=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL
 
T

ted

Thanks Dimitre. Works like a charm.

Dimitre Novatchev said:
This is something very fundamental in XSLT.

Use the identity transform and override it for "id" attributes.

The solution looks like this:

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

<xsl:eek:utput omit-xml-declaration="yes"/>

<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>

<xsl:template match="@id">
<xsl:attribute name="id">
<xsl:value-of select="concat(., '-1')"/>
</xsl:attribute>
</xsl:template>

<xsl:template match="/">
<xsl:apply-templates select="/*/chapter"/>
</xsl:template>
</xsl:stylesheet>

When this transformation is applied on your source.xml:

<book>
<chapter id="c1">
<verse id="v1">Hello World</verse>
<verse id="v2">Goodbye World</verse>
</chapter>
<biblio id="b1">
<ref>reference one</ref>
</biblio>
</book>

the wanted result is produced:

<chapter id="c1-1">
<verse id="v1-1">Hello World</verse>
<verse id="v2-1">Goodbye World</verse>
</chapter>


=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top