0

I need to add an xmlns to the root element in the output of this XSLT transform. I've tried added <xsl:attribute name="xmlns"> but it's disallowed.

Has anyone got any ideas how I could solve this?

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

    <xsl:template match="/">
            <xsl:variable name="rootElement" select="name(*)"/>
            <xsl:element name="{$rootElement}">
                <xsl:apply-templates select="/*/*"/>
            </xsl:element>
    </xsl:template>

    <xsl:template match="node()"> 
        <xsl:copy> 
                <xsl:copy-of select="@*"/> 
            <xsl:apply-templates select="node()"/> 
        </xsl:copy> 
    </xsl:template>

</xsl:stylesheet>

2 Answers 2

4

From the XSLT 1.0 spec:

The xsl:element element allows an element to be created with a computed name. The expanded-name of the element to be created is specified by a required name attribute and an optional namespace attribute.

So you need to declare the namespace prefix you wish to use on your xsl:stylesheet element, and then specify the namespace URI when you create the element.

To illustrate, the following stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:foo="http://example.com/foo">
  <xsl:template match="/">
    <xsl:element name="bar" namespace="http://example.com/foo">element</xsl:element>
  </xsl:template>
</xsl:stylesheet>

produces the output:

<?xml version="1.0" encoding="UTF-8"?>
<foo:bar xmlns:foo="http://example.com/foo">element</foo:bar>
Sign up to request clarification or add additional context in comments.

1 Comment

The problem is how to make the nodes below use the same namespace.
2

You can't simply "add" a namespace, at least not in XSLT 1.0. Namespaces are fixed properties of the input nodes. You copy the node, you copy its namespace as well.

This means you'd have to create new nodes that are in the correct namespace. If you don't want a prefix, but a default namespace instead, the XSL stylesheet has to be in the same default namespace.

The following applies the default namespace to all element nodes and copies the rest:

<xsl:stylesheet 
  version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns="http://tempuri.org/some/namespace"
>

  <xsl:template match="node() | @*">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="*">
    <xsl:element name="{local-name()}">
      <xsl:apply-templates select="node() | @*" />
    </xsl:element> 
  </xsl:template>

</xsl:stylesheet>

turning

<bla bla="bla">
  <bla />
</bla>

to

<bla bla="bla" xmlns="http://tempuri.org/some/namespace">
  <bla></bla>
</bla>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.