12

I have an XML document with un-namespaced elements, and I want to use XSLT to add namespaces to them. Most elements will be in namespace A; a few will be in namespace B. How do I do this?

Mathias Müller
  • 22,203
  • 13
  • 58
  • 75
Craig Walker
  • 49,871
  • 54
  • 152
  • 212

3 Answers3

15

With foo.xml

<foo x="1">
    <bar y="2">
        <baz z="3"/>
    </bar>
    <a-special-element n="8"/>
</foo>

and foo.xsl

    <xsl:template match="*">
        <xsl:element name="{local-name()}" namespace="A" >
            <xsl:copy-of select="attribute::*"/>
            <xsl:apply-templates />
        </xsl:element>
    </xsl:template>

    <xsl:template match="a-special-element">
        <B:a-special-element xmlns:B="B">
            <xsl:apply-templates match="children()"/>
        </B:a-special-element>
    </xsl:template>

</xsl:transform>

I get

<foo xmlns="A" x="1">
    <bar y="2">
        <baz z="3"/>
    </bar>
    <B:a-special-element xmlns:B="B"/>
</foo>

Is that what you’re looking for?

andrewdotn
  • 32,721
  • 10
  • 101
  • 130
  • Yup; I Googled up an answer prior to your post, and it was essentially the same. The one difference is that I'm using instead, but I believe that they're functionally identical. – Craig Walker Sep 28 '08 at 00:01
3

You will need two main ingredients for this recipe.

The sauce stock will be the identity transform, and the main flavor will be given by the namespace attribute to xsl:element.

The following, untested code, should add the http://example.com/ namespace to all elements.

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

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

Personal message: Hello, Jeni Tennison. I know you are reading this.

ddaa
  • 52,890
  • 7
  • 50
  • 59
1

Here's what I have so far:

<xsl:template match="*">
    <xsl:element name="{local-name()}" namespace="A" >
        <xsl:apply-templates />
    </xsl:element>
</xsl:template>

<xsl:template match="a-special-element">
    <B:a-special-element xmlns:B="B">
      <xsl:apply-templates />
    </B:a-special-element>
</xsl:template>

This almost works; the problem is that it's not copying attributes. From what I've read thusfar, xsl:element doesn't have a way to copy all of the attributes from the element as-is (use-attribute-sets doesn't appear to cut it).

Craig Walker
  • 49,871
  • 54
  • 152
  • 212
  • 2
    You have not read the right documentation. Use the force, read the spec, it is very well written and accessible. – ddaa Sep 27 '08 at 23:39