Friday, September 11, 2009

How to Remove All Empty Nodes from XML Payload

Empty nodes in an XML payload increases payload size and may be the reason for XML parsing errors. You can add conditional logic to handle empty nodes in transformations but it’s not feasible for big XML payloads. Adding if/switch conditions for transforming big XML payloads is time consuming and error prone too. It requires a throughout testing to verify whether all the conditional logic is applied correctly or not.


For big XML payloads you can use a separate XSLT transformation to handle all the empty nodes. It will save your time to add conditional logic to handle empty nodes in every transformation. It incurs a little performance overhead but save lot of time and efforts to add/debug/test/re-test condition logic for empty nodes.


See the script given underneath; it can handle all empty nodes in an XML payload:


<xsl:template match="node()">
<xsl:if test="count(descendant::text()[string-length(normalize-space(.))>0]|@*)">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:if>
</xsl:template>

<xsl:template match="@*">
<xsl:copy/>
</xsl:template>

<xsl:template match="text()">
<xsl:value-of select="normalize-space(.)"/>
</xsl:template>

Steps to use this script in BPEL:

  • Drag and drop a Transform activity and select the XML payload, from which you want to remove empty nodes. Select same XML document for source and target.
  • Create an empty transformation file and go to the source view.
  • Replace the XSLT fragment given below with the XSLT script given above:


<xsl:template match="/">

</xsl:template>

  • Now you all set, save and deploy your BPEL process, XSLT map and do a sanity test.


10 comments:

Anonymous said...

Hi,

You can also remove empty elements using the remove option inside an assign activity.

<assign name="RemoveEmptyElements">
<bpelx:remove>
<bpelx:target variable="ResponseVariable" part="payload" query="/client:MyResponse/*[string-length(.) = 0]"/>
</bpelx:remove>
</assign>

Best Regards,
Harald Reinmueller

Dharmendra said...

You can use bpelx:remove to remove empty nodes, but bpelx:remove requires at least one empty node in the XML payload otherwise it will throw a selectionFailure. In real life scenarios you might get an XML payload with or without empty nodes.

Srikant Vaidya said...

Hi Dhanajay

i have a simple requirement of pushing a text file into a database.
BUT the incoming files comes in different format and all the format have a associate columns in a TABLE.

i am still looking for ways to develope a generic BPEL process where it takes files with different XSD.

is it possible, can u suggest some other way of achieving it...

Tibirius said...

You should probable use element() for the top level match.

vijaysai said...

Hi
I am trying use this function is SOA Suite 11g
It failed by giving the following exception
Do you see that I need to change something to make this work in SOA Suite 11g?



0



XPath expression failed to execute. An error occurs while processing the XPath expression; the expression is ora:processXSLT('xsl/Transformation_4.xsl',bpws:getVariableData('g_InvokeOtmInput','payload')). The XPath expression failed to execute; the reason was: XML-22900: (Fatal Error) An internal error condition occurred.. Check the detailed root cause described in the exception message text and verify that the XPath query is correct.


XPathExecutionError




Can you send me your reply to my email vijaysaib4u@gmail.com?

Thank You
Vijay Sai.S

naveen said...

http://forums.oracle.com/forums/thread.jspa?threadID=1098869&tstart=0


can u help on this thread

Unknown said...

Hi,

I'm also facing very similar issue what Vijay sai is facing, can anyone help me

Thanks
Venki

Raj said...

Hi Dharmendra,

I need few clarifications on how to implement removing empty nodes in bpel xslt.

Regards,
Raj.

Nagendra Reddy said...

Useful post on How to Remove All Empty Nodes from XML Payload.Its help me in my Oracle SOA training thank you sir.

Unknown said...

I want to remove an empty parent node only and don't want to check all child node. What to do please help.