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?
A:
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
2008-09-27 23:22:44
You have not read the right documentation. Use the force, read the spec, it is very well written and accessible.
ddaa
2008-09-27 23:39:23
A:
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
2008-09-27 23:38:13
+1
A:
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?
andrew
2008-09-27 23:46:14
Yup; I Googled up an answer prior to your post, and it was essentially the same. The one difference is that I'm using <xsl:copy-of select="@*" /> instead, but I believe that they're functionally identical.
Craig Walker
2008-09-28 00:01:09