Scrat
Scrat

Reputation: 99

XSLT transformation: Add fixed text to existing node value

I have a basic knowledge of XSLT transformation, but have been struggling with the following:

My xml contains :

<fixednode1>do not transform me</fixednode1>
<fixednode2>do not transform me also</fixednode2>
<element1Label>1234</element1Label>
<element7Label>hello</element7Label>
<element9Label>bar</element9Label>

I want to transform the entire xml so that, apart from the 2 fixed nodes, each node value is pre-pended by its node name followed by a colon and a whitespace, like this:

<fixednode1>do not transform me</fixednode1>
<fixednode2>do not transform me also</fixednode2>
<element1Label>element1Label: 1234</element1Label>
<element7Label>element7Label: hello</element7Label>
<element9Label>element9Label: bar</element9Label>

It should preferably be a generic transformation - the xml will sometimes contain node names which are unknown to the stylesheet. Only the 2 fixed nodes will remain the same, but they must not be transformed, only retained in the result.

I've wrestled with a "choose,when,otherwise" statement, but I'm lost at the moment. Any help or advice would be appreciated.

Kind Regards

Scrat

Upvotes: 4

Views: 2167

Answers (2)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243529

This transformation:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

 <xsl:template match="*[not(starts-with(name(), 'fixednode'))]/text()">
  <xsl:value-of select="concat(name(..), ': ', .)"/>
 </xsl:template>
</xsl:stylesheet>

when applied on the following XML document (the provided XML fragment, wrapped into a top element to become a well-formed XML document):

<t>
    <fixednode1>do not transform me</fixednode1>
    <fixednode2>do not transform me also</fixednode2>
    <element1Label>1234</element1Label>
    <element7Label>hello</element7Label>
    <element9Label>bar</element9Label>
</t>

produces the wanted, correct result:

<t>
   <fixednode1>do not transform me</fixednode1>
   <fixednode2>do not transform me also</fixednode2>
   <element1Label>element1Label: 1234</element1Label>
   <element7Label>element7Label: hello</element7Label>
   <element9Label>element9Label: bar</element9Label>
</t>

Upvotes: 1

hroptatyr
hroptatyr

Reputation: 4829

Just have a generic template and a specialised one:

<xsl:template match="*">
  <!-- prepend code here -->
</xsl:template>

<xsl:template match="fixednode1|fixednode2" priority="10">
  <xsl:copy-of select="."/>
</xsl:template>

Upvotes: 3

Related Questions