Wednesday, May 23, 2018

DocToDOM functionality inin IBM Sterling Integrator

Working with XPath function DocToDOM (CSE-Sterling B2B Integrator)

You can move data from the Primary Document or any other document to the Process Data areas in IBM Sterling B2B Integrator (ISBI) by using the DocToDOM xpath function.
The data in the source document is required to be a valid XML document for the DocToDOM function to work correctly.

This blog aims to clarify the usage of the DocToDOM xPath function in ISBI and provide clear examples of its usage.

For the official ISBI Documentation about this function, please see links below:

xPath and Process Data in ISBI and DocToDOM function in ISBI


DocToDOM parameters:

DocToDOM(xpath expression [, validate, loadDTD])


Xpath expression (Required): This is the xpath query to execute against ProcessData to find the node where the
document to be used is located.  
The node returned needs to have an SCIObjectID attribute.   

validate (Optional): whether to validate the XML document or not, Default value is true.

loadDTD (Optional): Determines if the parser loads the DTD, as specified. Default value is true.


Example usages of DocToDOM functions:

Unless stated otherwise, the examples below will be assumed to be using the following XML document as the input:

<Header>
<Body>
<Partner>
<Name>CompanyA</Name>
<Contact>PersonA</Contact>
</Partner>
<DocType>ORDERS</DocType>
<OrderNumber>12345</OrderNumber>
</Body>
</Header>

---------------Moving the complete contents of the PrimaryDocument to ProcessData---------------

In this example I’m attaching the entire contents of the primary document to process data.  
The nodes returned will be attached to the root of ProcessData.

<assign to="." from="DocToDOM(PrimaryDocument)"></assign>

Results in ProcessData:

<ProcessData>
  <PrimaryDocument SCIObjectID="rhel65_templ:node1:14f6fb36f06:7609060"/>
  <BPstart>ok</BPstart>
  <Header>
    <Body>
      <Partner>
        <Name>CompanyA</Name>
        <Contact>PersonA</Contact>
      </Partner>
      <DocType>ORDERS</DocType>
      <OrderNumber>12345</OrderNumber>
    </Body>
  </Header>
  <BPend>ok</BPend>
</ProcessData>


---------------Moving the complete contents of another Document into a specific node in ProcessData---------------

In this example I’m attaching the entire contents of document called MyDocSave to process data.  
The nodes returned will be attached to the node MyMessage.

<assign to="MyMessage" from=" DocToDOM(MyDocSave)"></assign>

Results in ProcessData:

<ProcessData>
  <PrimaryDocument SCIObjectID="rhel65_templ:node1:14f6fb36f06:7612152"/>
  <MyDocSave SCIObjectID="rhel65_templ:node1:14f6fb36f06:7612152"/>
  <MyMessage>
    <Header>
      <Body>
        <Partner>
          <Name>CompanyA</Name>
          <Contact>PersonA</Contact>
        </Partner>
        <DocType>ORDERS</DocType>
        <OrderNumber>12345</OrderNumber>
      </Body>
    </Header>
  </MyMessage>
</ProcessData>


---------------Moving specific nodes to ProcessData---------------

If the document you are working with is very large, it is not recommended to parse the full contents into ProcessData,
depending on how large the document is and how your system is configured, you could even get out of memory errors when using the DocToDOM function.

Instead of moving the complete document to ProcessData, it is recommended to move only the info you need to ProcessData

In this example, I’m specifying an additional xpath node (OrderNumber) that will be executed against the document in order to return only that node.

<assign to="." from=" DocToDOM(PrimaryDocument)//OrderNumber"></assign>
or
<assign to="." from=" DocToDOM(PrimaryDocument)/Header/Body/OrderNumber"></assign>

Results in ProcessData:

<ProcessData>
  <PrimaryDocument SCIObjectID="rhel65_templ:node1:14f6fb36f06:7630219"/>
  <OrderNumber>12345</OrderNumber>
</ProcessData>


---------------Moving only the value of a certain node into another node in ProcessData---------------

You can also retrieve only the value of certain nodes of your document and assign them to a different node in ProcessData.

In the example below, we will retrieve the value of Contact in the document and assign it to the node "CustomerContactName" in ProcessData.

<assign to="CustomerContactName" from=" DocToDOM(PrimaryDocument)//Contact/text()"></assign>

Results in ProcessData:

<ProcessData>
  <PrimaryDocument SCIObjectID="rhel65_templ:node1:14f6fb36f06:7638558"/>
  <CustomerContactName>PersonA</CustomerContactName>
</ProcessData>

---------------Solving XML validation errors---------------

When using DocToDOM, you might see validation error like below in the noapp log:

[STDERR] [Error] :1:46: Document is invalid: no grammar found.
[STDERR] [Error] :1:46: Document root element "Result", must match DOCTYPE root "null".

DocToDOM contains a validation routine, and it is set by default to validate input.
The error might occur when the document does not contain the values being searched.

The easiest way to get rid of that error is to turn the validation off for the DocToDOM function.

<assign to="." from="DocToDOM(PrimaryDocument,'false')"/>


---------------Using the DocToDOM directly in an adapter configuration---------------

This example uses the LJDBC adapter to execute a select SQL query against the ISBI database and place the results directly into ProcessData using the DocToDOM function.

Note also the validation is turned off to avoid the validation error in the noapp log as mentioned in previous example.

Business Process example:

<process name="DocToDOMexample">
 <sequence>
 <operation name="JDBCQuery">
 <participant name="LightweightJDBCAdapterQuery"/>
  <output message="LightweightJDBCAdapterTypeInputMessage">
   <assign to="query_type">SELECT</assign>
   <assign to="pool">oraclePool</assign>
   <assign to="row_name">Row</assign>
   <assign to="result_name">Result</assign>
   <assign to="sql">Select * from SI_VERSION</assign>
   <assign to="." from="*"/>
  </output>
  <input message="inmsg">
   <assign to="." from="DocToDOM(PrimaryDocument,'false')"/>
  </input>
 </operation>
 </sequence>
</process>


Results in ProcessData:

<ProcessData>
  <Result>
    <Row>
      <PRODUCT_LABEL>asset</PRODUCT_LABEL>
      <BUILD_NUMBER>4060500</BUILD_NUMBER>
      <LIC_PROD_VER>4_6</LIC_PROD_VER>
      <SI_INSTALL_DATE>2015-01-05 16:56:09.0</SI_INSTALL_DATE>
      <SI_COMMENTS>asset update</SI_COMMENTS>
    </Row>
    <Row>
      <PRODUCT_LABEL>B2BF</PRODUCT_LABEL>
      <BUILD_NUMBER>4020500</BUILD_NUMBER>
      <LIC_PROD_VER>4_2</LIC_PROD_VER>
      <SI_INSTALL_DATE>2015-01-05 16:52:47.0</SI_INSTALL_DATE>
      <SI_COMMENTS>B2BF update</SI_COMMENTS>
    </Row>
  </Result>
</ProcessData>



 

Comments (0)
  • Add a Comment
  • Edit
  • More Actions v
  • Quarantine this Entry

DOMToDoc functinality in IBM Sterling Integrator

Working with XPath function DOMToDoc (CSE-Sterling B2B Integrator)
You can move data from the Process Data area into a document in IBM Sterling B2B Integrator (ISBI) by using the DOMToDoc xPath function.
This function will execute an XPath query against the process data DOM and save the node into a workflow document.

This blog aims to clarify the usage of the DOMToDoc XPath function in ISBI and provide clear examples of its usage.

For the official ISBI Documentation about this function, please see links below:

XPath and Process Data in ISBI and DOMToDoc function in ISBI


DOMToDoc parameters:

DOMToDoc(xpath expression , document_name, standalone, root_name, encoding, systemURL, dtdName, publicURL)
Wrap each parameter with single quotes, except from the first, XPath expression.

XPath expression (Required): This is the xpath query to execute against the process data to identify the node you want
to place in your new document.

documentName (Optional): This is the name to be assigned to the new workflow document. The default value is 'Document'

standAlone (Optional): The default value is 'no'.

rootName (Optional): This is the name of the document element where the result from the xpath query will reside under.
This entire node will then be written to the workflow document.
If a name is not provided then the document element will be the root node returning from the xpath query.

encoding (Optional): This string value will be used to build the encoding section of the XML header and to specify
the encoding type of the workflow document. This parameter will default to UTF-8 if an encoding is not provided.

*The next set of parameters is used to rebuild the DOCTYPE element that was lost when the xpath query was executed.

systemURL (Optional): This is the value of the system URL.

dtdName (Optional): This is the value of the DTD name. If a value for this parameter is specified then the publicURL parameter will be ignored.

publicURL (Optional): This is the value of the public URL. If a value for this parameter is specified then the DtdName parameter will be ignored.


Example usages of DOMToDoc function:

Unless stated otherwise, the examples below will assume the usage of the following info in Process Data area:

<ProcessData>
<PartnerInfo>
<Partner>
<Name>CompanyA</Name>
<Contact>PersonA</Contact>
</Partner>
<DocType>ORDERS</DocType>
<OrderNumber>12345</OrderNumber>
</PartnerInfo>
</ProcessData>


---------------Move the full contents of ProcessData to a document---------------

This example will create a new document with the full contents of ProcessData, note that the ProcessData
element will not be included, only the contents of ProcessData.

Note as well that that I am not assigning a document name, so by default it will be called "Document".

<assign to="." from="DOMToDoc(/ProcessData)"></assign>

Contents of ProcessData:

<ProcessData>
<PartnerInfo>
<Partner>
<Name>CompanyA</Name>
<Contact>PersonA</Contact>
</Partner>
<DocType>ORDERS</DocType>
<OrderNumber>12345</OrderNumber>
</PartnerInfo>
<Document SCIObjectID="rhel65_templ:node1:14f6fb36f06:8998760"/>
</ProcessData>

Contents of the document generated:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<PartnerInfo>
<Partner>
<Name>CompanyA</Name>
<Contact>PersonA</Contact>
</Partner>
<DocType>ORDERS</DocType>
<OrderNumber>12345</OrderNumber>
</PartnerInfo>


---------------Move the full contents of ProcessData to a named document---------------

This example will create a new document with the full contents of ProcessData and use the documentName parameter to name the new document MyDoc.

<assign to="." from="DOMToDoc(/ProcessData,'MyDoc')"></assign>

Contents of ProcessData:

<ProcessData>
<PartnerInfo>
<Partner>
<Name>CompanyA</Name>
<Contact>PersonA</Contact>
</Partner>
<DocType>ORDERS</DocType>
<OrderNumber>12345</OrderNumber>
</PartnerInfo>
<MyDoc SCIObjectID="rhel65_templ:node1:14f6fb36f06:9121107"/>
</ProcessData>

Contents of the document generated:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<PartnerInfo>
<Partner>
<Name>CompanyA</Name>
<Contact>PersonA</Contact>
</Partner>
<DocType>ORDERS</DocType>
<OrderNumber>12345</OrderNumber>
</PartnerInfo>


---------------Move the full Contents of ProcessData to the PrimaryDocument---------------

This example will move the full contents of Process data to a new document and assign it as Primary Document.

<assign to="." from="DOMToDoc(/ProcessData,'PrimaryDocument')"></assign>

Contents of ProcessData:

<ProcessData>
<PartnerInfo>
<Partner>
<Name>CompanyA</Name>
<Contact>PersonA</Contact>
</Partner>
<DocType>ORDERS</DocType>
<OrderNumber>12345</OrderNumber>
</PartnerInfo>
<PrimaryDocument SCIObjectID="rhel65_templ:node1:14f6fb36f06:9151630"/>
</ProcessData>

Contents of the document generated:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<PartnerInfo>
<Partner>
<Name>CompanyA</Name>
<Contact>PersonA</Contact>
</Partner>
<DocType>ORDERS</DocType>
<OrderNumber>12345</OrderNumber>
</PartnerInfo>


---------------Move the contents of Partner node only to a new document----------------

In this example we will be moving the contents of the node "Partner" only in ProcessData and move it to a new document called
MyDoc; I also want that the root element in my new document to be called "Customer", so I use the rootName parameter to assign the new root element in my document.

<assign to="." from="DOMToDoc(/ProcessData/PartnerInfo/Partner,'MyDoc','','Customer')"></assign>

Contents of ProcessData:

<ProcessData>
<PartnerInfo>
<Partner>
<Name>CompanyA</Name>
<Contact>PersonA</Contact>
</Partner>
<DocType>ORDERS</DocType>
<OrderNumber>12345</OrderNumber>
</PartnerInfo>
<MyDoc SCIObjectID="rhel65_templ:node1:14f6fb36f06:9121107"/>
</ProcessData>

Contents of the document generated:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Customer>
<Name>CompanyA</Name>
<Contact>PersonA</Contact>
</Customer>

---------------Adjusting the XML preamble---------------

By default SI will use the XML preamble below for any new document created:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

There might be a need to adjust this preamble, so in this example we are going to set the encoding to "UTF-16", the standalone to "yes"
and specify a system URL.
<assign to="." from="DOMToDoc(/ProcessData/PartnerInfo/Partner,'MyDoc','yes','Customer','UTF-16','http://hostaname:5000/test')"></assign>

Contents of ProcessData:

<ProcessData>
<PartnerInfo>
<Partner>
<Name>CompanyA</Name>
<Contact>PersonA</Contact>
</Partner>
<DocType>ORDERS</DocType>
<OrderNumber>12345</OrderNumber>
</PartnerInfo>
<MyDoc SCIObjectID="rhel65_templ:node1:14f6fb36f06:9121107"/>
</ProcessData>

Contents of the document generated:

<?xml version="1.0" encoding="UTF-16" standalone="yes"?><!DOCTYPE Customer SYSTEM "http://hostaname:5000/test">
<Customer>
<Name>CompanyA</Name>
<Contact>PersonA</Contact>
</Customer>

---------------Retrieve a specific Value from ProcessData---------------

In this example, I just want to retrieve the value of elements "Name" and "Contact" in ProcessData and create a
new flat file document correctly formatted with that info.

First, you will need to create a node in ProcessData with the info required using the format you need,
for example you can use the assign below:

<assign to="MyFlatFile" from="concat('Customer Name: ',PartnerInfo/Partner/Name/text(),string('&#x0d;&#x0a;'),'Customer Contact: ',PartnerInfo/Partner/Contact/text())"></assign>

This will create a ProcessData node called MyFlatFile like below:

<ProcessData>
<PartnerInfo>
<Partner>
<Name>CompanyA</Name>
<Contact>PersonA</Contact>
</Partner>
<DocType>ORDERS</DocType>
<OrderNumber>12345</OrderNumber>
</PartnerInfo>
<MyFlatFile>Customer Name: CompanyA
Customer Contact: PersonA</MyFlatFile>
</ProcessData>

Then use the DOMToDoc to insert the MyFlatFile node value into a new document:

<assign to="." from="DOMToDoc(MyFlatFile/text(),'PrimaryDocument')"></assign>

This will create a new document with the following contents:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>Customer Name: CompanyA
Customer Contact: PersonA

You can then use the Document Keyword Replace service to remove the XML preamble from your flat file
so that your new document contents looks like:

Customer Name: CompanyA
Customer Contact: PersonA

See link below for a blog on the document keyword replace service usage that contains an example of how to remove an XML preamble:

Document keyword Replace Service

Note: An alternative to this would be to use the StringToDoc function instead of the DOMToDoc.
The function StringToDoc will achieve the same results but without inserting the XML preamble in your new document.

<assign to="." from="StringToDoc(MyFlatFile/text(),'PrimaryDocument')"></assign>


---------------Avoid Trimming of leading or trailing spaces---------------

Sometimes some of your ProcessData values might contain trailing or leading spaces, for example:

<ProcessData>
<param1>param1</param1>
<param2>param2 </param2>
<param3> param3</param3>
</ProcessData>

When using a regular DOMToDoc function to move the contents into a new document; the document will look like the following (note the missing spaces):

<ProcessData>
<param1>param1</param1>
<param2>param2</param2>
<param3>param3</param3>
</ProcessData>

To avoid this, you can set a property to change the behavior of DOMToDoc and keep the leading and trailing spaces,if required.
You need to change the parameter trimTextNodeOutput of the translator.properties and set it to false.

You can achieve that by adding the line below to the customer_overrides.properties of your system:

translator.trimTextNodeOutput=false

Note that you will need to restart the system for the change to take effect.






 

Comments (2)
  • Add a Comment
  • Edit

What are main risks facing by bank customers while providing open banking by banks

  Open banking, while promising exciting opportunities, also comes with some potential risks for bank customers. Here are some of the main c...