In this post I will explain you how to
convert delimited string to XML fragment/format by using “oraext:create-nodeset-from-delimited-string()” function in SOA 11g.
You can download code from here
Input Delimited string
E.g.
Vivek,25,Mumbai
In response we should get below xml
<processResponse>
<Name>vivek</Name>
<Age>25</Age>
<Address>Mumbai</Address>
</processResponse>
We need to use one intermediate schema
to accomplish this task, so first we will convert delimited string to
intermediate schema format and then to final xml format.
To start with this, we need to create a
simple composite application.
-
Create a composite and add one
Sync BPEL process in it. Use below schema for BPEL
<?xml version="1.0" encoding="UTF-8"?>
<schema
attributeFormDefault="unqualified"
elementFormDefault="qualified"
targetNamespace="http://xmlns.oracle.com/TestApplication/DelimitedStringToXml/DelimitedStringToXml"
xmlns="http://www.w3.org/2001/XMLSchema">
<element name="process">
<complexType>
<sequence>
<element name="input" type="string"/>
</sequence>
</complexType>
</element>
<element
name="processResponse">
<complexType>
<sequence>
<element name="Name" type="string"/>
<element name="Age" type="string"/>
<element name="Address" type="string"/>
</sequence>
</complexType>
</element>
</schema>
-
Create one intermediate schema
<?xml version="1.0"
encoding="windows-1252" ?>
<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.example.org"
targetNamespace="http://www.example.org"
elementFormDefault="qualified">
<xsd:element name="Customer">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="CustomerInfo"
type="xsd:string" minOccurs="0"
maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
-
Now we will convert delimited
string to intermediate xml format. To do
this we will use one function “oraext:create-nodeset-from-delimited-string”
in assign activity and the operation will be CopyList not Copy.
<assign
name="StringToIntermedaiteXMl">
<bpelx:copyList>
<bpelx:from
expression="oraext:create-nodeset-from-delimited-string('{http://www.example.org}CustomerInfo',bpws:getVariableData('inputVariable','payload','/client:process/client:input'),',')"/>
<bpelx:to variable="CustomerInfo"
query="/ns1:Customer/ns1:CustomerInfo"/>
</bpelx:copyList>
</assign>
-
Now we need to transform
intermediate xml format to actual xml format. To do this add one transform.
<assign
name="Transform_FinalResult">
<bpelx:annotation>
<bpelx:pattern>transformation</bpelx:pattern>
</bpelx:annotation>
<copy>
<from
expression="ora:doXSLTransformForDoc('xsl/Transformation_Output.xsl',
$CustomerInfo)"/>
<to variable="outputVariable" part="payload"/>
</copy>
</assign>
-
In transform just do the
required mapping
<xsl:template match="/">
<client:processResponse>
<client:Name>
<xsl:value-of
select="/ns0:Customer/ns0:CustomerInfo[1]"/>
</client:Name>
<client:Age>
<xsl:value-of
select="/ns0:Customer/ns0:CustomerInfo[2]"/>
</client:Age>
<client:Address>
<xsl:value-of
select="/ns0:Customer/ns0:CustomerInfo[3]"/>
</client:Address>
</client:processResponse>
</xsl:template>.
-
Complete
Bpel flow
-
Now we are ready to test our bpel peocess. Go to em console and test your bpel
process.
You can download code from here
Hi Vivek,
ReplyDeleteThis is a great post... Finally a working sample with oraext:create-nodeset-from-delimited-string()...
Still could not find a way to use it into a XSLT transformation...
Shame on Oracle that decided not to implement fn:tokenize XPath function, that would make the work so much easier...
Cheers,
Vlad
Yes Vlad , as you mentioned fn:tokenize is not available currently.
ReplyDelete"create-nodeset-from-delimited-string" is also available in transform but again you have to follow same steps, first convert delimited string to intermediate format and then to final format.
Vivek
Tried but instead of the nodes I got this...
ReplyDelete<tns:val>oracle.xml.parser.v2.XMLNodeList@246be4</tns:val>
Can you please post a sample with XSLT?
Cheers,
Vlad
Vlad,
DeleteSample code is attached in the post , you can download it and check the transform.
Vivek
Hi Vivek,
ReplyDeleteThe sample code doesn't have create-nodeset-from-delimited-string IN the XSLT transformation.
I'm looking for a way to use create-nodeset-from-delimited-string in a XSLT transf, at the moment, I don't think it's possible.
Cheers,
Vlad
Vlad,
DeleteI never tried "create-nodeset-from-delimited-string" function inside XSLT. I will try to create one sample and will share with you.
Vivek
Vlad,
DeleteYou can not use this function inside transform. This is Bug (14548762). Hope Oracle will come up with solution in next release.
Vivek
Many thanks, Vivek!
DeleteNice Post, helped me a lot
ReplyDeleteThanks
This comment has been removed by the author.
ReplyDeleteHi, I tried your example but for some reason, when create the nodeset from the delimited string, the result complex object is not the original Customer, it renames the child CustomerInfo nodes to Customer, so I have
ReplyDeleteCustomer
Customer
Customer c1 /Customer
Customer c2 /Customer
Customer c3 /Customer
/Customer
/Customer
any idea what i am doing wrong?
thanks for the post btw
Hi Rene,
DeleteMake sure you are using correct schema and mapping nodeset function to CustomerInfo not to Customer element of the schema.
Thanks
Vivek Garg
Hi Vivek,
ReplyDeleteIm using the below code and it works fine., But it ommiting all the empty fields.., Is there any way to include the empty tags also,
And my input is ,
C|2004|CL009|007|||101
And my Current Output is,
C
2004
CL009
007
101
But i want output like below,
C
2004
CL009
007
101
Can you please help in this.??
My Current Output..,
ReplyDelete(Result) C (/Result)
(Result) 2004 (/Result)
(Result) CL009 (/Result)
(Result) 007 (/Result)
(Result) 101 (/Result)
Expected output:
(Result) C (/Result)
(Result)2004 (/Result)
(Result) CL009 (/Result)
(Result) 007 (/Result)
(Result/)
(Result/)
(Result) 101 (/Result)
Hi Praba,
DeleteThis should work. Please send me your code to my id (gargvivek2008@gmail.com). I will look over it.
Thanks
Vivek Garg
was there any update on this? i am experiencing the same issue..
Deleteinput string is "x;xx;xxx;;xxxxx"
with delimiter ";"
and instead of "x","xx","xxx","","xxxxx"
i receive ""x","xx","xxx","xxxxx"
I tried but I also got the same response. Seems like this function does not allow null values.
DeleteHi Vivek,
ReplyDeleteIs it possible to create node-set from more than on delimited string?
Ex:
1,2,3
x,y,z
1990,1991,1992 to
1
x
1990
2
y
1991
3
z
1992
We can use only one delimited string in this function.
DeleteThanks for the reply ya.. I think I can do it by for each/Repeat Until and substring functions in BPEL. Lemme try that..
DeleteHi Vivek, I am trying to do countNodes on the result from the create-nodeset-from-delimited-string function but this does not seem to work
ReplyDeleteplease see code below
oraext:create-nodeset-from-delimited-string('{http://xmlns.oracle.com/TestNodeSet_jws/TestNodeSet/TestNodeSet} innerElement',bpws:getVariableData('inputVariable','payload','/client:process/client:input'),';')
ora:countNodes('OuterElement','','/client:Output/client:innerElement')
Hi,
DeletePlease try with count function , like count(bpws:getVariableData('inputVariable','payload','/client:process/client:input'))
Vivek Garg
Helped me solve one of my requirement. Glad that you shared :)
ReplyDelete