Monday, December 01, 2008

Remove namespaces in OSB and BPEL/ESB

Removing name spaces from your XML payload is sometimes needed. Various reasons require this. This article shows you how to remove namesapces in your XML payload. There are two solutions.

XML Stylesheets (XSLT)

For BPEL and ESB you can use the XSLT solution to remove namespaces. The next example show you how to implement this in BPEL. First of all we need to create a XSLT file. The file shoudl looks like this:

TrX_RemoveNamespace.xsl
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes="xsl">
<xsl:template match="comment()|processing-instruction()|/">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:choose>
<xsl:when test="name() != 'xmlns'">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:when>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
The BPEL code to call this XSLT is as follows.

<assign name="Transform_1">
<copy>
<from expression="ora:getContentAsString(
ora:processXSLT('TrX_RemoveNamespace.xsl'
, bpws:getVariableData('inputVariable','payload'))
)"/>
<to variable="outputVariable" part="payload"
query="/client:BPELRemoveNameSpaceProcessResponse/client:result"/>
</copy>
</assign>


The above example will remove the namespaces from the input payload, then it will convert it to a string and put the output into the result element.

XQuery

The solution for OSB can alo apply via XLST, but in OSB the XQuery technology is used.. Removing the namespace in XQuery is done via the following function.

declare namespace xf = "http://tempuri.org/vijfhuizen/com/myMessage/";

declare function xf:strip-namespace($e as element())
as element()
{
element { xs:QName(local-name($e)) }
{
for $child in $e/(@*,node())
return
if ($child instance of element())
then xf:strip-namespace($child)
else $child
}
};
You can call this function in your XQuery file as follows.
<ns0:Data>
{
concat('<?xml version="1.0" encoding="UTF-8"?>', fn-bea:serialize(xf:strip-namespace($varMessage)))
}
</ns0:Data>

7 comments:

Bitman said...

This is sorta un-related - but would you know how to manage the error-handling in OSB?

I'm getting stuck in how events/errors from services in the stack gets passed up. I've tried to manipulate the $fault variable by adding custom messages but I'm told that $fault isn't a valid target.

NWE said...

During importing the XQuery into the ALSB/OSB this error message occcurs:

An error occurred updating the resource:
An error occurred compiling the XQuery resource: line 14, column 3: {err}XP0003: Invalid expression: unexpected token: null.

kerr said...

Hi Marc,

I read your note from OTN SOA forums.
But if I remove my name-sapce, the xml data will not be valid.
And I want to add name-space instead, because the some nodes in the XML don't have a namespace.

Please check this note.
http://forums.oracle.com/forums/thread.jspa?threadID=918002&tstart=0

Regards,
Kerr

Marc Kelderman SOA Blog said...

That your XML is not valid, due to the fact it has no namespace, is correct. But sometimes you need this ínvalid xml to pass to legacy systems.

Hendra Tanto said...

Mark, i've read your blog and i still don't really understand how to use it...

cause, my bpel returns this error

ORABPEL-09500 XPath expression failed to execute. Error while processing xpath expression, the expression is "ora:getContentAsString(ora:processXSLT('TrX_RemoveNamespace.xsl',bpws:getVariableData('session_id')))", the reason is FOTY0001: type error. Please verify the xpath query.

where should i put my "TrX_RemoveNamespace.xsl"

what is the cause of this error ?

Marc Kelderman SOA Blog said...

If you have an

the reason is FOTY0001: type error.

It is or a namespace issue or an datatype-cast issue.

The XLST should be in the same directory as your BPEL file

קובי שעיו said...

for NWE, on oracle service bus, you must also add a declaration of input variable and a call to your function. example:
declare variable $xmlObj as element() external;
ns:myfunc($xmlObj)
good luck

Post a Comment

Post a Comment