Connecting Tech Pros Worldwide Forums | Help | Site Map

xsl:attribute w/variable as 'name' attribute?

daldridge@gmail.com
Guest
 
Posts: n/a
#1: Apr 21 '06
Is there anyway to use the contents of a variable as the value of the
'name' attribute of an <xsl:attribute>?

Suppose I have this XML input:

<Foo>
<Bar>Baz</Bar>
</Foo>


What I'd like to generate (ignore any <xs:include> requirements) is:

<xs:element ref="Baz:Baz" xmlns:Baz="A:B:C:Baz"/>


Here's what I have so far:

<xsl:template match="Foo">
<xsl:element name="xs:element">
<xsl:attribute name="ref">
<xsl:value-of select="Bar"/>
<xsl:text>:</xsl:text>
<xsl:value-of select="Bar"/>
</xsl:attribute>
<xsl:variable name="bazNamespace">
<xsl:text>xmlns:</xsl:text>
<xsl:value-of select="Bar"/>
</xsl:variable>
<xsl:attribute name="How-{$bazNamespace}-DoesntWork">
<xsl:text>A:B:C:</xsl:text>
<xsl:value-of select="Bar"/>
</xsl:attribute>
</xsl:element>
</xsl:template>


Obviously I could manually build the <xs:element> with a bunch of
<xsl:text>, but that's crummy. Any ideas?


Martin Honnen
Guest
 
Posts: n/a
#2: Apr 21 '06

re: xsl:attribute w/variable as 'name' attribute?




daldridge@gmail.com wrote:

[color=blue]
> Suppose I have this XML input:
>
> <Foo>
> <Bar>Baz</Bar>
> </Foo>
>
>
> What I'd like to generate (ignore any <xs:include> requirements) is:
>
> <xs:element ref="Baz:Baz" xmlns:Baz="A:B:C:Baz"/>[/color]

Most can be simply done with

<xsl:template match="Foo">
<xs:element
xmlns:xs="http://www.w3.org/2001/XMLSchema"
ref="{Bar}:{Bar}" />
</xsl:template>

The xmlns:Baz="A:B:C:Baz" will be tricky however as namespace
declarations in terms of the XSLT/XPath tree model are not attributes.

I am not sure that there is a way with XSLT 1.0 to achieve what you
want, if the prefix and value are to be generated from the source input.
If it were static you could simply do e.g.

<xsl:template match="Foo">
<xs:element
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:Baz="A:B:C:Baz"
ref="{Bar}:{Bar}" />
</xsl:template>

See also <http://www.dpawson.co.uk/xsl/sect2/N5536.html#d6476e2293>
which suggests XSLT 2.0 has a solution.

There you could do e.g.

<xsl:template match="Foo">
<xs:element
xmlns:xs="http://www.w3.org/2001/XMLSchema"
ref="{Bar}:{Bar}">
<xsl:namespace name="{Bar}"><xsl:value-of select="concat('A:B:C:',
Bar)" /></xsl:namespace>
</xs:element>
</xsl:template>

and the result is

<xs:element xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:Baz="A:B:C:Baz" ref="Baz:Baz"/>


http://www.saxonica.com/ provides an XSLT 2.0 processor.


--

Martin Honnen
http://JavaScript.FAQTs.com/
Joe Kesselman
Guest
 
Posts: n/a
#3: Apr 21 '06

re: xsl:attribute w/variable as 'name' attribute?


Martin Honnen wrote:[color=blue]
> I am not sure that there is a way with XSLT 1.0 to achieve what you
> want, if the prefix and value are to be generated from the source input.[/color]

XSLT 1.0 doesn't have a way to generate namespace declarations
("namespace nodes") programmatically. You may be able to find an
extension function in your implementation that will do so. If not...
well, you can _try_ creating the declaration as an attribute node,
giving it the "namespace for namespaces", and see if your implementation
will let you get away with it.
[color=blue]
> See also <http://www.dpawson.co.uk/xsl/sect2/N5536.html#d6476e2293>
> which suggests XSLT 2.0 has a solution.[/color]

It does. Known hole in the spec, closed in 2.0.

--
() ASCII Ribbon Campaign | Joe Kesselman
/\ Stamp out HTML e-mail! | System architexture and kinetic poetry
daldridge@gmail.com
Guest
 
Posts: n/a
#4: Apr 21 '06

re: xsl:attribute w/variable as 'name' attribute?


Thanks for the suggestions, Martin. They didn't work as-is, as I'm
generating a schema that references additional external schemas, thus I
want <xsl:element>s, not <xs:elements>, which brings a few restrictions
that prefent your sample from working, and I wanted to output a "ref"
attribute, rather than use one inline to refer to another node;
however, the XSLT 2.0 <xsl:namespace> was indeed the key to getting
what I wanted.

Here's what I ended up with:

<xsl:template match="Foo">
<xsl:element name="xs:element">
<xsl:attribute name="ref">
<xsl:value-of select="concat(Bar, ':', Bar)"/>
</xsl:attribute>
<xsl:namespace name="{Bar}">
<xsl:value-of select="concat('A:B:C:', Bar)"/>
</xsl:namespace>
</xsl:element>
</xsl:template>


Thanks again for the help!

David

Closed Thread