This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: Copying unknown attributes in XML to XML transformation?
Hi Bill,
> Yes, it is. The above is a little more verbose than the original solution
> proposed by a couple of people (below), but I think the syntax is simpler
> and if there are more than two or three attributes that need their values
> substituted, will be easier to maintain than this solution:
>
> <xsl:template match="connectionFactory">
> <connectionFactory host="{$host}" port="{$port}">
> <xsl:copy-of select="@*[name()!='host' and name()!='port']"/>
> </connectionFactory>
> </xsl:template>
Very possibly. One problem with the above solution in the general case
is that it doesn't work well with namespaced attributes: you need to
test local name and namespace URI or use an identity test to get
those, e.g.:
<xsl:copy-of
select="@*[not(local-name() = 'foo' and
namespace-uri() = 'http://www.bar.com/')]" />
or:
<xsl:copy-of
select="@*[count(.|../@bar:foo) != count(../@bar:foo)]" />
Copying everything and then overriding those attributes that you want
different values for saves you from having to do either of these.
> After a bit of experimentation, I came up with this:
> <xsl:template match="connectionFactory">
> <connectionFactory host="{$host}" port="{$port}">
> <xsl:copy-of select="@*[not(contains('host|port',name()))]"/>
> </connectionFactory>
> </xsl:template>
That's great as long as you don't have attribute names that are
substrings of each other. For example, if you wanted to filter out
'hostPort' attributes, but wanted to keep a 'host' attribute, then the
above solution will filter out the 'host' attributes as well.
> It still seems rather odd to me that where copying a selected list
> attributes (in this case) is so easy with:
> <xsl:copy-of select="@attr1|@attr2|@attr3"/>
> that there ought to also be a similarly easy way to copy all nodes except
> the specified ones. Maybe something like:
> <xsl:copy-of select="@*[exclude(@attr1|@attr2|@attr3)]"/>
> or
> <xsl:copy-of select="@*" exclude="@attr1|@attr2|@attr3"/>
If we were dealing with elements, then you could do:
<xsl:copy-of select="*[not(self::el1 or self::el2 or self::el3)]" />
But you can't use the self:: axis with attributes. Maybe just a set
difference function would work, like saxon:difference():
<xsl:copy-of select="saxon:difference(@*, @host | @port)" />
Cheers,
Jeni
---
Jeni Tennison
http://www.jenitennison.com/
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list