XSLT: renaming an attribute in whatever element

M

Martin Plantec

Hi again,

If I may, I have another, slightly more complex, XSLT question. (I'm
learning, but it's not as easy as I would have thought!) I would like a
rule that says: for every element that has an attribute "webclass",
rename the attribute as "class", keeping the same value for the
attribute (and keeping the same element name). In other words, I would
like to rename an attribute, whatever the element it comes in.

I gather it is possible, but I had no luck so far with my tries.

Thanks,

Martin
 
M

Martin Plantec

I may have found the answer. The following rule seems to work:

<xsl:template match="*[@webclass]">
<xsl:copy>
<xsl:attribute name="class">
<xsl:value-of select="@webclass"/>
</xsl:attribute>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
 
M

Martin Plantec

Well, the problem with this, is that suppose my XML has

<para webclass="red">hjk hjk hjk</para>

and that my XSL stylesheet has already, in addition to the proposed
rule above, a rule catching para elements, in my case:

<xsl:template match="para">
<p>
<xsl:for-each select="ligne">
<xsl:apply-templates />
<xsl:if test="position() &lt; last()">
<br />
</xsl:if>
</xsl:for-each>
</p>
</xsl:template>

then this will be applied, and the "webclass" attribute of the para
elements will not be renamed. How can I solve this?

Thanks,

Martin
 
R

Richard Tobin

Martin Plantec said:
Well, the problem with this, is that suppose my XML has

<para webclass="red">hjk hjk hjk</para>

and that my XSL stylesheet has already, in addition to the proposed
rule above, a rule catching para elements, in my case:

<xsl:template match="para">
<p>
<xsl:for-each select="ligne">
[...]

Presumably you want to put the renamed attribute on the new p element?
You need to call apply-templates on the attributes of the old para
element.

<xsl:template match="para">
<p>
<xsl:apply-templates select="@*"/>
<xsl:for-each select="ligne">
....

-- Richard
 
M

Martin Plantec

Hi Richard,

Thanks for your help. This doesn't work: the attribute is renamed, but
the rule turning para into p is not applied. I have little experience
in XSLT (about 1 day), but I can speculate it is because the first rule
(attribute renaming) catches "all elements with attribute webclass" --
but the para element has already been caught, and the apply-templates
on the attributes doesn't fire it. Maybe the first rule could be
replaced by a rule targetting the webclass attribute directly (vs.
elements with the webclass attribute)?

(I have tried such a thing but it didn't work.)

If this has become confused I could produce a minimal and complete
example.

Thanks!

Martin
 
D

Dimitre Novatchev

Below is the really simple transformation producing the wanted result of
global renaming a given attribute. It uses the most fundamental XSLT design
pattern -- overriding the identity rule.

A word of caution is that you haven't specified what to do in case of a
potential conflict -- such as when an element has both a "webclass" and a
"class" attribute.

When this transformation:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:eek:utput omit-xml-declaration="yes" indent="yes"/>

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

<xsl:template match="@webclass">
<xsl:attribute name="class">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>

is applied on this source xml:

<t>
<x webclass="a" myclass="b">
<y webclass="c" yClass="d"/>
<z/>
</x>
</t>

the wanted result is produced:

<t>
<x class="a" myclass="b">
<y class="c" yClass="d"></y>
<z></z>
</x>
</t>


Cheers,
Dimitre Novatchev.
 

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,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top