Distinguishing null values, empty values and elements not present

One Star

Distinguishing null values, empty values and elements not present

Hello,
we are building an webservice that will be updating data. For simplicity, lets assume that there are 3 elements that can be updated (A as xs:string, B as xs:date and C as xs:integer).
We need to be able to distinguish whether element was ommited in the request (means - do not update), was present and was set to null value (empty string or xsi:nil, means - update and set to null), was present and was set to not null value (means - update to given value).
What is the best approach to accomplish this in Talend ESB? It seems like ommited elements and elements with empty/null value are both treated as "null" in tXMLMap.
Any advice appreciated.
Few examples:
<A>val1</A><B>2015-01-01Z</B><C>1</C> <!-- update all -->
<A>val1</A><C>1</C> <!-- update A and C, leave B unchanged -->
<A>val1</A><C xsi:nil="true" /> <!-- update A, leave B unchanged, set C to null -->
Sixteen Stars

Re: Distinguishing null values, empty values and elements not present

Use an XPath to test to see if the element actually exists combined with the null check. So if it is null and doesn't exist it means one thing, if it is null and does exist it means the other thing.
One Star

Re: Distinguishing null values, empty values and elements not present

hello,
could you be please a little more specific?
I tried to create an XPATH expression in TXMLMap to test if this node is present however it failed to compile (   boolean()) , seems like these expressions do not support xpath.
How do I create an xpath expression in tXMLMap?
Thanks,
Adam
Sixteen Stars

Re: Distinguishing null values, empty values and elements not present

Use a tExtractXMLField component to test the XPath. Use that component to return the full XML and the result of the XPath. Then send that to a tMap and use conditional logic based on the result of the XPath to decide where to send the XML for further processing.
One Star

Re: Distinguishing null values, empty values and elements not present

                                                                           
Thanks, this got me going, however still not there...
I configured the tExtractXMLField as (I think) you suggested. The payload gets extracted properly. However population of fi_string fails - in the error log I can see either - seems like the result must be a node:

Exception occurred evaluting XPath: The result of the XPath expression is not a Node. It was: false of type: java.lang.Boolean
or
Exception occurred evaluting XPath: The result of the XPath expression is not a Node. It was: true of type: java.lang.Boolean
depending of whether the element was or was not there.
Screenshot:
Sixteen Stars

Re: Distinguishing null values, empty values and elements not present

It's a bit difficult to debug this without seeing it, but it sounds like you do not have the correct type set for your column. I'm guessing you have it set as a String but the data is returning a Boolean. The response type must match the column type. I'm guessing that changing the column type to a Boolean will fix this.
One Star

Re: Distinguishing null values, empty values and elements not present

Are you able to see the attached screenshot in my previous post? On the bottom side there is a partial screenshot from the schema. The column I am populating it to is defined as "Boolean" and "Get Nodes" property on this column is unchecked.
Sixteen Stars

Re: Distinguishing null values, empty values and elements not present

Sorry I missed that. What you are doing looks OK. It must be something to do with the XPath. XPaths are notoriously tricky with Talend and I tend to try them out on test sites online before plugging them into Talend......and still have trouble getting some of them to work. I'm afraid I can't give you the answer on this one. I think you will need to play around with it until you get it right.
One Star

Re: Distinguishing null values, empty values and elements not present

I believe the problem is in how the code is generated.
In my case:
row2.payload = ParserUtils
.parseTo_Document(str_tExtractXMLField_1);
org.dom4j.XPath xTmp1_tExtractXMLField_1 = temp_tExtractXMLField_1
.createXPath(nsTool_tExtractXMLField_1
.addDefaultNSPrefix(
"boolean(cbs:validateRequest/cbs:msgDataReq/tns:t_ulica)",
loopQuery_tExtractXMLField_1));
xTmp1_tExtractXMLField_1
.setNamespaceURIs(xmlNameSpaceMap_tExtractXMLField_1);
xTmp1_tExtractXMLField_1
.setNamespaceContext(namespaceContext_tExtractXMLField_1);
Object obj1_tExtractXMLField_1 = xTmp1_tExtractXMLField_1
.evaluate(temp_tExtractXMLField_1);
if (obj1_tExtractXMLField_1 instanceof String
|| obj1_tExtractXMLField_1 instanceof Number) {
resultIsNode_tExtractXMLField_1 = false;
str_tExtractXMLField_1 = String
.valueOf(obj1_tExtractXMLField_1);
} else {
resultIsNode_tExtractXMLField_1 = true;
node_tExtractXMLField_1 = xTmp1_tExtractXMLField_1
.selectSingleNode(temp_tExtractXMLField_1);
str_tExtractXMLField_1 = xTmp1_tExtractXMLField_1
.valueOf(temp_tExtractXMLField_1);
}
And the problem is that obj1_tExtractXMLField_1 is created as "Boolean" (which is correct), however the subsequent test checks it only agains String or Number, anything else is considered a Node.
I believe this might actually be a bug that the generated code does not check for Boolean.
One Star

Re: Distinguishing null values, empty values and elements not present

Yep, after changing the Xpath expression from boolean(..) to count(..), it started working.
Sixteen Stars

Re: Distinguishing null values, empty values and elements not present

Well spotted. There is a Jira site for raising issues like this. I think your description there would be good enough to point the developers in the right direction. The link to the Jira site is https://jira.talendforge.org/secure/Dashboard.jspa