Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

XSL Conversion: Schema Namespace Issue

Status
Not open for further replies.

jimbo14

Programmer
Feb 22, 2009
7
GB
Hello there,

I have the following, very basic, XML Document:

<ROWSET>
<ROW>
<START_DATE>2009-02-14T00:00:00Z</START_DATE>
<END_DATE>2009-02-20T23:59:59Z</END_DATE>
</ROW>
</ROWSET>

I want to apply an XSLT to transform it into the following:

<?xml version="1.0" encoding="utf-8"?>
<notification-history-request xmlns=" <start-time>2009-02-14T00:00:00Z</start-time>
<end-time>2009-02-20T23:59:59Z</end-time>
<notification-types>
<notification-type>new-order</notification-type>
</notification-types>
</notification-history-request>

I have constructed this XSLT to do this job:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl=" version="1.1" >
<xsl:template match="ROWSET/ROW">
<notification-history-request xmlns=" <start-time><xsl:value-of select="START_DATE"/></start-time>
<end-time><xsl:value-of select="END_DATE"/></end-time>
<notification-types>
<notification-type>new-order</notification-type>
</notification-types>
</notification-history-request>
</xsl:template>
</xsl:stylesheet>

Now, if I apply that XSLT to the starting document in XML Exchanger, using the Saxon 1.X Parser, I get the desired XML document.

However, if I apply it on an Oracle Database, using the version of the Sax Parser (I think) that ships with the database, I get the following XML document:

<?xml version="1.0" encoding="utf-8"?>
<notification-history-request xmlns=" <start-time></start-time>
<end-time></end-time>
<notification-types>
<notification-type>new-order</notification-type>
</notification-types>
</notification-history-request>

In effect. the START_DATE and END_DATE values are not being transferred. However, if I remove the xmlns Google Checkout Schema namespace from the XSLT, both values are successfully transferred.

The presence of the namespace is obviously the issue, and this is only affecting the Sax Parser that comes with Oracle 10g. Unfortunately, I have to use this parser if I want to do this inside an Oracle database.

Is there any elegant way to get this to work?
 
[1] I am not sure about the quirks, if any, of Oracle's xslt processor, but, what I am sure is that v1.1 is dumped in favor of v2.0 as a successor of v1.0. Hence, you should stick to v1.0 in the root xsl:stylesheet.

[2] I would propose to move the default namespace declaration from notification-history element to xsl:stylesheet root element.
[tt]
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="[ignore][/ignore]" version="1.[red]0[/red]" [blue]xmlns="[ignore][/ignore]"[/blue]>
<xsl:template match="ROWSET/ROW">
[red]<!--[/red]
<notification-history-request xmlns="[ignore][/ignore]">
[red]-->[/red]
[blue]<notification-history-request>[/blue]
<start-time><xsl:value-of select="START_DATE"/></start-time>
<end-time><xsl:value-of select="END_DATE"/></end-time>
<notification-types>
<notification-type>new-order</notification-type>
</notification-types>
</notification-history-request>
</xsl:template>
</xsl:stylesheet>
[/tt]
[3] You could be more specific on the output's encoding and method etc using an xsl:eek:utput element. But I think method="xml" might be the default for Oracle xslt processor? If not, it should be added for clarity.
 
Hi Mate,

Thanks for your response. I constructed the following stylesheet from it:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl=" version="1.0" xmlns="<xsl:eek:utput method="xml"/>
<xsl:template match="ROWSET/ROW">
<notification-history-request>
<start-time><xsl:value-of select="START_DATE"/></start-time>
<end-time><xsl:value-of select="END_DATE"/></end-time>
<notification-types>
<notification-type>new-order</notification-type>
</notification-types>
</notification-history-request>
</xsl:template>
</xsl:stylesheet>

It worked well in the XML Exchanger Saxon Parser. Unfortunately, I got the following error message when I tried it in Oracle 10g R2:

ORA-19010: Cannot insert XML fragments

Unfortunately, that means the transformation didn't work. I know of no way to view the output, as it's all done behind the scenes by Oracle.

I did, however, manage to get the following Stylesheet to produce the desired results in Oracle:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl=" version="1.1">
<xsl:eek:utput method="xml"/>
<xsl:template match="ROWSET/ROW">
<gc:notification-history-request xmlns:gc=" <gc:start-time><xsl:value-of select="START_DATE"/></gc:start-time>
<gc:end-time><xsl:value-of select="END_DATE"/></gc:end-time>
<gc:notification-types>
<gc:notification-type>new-order</gc:notification-type>
</gc:notification-types>
</gc:notification-history-request>
</xsl:template>
</xsl:stylesheet>

Unfortunately, this means having to namespace-prefix every XML element. It seems that Oracle's parser cannot cope with default namespaces in XSL transformations. I've posted a question about this on OTN, but I'm not going to hold my breath about getting a helpful response.
 
[4] If the version with namespace prefix works for Oracle--it is also _a_ legitimate approach per w3c recommendation as well--, then you can use the xsl:namespace-alias to fix up the output. This is how.
[tt]
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="[ignore][/ignore]"
[blue]xmlns:gc="[ignore][/ignore]"[/blue]
[blue]xmlns="[ignore][/ignore]"[/blue]
version="1.0"
>
[blue]<xsl:namespace-alias stylesheet-prefix="gc" result-prefix="#default"/>[/blue]
<xsl:eek:utput method="xml"/>
<xsl:template match="ROWSET/ROW">
<[blue]gc:notification-history-request[/blue]>
<gc:start-time><xsl:value-of select="START_DATE"/></gc:start-time>
<gc:end-time><xsl:value-of select="END_DATE"/></gc:end-time>
<gc:notification-types>
<gc:notification-type>new-order</gc:notification-type>
</gc:notification-types>
</gc:notification-history-request>
</xsl:template>
</xsl:stylesheet>
[/tt]
 
Hello again,

Thanks for another helpful response. However, was that XSLT supposed to remove the "gc" prefix from the tags in the output XML file? If so, it didn't work. I got the following output running a transformation against it in the Saxon 1.X browser in XML Exchanger:

<?xml version="1.0" encoding="utf-8"?>
<gc:notification-history-request xmlns:gc=" xmlns=" <gc:start-time>2009-02-14T00:00:00Z</gc:start-time>
<gc:end-time>2009-02-20T23:59:59Z</gc:end-time>
<gc:notification-types>
<gc:notification-type>new-order</gc:notification-type>
</gc:notification-types>
</gc:notification-history-request>

Unfortunately, when I tried the same stylesheet in Oracle, it crashed once again with this error:

ORA-19010: Cannot insert XML fragments

I'd be interested in any further suggestions you have. The key thing for me now is that the XML from the XSL that does work is being correctly processed by the Google Checkout API, so essentially the original problem has been solved.

I'm just a little miffed that the Oracle XML Parser is still so darned restrictive in 10g. I've used it a lot in 9i (where it wasn't the greatest), but read that a lot of the issues had been resolved for 10g. Looks like there are still a couple......... ;)
 
[5] This is the least diverted from xsl namespace, see if it works. At all time, xsl elements are used. It might be what oracle xslt process is happy and not complaining insertion of xml fragments.
[tt]
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="[ignore][/ignore]"
xmlns="[ignore][/ignore]"
version="1.0"
>
<xsl:eek:utput method="xml"/>
<xsl:template match="ROWSET/ROW">
<xsl:element name="notification-history-request">
<xsl:element name="start-time">
<xsl:value-of select="START_DATE"/>
</xsl:element>
<xsl:element name="end-time">
<xsl:value-of select="END_DATE"/>
</xsl:element>
<xsl:element name="notification-types">
<xsl:element name="notification-type">new-order</xsl:element>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>[/tt]

Otherwise, I would suggest you post the question to oracle 10g forum.
 
Just tried that XSLT. It didn't work; got the same error message.

Thanks for your help anyway. It has been extremely informative.

I will post the new question in the Oracle forum.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top