Dynamically Mapping Fields from Salesforce Query Activity Output

While I was working on Salesforce.com integration, the TIBCO BusinessWorks plug-in provides a "Query All" and "Retrieve All" activities to query Salesforce objects. The "Query All" lets you use a SOQL statement freely, while "Retrieve All" only allows you to specify the list of fields and optionally the object IDs. The only filter you can use for the latter are the object IDs, which doesn't seem to be the case most of the time. Both activities have a generic output and are not specific to a particular Salesforce object. It has an "any element" field which you can coerce based on a specified schema and you would need a WSDL file generated from Salesforce to do this. However, the problem starts when Salesforce keeps on updating the WSDL at the same time, so you will need to map the newly added field all the time! The solution I have come up with for this dilemma was not actually quite that simple but it offers more flexibility in the code.

You would notice that the XPath expression for retrieving a particular field always starts with //result/records/. These two nodes contain a particular namespace. You can override namespaces by using the local-name() function such as the following (for instance you want to get the ContactId):

//*[local-name()='result']/*[local-name()='records']/*[local-name()='ContactId']

Even though the WSDL file is not updated, you can still retrieve the ContactId field. That means, you won't need the updated WSDL file at all!

This would be more useful if you want to implement dynamic evaluation of XPath expressions. You can write a Java custom function to do this. It could be the usual Java code. In TIBCO BW, I don't think we have yet dynamic evaluation of an XPath expression. So, in the Java method, you can pass the XPath formula and the XML string which the XPath formula will be evaluated against. I've tried this and it doesn't really slow down performance.

XPath xPath = XPathFactory.newInstance().newXPath();
xPath.evaluate(xPathExpression, new InputSource(new SringReader(...));

You can create a static XML file where you can specify all the fields you need to retrieve. You can also use this XML file to dynamically build the SOQL statement. You can iterate through the list of Salesforce fields without mapping them one by one; most especially useful if you would need to render a generic canonical XML that uses a simple "field-value pair" schema.

Comments

Post a Comment

Popular posts from this blog

XML Schema and JSON Schema Validation in Mule 4

Parsing a JSON String and Converting it to XML in TIBCO

Using XML To Java in TIBCO BW