5

This is probably a duplicate, but I haven't found the answer from any other posts so I will go ahead and ask.

Inside an XSL file, I'd like to have variables that are the namespaces that will be output.

Something like:

<xsl:variable name="some_ns" select="'http://something.com/misc/blah/1.0'" />

Then in a template, do this:

<SomeElement xmlns="$some_ns">

I have had no luck getting this work, even though it seems rather simple.

Thanks for your time.

George Brighton
  • 5,131
  • 9
  • 27
  • 36
chrismead
  • 2,163
  • 3
  • 24
  • 36

3 Answers3

9

To set namespaces dynamically at runtime, use <xsl:element> and an attribute value template.

<xsl:element name="SomeElement" namespace="{$some_ns}">
  <!-- ... -->
</xsl:element>

If you don't need to set dynamic namespaces, declare a prefix for them and use that:

<xsl:stylesheet 
  version="2.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns:foo="http://something.com/misc/blah/1.0"
>
  <xsl:template match="/">
    <foo:SomeElement>
      <!-- ... -->
    </foo:SomeElement>
  </xsl:template>
</xsl:stylesheet>

or even mark the namespace as default:

<xsl:stylesheet 
  version="2.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns="http://something.com/misc/blah/1.0"
>
  <xsl:template match="/">
    <SomeElement>
      <!-- ... -->
    </SomeElement>
  </xsl:template>
</xsl:stylesheet>
Tomalak
  • 332,285
  • 67
  • 532
  • 628
3

In XSLT 2.0 you can use <xsl:namespace>. But it's only needed in the rare case where you need to generate a namespace declaration that isn't used in the names of elements and attributes. To generate a dynamic namespace for the names of constructed elements and attributes, use the namespace attribute of xsl:element or xsl:attribute, which is an attribute value template so it can be written

<xsl:element name="local" namespace="{$var}">
Michael Kay
  • 156,231
  • 11
  • 92
  • 164
1

Please don't hit me with your legs, neither with my own. ;)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" encoding="utf-8"/>
    <xsl:variable name="some_ns" select="'http://something.com/misc/blah/1.0'" />                       
    <xsl:template match="/">
        <!-- variant for output method="text" that doesn't generate xml declaration -->
        <!--xsl:value-of select="'&#60;element xmlns=&#34;'"/>
        <xsl:value-of select="$some_ns"/>
        <xsl:value-of select="'&#34;&#47;&#62;'"/-->
        <xsl:value-of disable-output-escaping="yes" select="'&#60;element xmlns=&#34;'"/>
        <xsl:value-of select="$some_ns"/>
        <xsl:value-of disable-output-escaping="yes" select="'&#34;&#47;&#62;'"/>
    </xsl:template>
</xsl:stylesheet>

produces

<?xml version="1.0" encoding="utf-8"?>
<element xmlns="http://something.com/misc/blah/1.0"/>
arkonautom
  • 958
  • 18
  • 29
  • 1
    disable-output-escaping is a last resort when there's no other solution. It's quite unnecessary here. Downvoting. – Michael Kay Nov 07 '13 at 08:37
  • @MichaelKay Well it's not best but it's a solution as you mentioned yourself. And there's commented out variant for outputting text without disable-output-escaping ;). – arkonautom Nov 07 '13 at 08:48