I think the best way to ask this question is: How do I specify a default namespace for the root element in the output? Doing this:
<xsl:template match="/">
<r xmlns:s"http://www.mycompany.com/s/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.mycompany.com/default/schema" >
....
....
Gives me an error in Oracle:
ORA-31011: XML Parsing Failed ORA-19201: Error occurred in in XML Processing LPX-00604: Invalid attribute 'nIfNotExist', for attribute 'name' ORA-06512: at SYS.XMLType at line 74 ORA-06512: at line 24
where the 'nIfNotExist'
is a template:
<xsl:template name="nIfNotExist" xmlns:scom="http://www.mycomapny.com/s/schema">
<xsl:param name="nodeToTest"/>
<xsl:param name="nodeName"/>
...
I want the resulting document to have the root element look like this:
<r xmlns:s="http://www.mycompany.com/s/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.mycompany.com/default/schema">
I want "http://www.mycompany.com/default/schema"
as the default namespace so the document can pass XSD validation. Otherwise, I have to add it manually before running validation (not an option for batch processing).
EDIT
I have tried 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:s="http://www.mycompany.com/schema"
xmlns="http://www.mycompany.com/def_schema">
The result is a document with no data, like this:
<r xmlns:s="http://www.mycompany.com/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.mycompany.com/def_schema">
<a></a>
<s:b></s:b>
<c></c>
....
It should have been:
<r xmlns:s="http://www.mycompany.com/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.mycompany.com/def_schema">
<a>123</a>
<s:b>ABC34L</s:b>
<c>7.092381</c>
UPDATE
Source data looks something like this (input that I get has no namespaces defined in it):
<ROOT_NODE>
<DATA_A>1234</DATA_A>
<DATA_B>34567</DATA_B>
<OTHER_DATA_C>7.123456</OTHER_DATA_C>
</ROOT_NODE>
Desired output
<r xmlns:s="http://www.mycompany.com/schema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.mycompany.com/def_schema">
<a>1234</a>
<s:b>34567</s:b>
<c>7.123456</c>
</r>
This transformation:
when applied on the provided XML document:
produces the wanted result:
You're halfway to the right answer. When you declare a default namespace at the root of the transform, you are asserting (assuming that you don't override the declaration elsewhere) that all of the non-qualified elements in that document belong to that namespace. Every non-qualified element that the transform emits will belong to that namespace. You've got that part right.
What I think you're probably overlooking is that namespace declarations in an XSLT transform also apply to the XPath patterns in the transform. I'd bet that the XPath node tests in your transform aren't matching any of the input nodes because the input nodes are in the empty namespace, not the namespace you've declared in the transform.
What you probably want to do is something like this:
...and then change the patterns in the transform accordingly:
This is, by the way, one of the reasons that
xsl:element
exists - you can build a template that transforms elements from one namespace to another with it, e.g.:Edit:
I haven't played around with namespace in quite this way before, and it turns out that the above is not actually legal. You can't specify no namespace with a namespace prefix. So you can't use the target namespace as the default namespace of your transform, because then you have no way of telling XPath to find the elements in the source document.
You can either specify the output namespace with a prefix, e.g.:
...but that will write the
out
namespace prefix to the output, which won't bother any XML processor but might bother humans. Or you can specify it explicitly in your templates, e.g.:There are many possible solutions, but none seem to work well in Oracle, from PL/SQL. One of the other devs here "solved" this by converting the XML object to a CLOB, performing some string manipulation to force the default namespace into the root element, and then converting back to XML for the next step... I don't like it but it works...