I'm not sure if that is possible, as I'm very new to XSLT and stuff, but maybe some of you could help me here? It's a bit tricky and I haven't found anything like it on the internet:
The problem is that I have an input xml with namespaces declared and all and I only need to make slight changes to it (adding or deleting attributes, or shifting them to other locations). But at the same time, I have to update the namespace references in the document's document tag. So, for example, the input xml might look something like this:
<order
xmlns="some.url.01"
xmlns:ns2="some.other.url"
xmlns:ns3="another.one"
>
<orderEntry>
<orderControl>
<mandant>test</mandant>
<businessUnit>test</businessUnit>
<inboundChannel>test</inboundChannel>
<timestamp>timestamp</timestamp>
<requestedDocuments>
<ns2:document>orderForm</ns2:document>
</requestedDocuments>
</orderControl>
</orderEntry>
</order>
the resulting xml should look like this:
<order
xmlns="some.url.02"
xmlns:ns2="some.other.url.02"
xmlns:ns3="another.one.02"
>
<orderEntry>
<orderControl>
<mandant>test</mandant>
<businessUnit>test</businessUnit>
<inboundChannel>test</inboundChannel>
<!-- deleted timestamp for example -->
<requestedDocuments>
<ns2:document>orderForm</ns2:document>
</requestedDocuments>
</orderControl>
</orderEntry>
</order>
but the only thing I get is:
<order
xmlns="some.url.02"
>
<orderEntry>
<orderControl>
<mandant>test</mandant>
<businessUnit>test</businessUnit>
<inboundChannel>test</inboundChannel>
<!-- deleted timestamp for example -->
<requestedDocuments>
<ns2:document xmlns:ns2="some.other.url.02">orderForm</ns2:document>
</requestedDocuments>
</orderControl>
</orderEntry>
</order>
Now maybe for one or two of you it might not be that big a deal, but I have the restriction that the output document should look one-to-one the same as the input document except for the requested changes (namespace changes and deletion).
My XSLT looks a like this:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="some.url.02"
xmlns:ns2="some.other.url.02"
xmlns:ns3="another.one.02"
>
<xsl:output method="xml" version="1.0" encoding="UTF-8" standalone="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*">
<xsl:choose>
<xsl:when test="name(.) != 'timestamp'">
<xsl:element name="{node-name(.)}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{node-name(.)}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
Can somebody please help? Namespaces are tricky :(
P.S.: Whoever edited my entry: Thanks :)
You can set the namespace on the output element with the namespace attribute:
Note that the namespace must be a URI and although I expect you know this it's probably a good idea to use URIs in your example.
Here is a link to the excellent ZVON tutorial which has worked examples: http://www.zvon.org/xxl/XSLTreference/Output/xslt_element_namespace.html
I agree that namespaces are tricky. As you know the prefix is semantically irrelevant, but many systems allow you to choose your prefix for aesthetic reasons. Also look at Saxon (http://saxon.sourceforge.net/)
EDIT I think you will find your answer here: XSLT root tag namespace instead of element attribute namespace
It searches for any element in namespace with prefix
a
and replaces it with an element with the same name of namespacehttp://example.com/B
. All attributes are copied 'as is' and then all children are evaluated.Add your custom processing in or around that as needed.
Output:
Are you using Ant's XSLT task to do your transformation?
If the answer is yes, you may want to switch from the default XSLT engine that comes with Sun JDK 1.5+. Read this.
Also, read this article about namespaces in XSLT