Re: Manipulation of XSL attributes

Subject: Re: Manipulation of XSL attributes
From: David Allouche <david@xxxxxxxxxxxxxxxx>
Date: Mon, 21 Aug 2000 15:31:17 -0200 (GMT+2)
You rude boy: you must never cross-post to different mailing lists.
Choose the one more closely related to your problem or keep silence!

Let's have a look at your problem anyway.

> My desired output is:
> <img src="y.bmp" alt="z.bmp"/>  
> 
> As can be seen from above I've added in the $path and removed
> empty attribute values.
 
> <xsl:attribute-set name="attributes">
> 	<xsl:attribute name="src"><xsl:value-of select="$path"/></xsl:attribute>
> 	<xsl:if test="string(@alt)">
> 		<xsl:attribute name="alt"><xsl:value-of select="@alt/></xsl:attribute>
> 	</xsl:if>
> </xsl:attribute-set>
> .......
> <xsl:copy use-attribute-sets="attribute">
> 
> This gives me an error !!

There is a typo.  The name in the use-attribute-set does not match the
name in the attribute set declaration.

But I think the problem is more that you can only put <xsl:attribute>
elements inside an <xsl:attribute-set> element.  Only inside the
<xsl:attribute> elements you have a real template body.

The correct would look like (not tested)

<xsl:attribute-set name="attributes">
  <xsl:attribute name="src">
    <xsl:value-of select="$path"/>
  </xsl:attribute>
</xsl:attribute-set>
.........
<xsl:copy use-attribute-sets="attributes">
  <xsl:for-each select="@*[not(self::src) and string(.)]">
    <xsl:copy-of select="."/>
  </xsl:for-each>
</xsl:copy>

But this is not optimal since you have to modify the set of pruned
attribute names in the xsl:for-each select attribute for every utilisation
of the attribute-set whenever you modify the attribute-set contents.

This is bad.  You should better use a named template and call it after
copying the non-empyt attributes.

<xsl:template name="attributes">
  <xsl:attribute name="src">
    <xsl:value-of select="$path"/>
  </xsl:attribute>
</xsl:template>
.........
<xsl:copy>
  <xsl:for-each select="@*[string(.)]">
    <xsl:copy-of select="."/>
  </xsl:for-each>
  <xsl:call-template name="attributes"/>
</xsl:copy>

This way, any attribute defined in the named template will overwrite any
attribute with the same previously created by the for-each element.

Of course, if you use the named template / attribute set only in one
place, there no reason not to include the attribute definition directly in
the copy element.

Hope this helps (even if cross posting is rude)

                             -- David --


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread