Monday, January 9, 2012

Adding namespace to XML Structure

I came across a situation while doing CSV to XML transformation, the MFL action in OSB transforms CSV to XML or vice -versa but the resulted XML structure does n't have a namespace added to it.

Namespace is required while doing service orchestration (by using Service Callout or Route action ).
There are two ways u can add namespace to xml structure .

1. Make a XSD of the xml structure and use Xquery transformation selecting newly created xsd of non-namespace as Source and in Target select as xsd/wsdl element which u want as result.

2. We can use xquery to add a default namespace to xml structure.(which is obtained using mfl action and storing the result in variable named InputRequestXmlBody
                         

xquery version "1.0" encoding "Cp1252";
(:: pragma parameter="$noNamespaceXML" type="xs:anyType" ::)
(:: pragma parameter="$namespaceURI" type="xs:string" ::)
(:: pragma type="xs:anyType" ::)
declare namespace xf = "http://tempuri.org/Resources/XQueries/addNamespace/";

declare function xf:addNamespaceToXML($noNamespaceXML as element(*),$namespaceURI as xs:string) as element(*)
{
element {fn:expanded-QName($namespaceURI,fn:local-name($noNamespaceXML))}
{
$noNamespaceXML/@*,
for $node in $noNamespaceXML/node()
return
if (exists($node/node())) then xf:addNamespaceToXML($node,$namespaceURI)
else if ($node instance of element()) then element {fn:expanded-QName($namespaceURI,fn:local-name($node))}{$node/@*}
else $node }
};

declare variable $noNamespaceXML as element(*) external;
declare variable $namespaceURI as xs:string external ;
xf:addNamespaceToXML($noNamespaceXML, $namespaceURI)


We can use replace action then to add namespace to xml structure .
                               

So XML Structure like this :




<Transaction>
    <MemberDetails>
        <CashMemoNumber>CashMemoNumber</CashMemoNumber>
        <Date>Date</Date>
        <Time>Time</Time>
        <ShopCode>ShopCode</ShopCode>
        <PrivilegeCustomerCode>PrivilegeCustomerCode</PrivilegeCustomerCode>
        <Country>Country</Country>
    </MemberDetails>
</Transaction>


would end up like this :
<req:Transaction xmlns:req="http://in.abhinav/schema/request">
<req:MemberDetails>
<req:CashMemoNumber>CashMemoNumber</req:CashMemoNumber>
<req:Date>Date</req:Date>
<req:Time>Time</req:Time>
<req:ShopCode>ShopCode</req:ShopCode>
<req:PrivilegeCustomerCode>PrivilegeCustomerCode</req:PrivilegeCustomerCode>
<req:Country>Country</req:Country>
</req:MemberDetails>
</req:Transaction>

Happy Flows !!

4 comments:

  1. which one would have better performance, the 1st or 2nd option ?

    ReplyDelete
  2. The second option would be better as your whole xml (not qualified) is being replaced with qualified namespace at the beginning rather than changing at individual steps !!

    ReplyDelete
  3. Hi thanks, for sharing this nice how-to tip. Could you tell us how do you set the namespace prefix? I see that in your example it was set to "req", but it not clear for me how you do that in the code.
    Thanks, Rob

    ReplyDelete
    Replies
    1. Rob,

      req: namespace declaration was done inside xquery selection box--- under the bind variables section .. see liink below ! http://3.bp.blogspot.com/-diQnQcs2pBo/TwnkkiBLPkI/AAAAAAAAAO4/oQypbbcNxAw/s1600/bindvariables.JPG

      $namespaceURI is the variable declared inside the xquery ..

      Regards, Abhinav

      Delete