In July 2017 we introduced the new General and Iterating Splitter version 1.2. This version considers namespaces without(!) prefix in the payload. (Remark: namespaces with prefix are already supported in version 1.1)
Because this makes the behavior incompatible to version 1.1 we decided to introduce a new version. In the following short blog I’ll explain what you must pay attention for making the “new” splitter work.
There are two kind of Splitter for XML:
General Splitter and
Iterating Splitter. The General Splitter stores all “header”-nodes on the way to the first split point defined by the XPath and put them in front of each split chunk. The Iterating Splitter only extracts the nodes defined by the XPath.
Behaviour of versions below 1.2 with the following payload:
<a xmlns=”sap”>
<b>
<c>1</c>
<c>2</c>
</b>
</a>
and
XPath = /a/b/c
As the old versions ignore the Namespace xmlns=”sap” a split point is found with XPath=/a/b/c
Result for “old” General Splitter” :
1. Split
<a xmlns=”sap”>
<b>
<c>1</c>
</b>
</a>
2. Split
<a xmlns=”sap”>
<b>
<c>2</c>
</b>
</a>
Result for “old” Iterating Splitter:
1. Split
<c xmlns=”sap”>1</c>
2. Split
<c xmlns=”sap”>2</c>
In the new version 1.2 xmlns=”sap” is considered right now and no split point is found with XPath /a/b/c
To make version 1.2 split the payload above, you have to define a namespace in the Namespace Mapping of the Runtime Configuration of an IFlow and use it in the XPath. For example you can define
xmlns:n0=sap (without “ in the IFlow tooling!)
and write for XPath
/n0:a/n0:b/n0:c
A popular mistake is that one defines /n0:a/b/c for XPath but this does not split the payload above because namespaces of the payload are inherited to the child nodes.
<a xmlns=”sap”>
<b>
<c>1</c>
<c>2</c>
</b>
</a>
is equivalent to
<a xmlns=”sap”>
<b xmlns=”sap”>
<c xmlns=”sap”>1</c>
<c xmlns=”sap”>2</c>
</b>
</a>
This must be reflected in the XPath and the correct XPath for splitting is
/n0:a/n0:b/n0:c
If the payload is
<a xmlns=”sap”>
<b xmlns=””>
<c xmlns=””>1</c>
<c xmlns=””>2</c>
</b>
</a>
then the XPath = /n0:a/b/c
would actually produce 2 chunks. For General Splitter the chunks are
<a xmlns="sap">
<b xmlns="">
<c xmlns="">1</c>
</b>
</a>
<a xmlns="sap">
<b xmlns="">
<c xmlns="">2</c>
</b>
</a>
Another example:
If the payload is
<a xmlns=”sap”>
<b>
<c>1</c>
<c xmlns=””>2</c>
</b>
</a>
then the XPath = /n0:a/n0:b/c
would create 1 chunk for General Splitter.
But what a surprise, the result is
<a xmlns="sap">
<b>
<c>1</c>
<c xmlns="">2</c>
</b>
</a>
You see <c>1</c> in the split! The reason is that <c>1</c> is a header for the General Splitter on the way to the first split point. Please remember the specification of the general splitter and that namespaces are inherited to the child nodes.
If the payload has namespaces with prefix than there is no difference in the behavior of the different splitter versions.
Appendix:
General Splitter and Iterating Splitter
In the business world there are a lot of documents with preceding information you don’t want to lose while splitting the document. Let’s assume you have an account statement with your name and different items. Then you probably expect that each item contains your name also after the split. This behavior is ensured by the General Splitter. I confess that the name “General Splitter” is not self-explaining so you have to learn the specification behind.
Another Example for a payload where one also want to preserve the header information after split:
<customer>
<customerNumber>0001</customerNumber>
<customerName>Paul Smith</customerName>
<order id="100">
<items>
<item>ice</item>
<item>fish</item>
<item>bologna</item>
</items>
</order>
<order id="101">
<items>
<item>bread</item>
<item>jam</item>
<item>butter</item>
</items>
</order>
</customer>
If you split this payload with the General Splitter and XPath = /customer/order
then you get 2 split
1. Split:
<customer>
<customerNumber>0001</customerNumber>
<customerName>Paul Smith</customerName>
<order id="100">
<items>
<item>ice</item>
<item>fish</item>
<item>bologna</item>
</items>
</order>
</customer>
2. Split:
<customer>
<customerNumber>0001</customerNumber>
<customerName>Paul Smith</customerName>
<order id="101">
<items>
<item>bread</item>
<item>jam</item>
<item>butter</item>
</items>
</order>
</customer>
With the Iterating Splitter and the same XPath = /customer/order
only the corresponding nodes are returned
1. Split:
<order id="100">
<items>
<item>ice</item>
<item>fish</item>
<item>bologna</item>
</items>
</order>
2. Split:
<order id="101">
<items>
<item>bread</item>
<item>jam</item>
<item>butter</item>
</items>
</order>
General and Iterating Splitter can not only split XML but also CSV (Text Files) with the “Expression Type” equal “Line Break”
If the incoming File is
ID;Category;Article;Description;Price;Weight
100;Mobile Phone;Samsung S5 Mini;blablabla;499.80;0.21
101;Mobile Phone;HTC XDA Orbit;blaundblupp;298.90;0.18
then you should use the General Splitter to get
1. Split:
ID;Category;Article;Description;Price;Weight
100;Mobile Phone;Samsung S5 Mini;blablabla;499.80;0.21
2. Split:
ID;Category;Article;Description;Price;Weight
101;Mobile Phone;HTC XDA Orbit;blaundblupp;298.90;0.18
Also here the column description is added to each split.
With the Iterating Splitter you get 3 splits:
1. Split:
ID;Category;Article;Description;Price;Weight
2. Split:
100;Mobile Phone;Samsung S5 Mini;blablabla;499.80;0.21
3.Split:
101;Mobile Phone;HTC XDA Orbit;blaundblupp;298.90;0.18
Restrictions:
● You cannot use two consecutive Splitter elements ending in Gather.
● You cannot use PKCS7 and IDOC Splitter within a Subprocess.