This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: Template matching attribute
- From: Peter Davis <pdavis152 at attbi dot com>
- To: xsl-list at lists dot mulberrytech dot com
- Date: Fri, 6 Sep 2002 00:30:30 -0700
- Subject: Re: [xsl] Template matching attribute
- References: <20020906053658.17590.qmail@webmail16.rediffmail.com>
- Reply-to: xsl-list at lists dot mulberrytech dot com
On Thursday 05 September 2002 22:36, Kalyan Kumar Mudumbai wrote:
> I am merging two files, and I have an element in
> file 1 like this.
>
> <Currency Unit="DOL">50</Currency>
>
> and in file 2 I have an element:
>
> <Unit key="DOL" val="$"/>
>
> In the output I should get it as:
>
> <Currency Unit="$">50</Currency>
I would normally suggest that you use <xsl:key> to easily look up the
key/value pairs, but it is difficult (although not impossible) to adapt that
to this usage since the keys and values are stored in another document, and
since it sounds like the key names aren't known beforehand. So, I'll try to
suggest something else. It's untested:
[I left out the 'xsl:' prefix on all of the elements below, but the meaning
stays the same.]
The first step is to load the second document and store it in a variable:
<variable name="keys" select="document('keys.xml')"/>
And since you're copying everything but the attributes verbatim, the second
step is to write a basic identity template:
<template match="node()">
<copy>
<apply-templates select="@*"/>
<apply-templates/>
</copy>
</template>
Now, you can write one or more templates to copy the attributes with their
modified values. If you know the list of attributes that need to be modified
beforehand, you can write them all out manually like this:
<template match="@Unit">
<attribute name="Unit">
<!-- with this usage, you could easily use <xsl:key> here instead,
bearing in mind that you'd have to use <xsl:for-each> to switch the
current document; there are a number of other threads on how to use the
key() function with multiple input documents -->
<value-of select="$keys//Unit[@key = current()]/@val"/>
</attribute>
</template>
If you don't know the attributes and elements beforehand, you can use an
uglier but more general approach:
<template match="@*">
<!-- give the new attribute the name and namespace as the original -->
<attribute name="{name()}" namespace-uri="{namespace-uri()}">
<!-- look up the new value in $keys, in the element with the same
name and namespace as the attribute and with @key equal to the
value of the attribute. -->
<value-of select="$keys//*[local-name() = local-name(current())]
[namespace-uri() = namespace-uri(current())]
[@key = current()]/@val"/>
</attribute>
</template>
Hope that helps!
--
Peter Davis
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list