Jules Colle
Jules Colle

Reputation: 11939

xslt how to add attributes to copy-of

I have the following piece of code in my XSLT file:

<xsl:copy-of select="/root/Algemeen/foto/node()" />

In the XML file the node /root/Algemeen/foto/ holds an HTML image, for example: <img src="somephoto.jpg" />

What I would like to do is to add a fixed width to the image. But the following doesn't work:

<xsl:copy-of select="/root/Algemeen/foto/node()">
    <xsl:attribute name="width">100</xsl:attribute>
</xsl:copy-of>

Upvotes: 32

Views: 29586

Answers (1)

Mads Hansen
Mads Hansen

Reputation: 66714

xsl:copy-of performs a deep copy of the selected node, but doesn't provide an opportunity to alter it.

You will want to use xsl:copy and then add additional nodes inside. xsl:copy just copies the node and namespace attributes, but not the regular attributes and child nodes, so you will want to ensure that you apply-templates to push the other nodes through as well. xsl:copy does not have a @select, it works on the current node, so wherever you were applying the <xsl:copy-of select="/root/Algemeen/foto/node()" /> , you will need to change to <xsl:apply-templates select="/root/Algemeen/foto/node()" /> and move the img logic into a template.

Something like this:

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

  <xsl:template match="/">
    <result>
      <xsl:apply-templates select="/root/Algemeen/foto/img"/>
    </result>
  </xsl:template>
    
  <!--specific template match for this img -->
  <xsl:template match="/root/Algemeen/foto/img">
    <xsl:copy>
      <xsl:attribute name="width">100</xsl:attribute>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>
    
  <!--Identity template copies content forward -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
    
</xsl:stylesheet>

Upvotes: 54

Related Questions