Discussion:
How to parse xml coming in http.bodyAsString attribute in HTTP Client Connector to set work entry for Recon operation
Add Reply
Sufyan Khan
2017-11-03 11:10:02 UTC
Reply
Permalink
Raw Message
I have developed custom adapter in which I am consuming SOAP WS (using HTTP Client Connector). In response I am getting XML (as below) in http.bodyAsString attribute.

How to parse below xml so that in every iteration I can map data of each Entry tag of XML in work and return work back to ISIM.


[It can be done if this XML is stored in file so using file connector in for each loop and simple xml parser, but I don't want to implement this approach as it is not a good way]


<?xml version="1.0" encoding="UTF-8"?>
<DocRoot>
<Entry>
<Telephone>111-1111</Telephone>
<Birthdate>1958-12-24</Birthdate>
<Title>Full-Time TDI Specialist</Title>
<uid>jdoe</uid>
<FullName>John Doe</FullName>
</Entry>
<Entry>
<Telephone>2222222</Telephone>
<Birthdate>12/23/4567</Birthdate>
<Title>Test</Title>
<uid>skhan</uid>
<FullName>Sufyan Khan</FullName>
</Entry>
</DocRoot>
yn2000
2017-11-03 18:08:56 UTC
Reply
Permalink
Raw Message
Somehow I have a mental block (amnesia) on how to loop the AL one entry at a time, but in your case, here is the 'lazy' way to skin the cat.
1. Put the HTTP Client connector to passive
2. Call that HTTP Client connector from 'On Start of Cycle' hook and drop the return message into a file.
3. Then, use a normal iterator to read that file, one entry at a time.
Side benefit: You will have a copy of the recon process in a file for forensic purpose... and yes, somehow I am sensitive about audit and forensic, lately.
Rgds. YN.
Eddie Hartman
2017-11-03 22:21:52 UTC
Reply
Permalink
Raw Message
Post by yn2000
Somehow I have a mental block (amnesia) on how to loop the AL one entry at a time, but in your case, here is the 'lazy' way to skin the cat.
1. Put the HTTP Client connector to passive
2. Call that HTTP Client connector from 'On Start of Cycle' hook and drop the return message into a file.
3. Then, use a normal iterator to read that file, one entry at a time.
Side benefit: You will have a copy of the recon process in a file for forensic purpose... and yes, somehow I am sensitive about audit and forensic, lately.
Rgds. YN.
If you are comfortable scripting then I would suggest scripting an Iterator. The initialize() function can be used to get the HTTP Client connector ready:

http = system.getConnector("ibmdi.HTTPClient");
http.initialize(null);

Then in selectEntries you make the actual request, e.g. using queryReply()

var requestEntry = system.newEntry();
requestEntry["http.Accept"] = "text/xml";
requestEntry.url = "http.....";
requestEntry["http.remoteuser"] = "login";
requestEntry["http.remotepass"] = "secret";
var replyEntry = http.queryReply(requestEntry);
// now parse the xml
var xml = work.getString("http.bodyAsString");
var xmlEntry = com.ibm.di.entry.Entry.fromXML(xml, "*", "");
// and get the list of Nodes
nodeList = xmlEntry.getElementsByNodeName("Entry");
// initialize the index
index = 0;

And then in getNextEntry() you advance the counter and return the next Entry;

if (index >= nodeList.getLength()) {
result.setStatus(0); // End of data
return;
}

var node = nodeList[index];
for (var att in node) {
var attName = node.getName();
var attVal = node.getValue();
entry[attName] = attVal;
}
index++;
Sufyan Khan
2017-11-05 21:56:55 UTC
Reply
Permalink
Raw Message
Post by Eddie Hartman
Post by yn2000
Somehow I have a mental block (amnesia) on how to loop the AL one entry at a time, but in your case, here is the 'lazy' way to skin the cat.
1. Put the HTTP Client connector to passive
2. Call that HTTP Client connector from 'On Start of Cycle' hook and drop the return message into a file.
3. Then, use a normal iterator to read that file, one entry at a time.
Side benefit: You will have a copy of the recon process in a file for forensic purpose... and yes, somehow I am sensitive about audit and forensic, lately.
Rgds. YN.
http = system.getConnector("ibmdi.HTTPClient");
http.initialize(null);
Then in selectEntries you make the actual request, e.g. using queryReply()
var requestEntry = system.newEntry();
requestEntry["http.Accept"] = "text/xml";
requestEntry.url = "http.....";
requestEntry["http.remoteuser"] = "login";
requestEntry["http.remotepass"] = "secret";
var replyEntry = http.queryReply(requestEntry);
// now parse the xml
var xml = work.getString("http.bodyAsString");
var xmlEntry = com.ibm.di.entry.Entry.fromXML(xml, "*", "");
// and get the list of Nodes
nodeList = xmlEntry.getElementsByNodeName("Entry");
// initialize the index
index = 0;
And then in getNextEntry() you advance the counter and return the next Entry;
if (index >= nodeList.getLength()) {
result.setStatus(0); // End of data
return;
}
var node = nodeList[index];
for (var att in node) {
var attName = node.getName();
var attVal = node.getValue();
entry[attName] = attVal;
}
index++;
Thanks Eddie for your help.
I tried your way but I am getting unexpected error, below is the trace -


Exception occurred: java.lang.Exception: Error calling method 'getElementsByNodeName(string)' on an object of type 'com.ibm.di.entry.Entry [Dynamic Java Wrapper, com.ibm.di.entry.Entry]'
java.lang.Exception: Error calling method 'getElementsByNodeName(string)' on an object of type 'com.ibm.di.entry.Entry [Dynamic Java Wrapper, com.ibm.di.entry.Entry]'
at com.ibm.di.script.ScriptEngine.unWrap(ScriptEngine.java:977)
at com.ibm.di.script.ScriptEngine.interpret(ScriptEngine.java:942)
at com.ibm.di.script.ScriptEngine.interpret(ScriptEngine.java:925)
at com.ibm.di.server.ScriptComponent.add1(ScriptComponent.java:244)
at com.ibm.di.server.ScriptComponent.add(ScriptComponent.java:210)
at com.ibm.di.server.AssemblyLine.msExecuteNextConnector(AssemblyLine.java:3782)
at com.ibm.di.server.AssemblyLine.executeMainStep(AssemblyLine.java:3392)
at com.ibm.di.server.AssemblyLine.executeMainLoop(AssemblyLine.java:3000)
at com.ibm.di.server.AssemblyLine.executeMainLoop(AssemblyLine.java:2983)
at com.ibm.di.server.AssemblyLine.executeAL(AssemblyLine.java:2952)
at com.ibm.di.server.AssemblyLine.run(AssemblyLine.java:1319)


Could you please advice?


Regards,
Sufyan
s***@gmail.com
2017-11-06 16:34:26 UTC
Reply
Permalink
Raw Message
Post by yn2000
Somehow I have a mental block (amnesia) on how to loop the AL one entry at a time, but in your case, here is the 'lazy' way to skin the cat.
1. Put the HTTP Client connector to passive
2. Call that HTTP Client connector from 'On Start of Cycle' hook and drop the return message into a file.
3. Then, use a normal iterator to read that file, one entry at a time.
Side benefit: You will have a copy of the recon process in a file for forensic purpose... and yes, somehow I am sensitive about audit and forensic, lately.
Rgds. YN.
Hi YN,

Actually I don't want to dump the xml in file, it won't look good so I am trying other ways to get this done.

Regards,
Sufyan
yn2000
2017-11-06 19:22:43 UTC
Reply
Permalink
Raw Message
In case you still want to pursue the 'lazy' way and you do not like recording the transaction into a file, then I guess you can try sending the return message into the memory stream (or other method) instead.

For example:
In Prolog - After Init (hook), instead of On Start of Cycle (hook), you have the response string in the responseString variable. Then you call:
MemoryStreamConnector.connector.initialize(responseString);

Then in the AL Feed >> MemoryStreamConnector (Iterator), you choose XML parser.

... or something like that.
Rgds. YN.
Eddie Hartman
2017-11-06 19:53:06 UTC
Reply
Permalink
Raw Message
Post by yn2000
In case you still want to pursue the 'lazy' way and you do not like recording the transaction into a file, then I guess you can try sending the return message into the memory stream (or other method) instead.
MemoryStreamConnector.connector.initialize(responseString);
Then in the AL Feed >> MemoryStreamConnector (Iterator), you choose XML parser.
... or something like that.
Rgds. YN.
Hands in the air. Who would like to get online together to look at how to roll your own scripted Iterator for use in an Adapter AL? And @Sufyan, if you share your screen then it will be your Adapter AL we make together.

And I would want to record the session. The more the merrier :)
Sufyan Khan
2017-11-08 18:33:00 UTC
Reply
Permalink
Raw Message
Post by Eddie Hartman
Post by yn2000
In case you still want to pursue the 'lazy' way and you do not like recording the transaction into a file, then I guess you can try sending the return message into the memory stream (or other method) instead.
MemoryStreamConnector.connector.initialize(responseString);
Then in the AL Feed >> MemoryStreamConnector (Iterator), you choose XML parser.
... or something like that.
Rgds. YN.
And I would want to record the session. The more the merrier :)
Eddie Sir I am done with the Adapter :), the script which you shared above was very helpful, thank you very much.

But it would be pretty Great to have a session from you on Script Connector, I AM IN.


Below is the script for reference (Here I have consumed "Test WebService" which is available for free, URL: http://www.webservicex.net/globalweather.asmx).


~~~~~~~~~~~~~~~~~~~~~~~ SCRIPT START ~~~~~~~~~~~~~~~~~~~~~~~

// Sample connector
// Place initialization code before function declarations
//
var index = 0;
var httpConn = system.getConnector("ibmdi.HTTPClient");
httpConn.initialize(null);

function selectEntries()
{
var requestEntry = system.newEntry();
requestEntry["http.Content-Type"] = 'text/xml;action="http://www.webserviceX.NET/GetCitiesByCountry"';
requestEntry["http.url"] = "http://www.webservicex.net/globalweather.asmx";
requestEntry["http.method"] = "POST";
requestEntry["http.body"] = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://www.webserviceX.NET">' +
'<soapenv:Header/>' +
'<soapenv:Body>' +
'<web:GetCitiesByCountry>' +
'<!--Optional:-->' +
'<web:CountryName>nepal</web:CountryName>' +
'</web:GetCitiesByCountry>' +
'</soapenv:Body>' +
'</soapenv:Envelope>';

var replyEntry = httpConn.queryReply(requestEntry);
var responseXML = replyEntry.getString("http.bodyAsString");

var tEntry = system.parseObject("XMLSax", responseXML);
var nXML = tEntry.getString("soap:***@soap:***@GetCitiesByCountryResponse@GetCitiesByCountryResult");

var xmlEntry = com.ibm.di.entry.Entry.fromXML(nXML, "*", "");
nodeList = xmlEntry.getElementsByTagName("Table");

task.logmsg("INFO", "Nodelist Length: " + nodeList.getLength());
}

function getNextEntry ()
{
if (index >= nodeList.getLength()) {
result.setStatus(0); // End of data
return;
}

var node = nodeList[index];
for (var att in node) {
var attName = att.getName();
var attVal = att.getValue();
entry[attName] = attVal;
}
index++;
}

~~~~~~~~~~~~~~~~~~~~~~~ SCRIPT END ~~~~~~~~~~~~~~~~~~~~~~~


Regards,
Sufyan Khan
+91-9045303453
yn2000
2017-11-08 23:57:20 UTC
Reply
Permalink
Raw Message
My schedule is so disperse, but I'll join if time is permitted.
It is always a privilege and educational.
Thanks. YN.
Eddie Hartman
2017-11-10 23:46:07 UTC
Reply
Permalink
Raw Message
Post by Sufyan Khan
Post by Eddie Hartman
Post by yn2000
In case you still want to pursue the 'lazy' way and you do not like recording the transaction into a file, then I guess you can try sending the return message into the memory stream (or other method) instead.
MemoryStreamConnector.connector.initialize(responseString);
Then in the AL Feed >> MemoryStreamConnector (Iterator), you choose XML parser.
... or something like that.
Rgds. YN.
And I would want to record the session. The more the merrier :)
Eddie Sir I am done with the Adapter :), the script which you shared above was very helpful, thank you very much.
But it would be pretty Great to have a session from you on Script Connector, I AM IN.
Below is the script for reference (Here I have consumed "Test WebService" which is available for free, URL: http://www.webservicex.net/globalweather.asmx).
~~~~~~~~~~~~~~~~~~~~~~~ SCRIPT START ~~~~~~~~~~~~~~~~~~~~~~~
// Sample connector
// Place initialization code before function declarations
//
var index = 0;
var httpConn = system.getConnector("ibmdi.HTTPClient");
httpConn.initialize(null);
function selectEntries()
{
var requestEntry = system.newEntry();
requestEntry["http.Content-Type"] = 'text/xml;action="http://www.webserviceX.NET/GetCitiesByCountry"';
requestEntry["http.url"] = "http://www.webservicex.net/globalweather.asmx";
requestEntry["http.method"] = "POST";
requestEntry["http.body"] = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://www.webserviceX.NET">' +
'<soapenv:Header/>' +
'<soapenv:Body>' +
'<web:GetCitiesByCountry>' +
'<!--Optional:-->' +
'<web:CountryName>nepal</web:CountryName>' +
'</web:GetCitiesByCountry>' +
'</soapenv:Body>' +
'</soapenv:Envelope>';
var replyEntry = httpConn.queryReply(requestEntry);
var responseXML = replyEntry.getString("http.bodyAsString");
var tEntry = system.parseObject("XMLSax", responseXML);
var xmlEntry = com.ibm.di.entry.Entry.fromXML(nXML, "*", "");
nodeList = xmlEntry.getElementsByTagName("Table");
task.logmsg("INFO", "Nodelist Length: " + nodeList.getLength());
}
function getNextEntry ()
{
if (index >= nodeList.getLength()) {
result.setStatus(0); // End of data
return;
}
var node = nodeList[index];
for (var att in node) {
var attName = att.getName();
var attVal = att.getValue();
entry[attName] = attVal;
}
index++;
}
~~~~~~~~~~~~~~~~~~~~~~~ SCRIPT END ~~~~~~~~~~~~~~~~~~~~~~~
Regards,
Sufyan Khan
+91-9045303453
Nice, Sufyan. And thanks for sharing. Looks like you're on a roll with rolling your own scripted Connector. And my offer stands. What time of day works best for you? And you, YN? Meaning - what timezones are y'all in. I'm here in Norway at CET (GMT+2).
Sufyan Khan
2017-11-13 11:07:49 UTC
Reply
Permalink
Raw Message
Post by Eddie Hartman
Post by Sufyan Khan
Post by Eddie Hartman
Post by yn2000
In case you still want to pursue the 'lazy' way and you do not like recording the transaction into a file, then I guess you can try sending the return message into the memory stream (or other method) instead.
MemoryStreamConnector.connector.initialize(responseString);
Then in the AL Feed >> MemoryStreamConnector (Iterator), you choose XML parser.
... or something like that.
Rgds. YN.
And I would want to record the session. The more the merrier :)
Eddie Sir I am done with the Adapter :), the script which you shared above was very helpful, thank you very much.
But it would be pretty Great to have a session from you on Script Connector, I AM IN.
Below is the script for reference (Here I have consumed "Test WebService" which is available for free, URL: http://www.webservicex.net/globalweather.asmx).
~~~~~~~~~~~~~~~~~~~~~~~ SCRIPT START ~~~~~~~~~~~~~~~~~~~~~~~
// Sample connector
// Place initialization code before function declarations
//
var index = 0;
var httpConn = system.getConnector("ibmdi.HTTPClient");
httpConn.initialize(null);
function selectEntries()
{
var requestEntry = system.newEntry();
requestEntry["http.Content-Type"] = 'text/xml;action="http://www.webserviceX.NET/GetCitiesByCountry"';
requestEntry["http.url"] = "http://www.webservicex.net/globalweather.asmx";
requestEntry["http.method"] = "POST";
requestEntry["http.body"] = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://www.webserviceX.NET">' +
'<soapenv:Header/>' +
'<soapenv:Body>' +
'<web:GetCitiesByCountry>' +
'<!--Optional:-->' +
'<web:CountryName>nepal</web:CountryName>' +
'</web:GetCitiesByCountry>' +
'</soapenv:Body>' +
'</soapenv:Envelope>';
var replyEntry = httpConn.queryReply(requestEntry);
var responseXML = replyEntry.getString("http.bodyAsString");
var tEntry = system.parseObject("XMLSax", responseXML);
var xmlEntry = com.ibm.di.entry.Entry.fromXML(nXML, "*", "");
nodeList = xmlEntry.getElementsByTagName("Table");
task.logmsg("INFO", "Nodelist Length: " + nodeList.getLength());
}
function getNextEntry ()
{
if (index >= nodeList.getLength()) {
result.setStatus(0); // End of data
return;
}
var node = nodeList[index];
for (var att in node) {
var attName = att.getName();
var attVal = att.getValue();
entry[attName] = attVal;
}
index++;
}
~~~~~~~~~~~~~~~~~~~~~~~ SCRIPT END ~~~~~~~~~~~~~~~~~~~~~~~
Regards,
Sufyan Khan
+91-9045303453
Nice, Sufyan. And thanks for sharing. Looks like you're on a roll with rolling your own scripted Connector. And my offer stands. What time of day works best for you? And you, YN? Meaning - what timezones are y'all in. I'm here in Norway at CET (GMT+2).
Thanks Sir, that would be great.
I work in India, IST (GMT +5:30 or CET +4:30).


Regards,
Sufyan
Eddie Hartman
2017-11-13 20:00:24 UTC
Reply
Permalink
Raw Message
Post by Sufyan Khan
Post by Eddie Hartman
Post by Sufyan Khan
Post by Eddie Hartman
Post by yn2000
In case you still want to pursue the 'lazy' way and you do not like recording the transaction into a file, then I guess you can try sending the return message into the memory stream (or other method) instead.
MemoryStreamConnector.connector.initialize(responseString);
Then in the AL Feed >> MemoryStreamConnector (Iterator), you choose XML parser.
... or something like that.
Rgds. YN.
And I would want to record the session. The more the merrier :)
Eddie Sir I am done with the Adapter :), the script which you shared above was very helpful, thank you very much.
But it would be pretty Great to have a session from you on Script Connector, I AM IN.
Below is the script for reference (Here I have consumed "Test WebService" which is available for free, URL: http://www.webservicex.net/globalweather.asmx).
~~~~~~~~~~~~~~~~~~~~~~~ SCRIPT START ~~~~~~~~~~~~~~~~~~~~~~~
// Sample connector
// Place initialization code before function declarations
//
var index = 0;
var httpConn = system.getConnector("ibmdi.HTTPClient");
httpConn.initialize(null);
function selectEntries()
{
var requestEntry = system.newEntry();
requestEntry["http.Content-Type"] = 'text/xml;action="http://www.webserviceX.NET/GetCitiesByCountry"';
requestEntry["http.url"] = "http://www.webservicex.net/globalweather.asmx";
requestEntry["http.method"] = "POST";
requestEntry["http.body"] = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://www.webserviceX.NET">' +
'<soapenv:Header/>' +
'<soapenv:Body>' +
'<web:GetCitiesByCountry>' +
'<!--Optional:-->' +
'<web:CountryName>nepal</web:CountryName>' +
'</web:GetCitiesByCountry>' +
'</soapenv:Body>' +
'</soapenv:Envelope>';
var replyEntry = httpConn.queryReply(requestEntry);
var responseXML = replyEntry.getString("http.bodyAsString");
var tEntry = system.parseObject("XMLSax", responseXML);
var xmlEntry = com.ibm.di.entry.Entry.fromXML(nXML, "*", "");
nodeList = xmlEntry.getElementsByTagName("Table");
task.logmsg("INFO", "Nodelist Length: " + nodeList.getLength());
}
function getNextEntry ()
{
if (index >= nodeList.getLength()) {
result.setStatus(0); // End of data
return;
}
var node = nodeList[index];
for (var att in node) {
var attName = att.getName();
var attVal = att.getValue();
entry[attName] = attVal;
}
index++;
}
~~~~~~~~~~~~~~~~~~~~~~~ SCRIPT END ~~~~~~~~~~~~~~~~~~~~~~~
Regards,
Sufyan Khan
+91-9045303453
Nice, Sufyan. And thanks for sharing. Looks like you're on a roll with rolling your own scripted Connector. And my offer stands. What time of day works best for you? And you, YN? Meaning - what timezones are y'all in. I'm here in Norway at CET (GMT+2).
Thanks Sir, that would be great.
I work in India, IST (GMT +5:30 or CET +4:30).
Regards,
Sufyan
YN is in California I believe, so that would be +9 hours from me (CET) and +12.5 from you. Is there an evening that works for you?
Sufyan Khan
2017-11-14 06:43:24 UTC
Reply
Permalink
Raw Message
Post by Eddie Hartman
Post by Sufyan Khan
Post by Eddie Hartman
Post by Sufyan Khan
Post by Eddie Hartman
Post by yn2000
In case you still want to pursue the 'lazy' way and you do not like recording the transaction into a file, then I guess you can try sending the return message into the memory stream (or other method) instead.
MemoryStreamConnector.connector.initialize(responseString);
Then in the AL Feed >> MemoryStreamConnector (Iterator), you choose XML parser.
... or something like that.
Rgds. YN.
And I would want to record the session. The more the merrier :)
Eddie Sir I am done with the Adapter :), the script which you shared above was very helpful, thank you very much.
But it would be pretty Great to have a session from you on Script Connector, I AM IN.
Below is the script for reference (Here I have consumed "Test WebService" which is available for free, URL: http://www.webservicex.net/globalweather.asmx).
~~~~~~~~~~~~~~~~~~~~~~~ SCRIPT START ~~~~~~~~~~~~~~~~~~~~~~~
// Sample connector
// Place initialization code before function declarations
//
var index = 0;
var httpConn = system.getConnector("ibmdi.HTTPClient");
httpConn.initialize(null);
function selectEntries()
{
var requestEntry = system.newEntry();
requestEntry["http.Content-Type"] = 'text/xml;action="http://www.webserviceX.NET/GetCitiesByCountry"';
requestEntry["http.url"] = "http://www.webservicex.net/globalweather.asmx";
requestEntry["http.method"] = "POST";
requestEntry["http.body"] = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://www.webserviceX.NET">' +
'<soapenv:Header/>' +
'<soapenv:Body>' +
'<web:GetCitiesByCountry>' +
'<!--Optional:-->' +
'<web:CountryName>nepal</web:CountryName>' +
'</web:GetCitiesByCountry>' +
'</soapenv:Body>' +
'</soapenv:Envelope>';
var replyEntry = httpConn.queryReply(requestEntry);
var responseXML = replyEntry.getString("http.bodyAsString");
var tEntry = system.parseObject("XMLSax", responseXML);
var xmlEntry = com.ibm.di.entry.Entry.fromXML(nXML, "*", "");
nodeList = xmlEntry.getElementsByTagName("Table");
task.logmsg("INFO", "Nodelist Length: " + nodeList.getLength());
}
function getNextEntry ()
{
if (index >= nodeList.getLength()) {
result.setStatus(0); // End of data
return;
}
var node = nodeList[index];
for (var att in node) {
var attName = att.getName();
var attVal = att.getValue();
entry[attName] = attVal;
}
index++;
}
~~~~~~~~~~~~~~~~~~~~~~~ SCRIPT END ~~~~~~~~~~~~~~~~~~~~~~~
Regards,
Sufyan Khan
+91-9045303453
Nice, Sufyan. And thanks for sharing. Looks like you're on a roll with rolling your own scripted Connector. And my offer stands. What time of day works best for you? And you, YN? Meaning - what timezones are y'all in. I'm here in Norway at CET (GMT+2).
Thanks Sir, that would be great.
I work in India, IST (GMT +5:30 or CET +4:30).
Regards,
Sufyan
YN is in California I believe, so that would be +9 hours from me (CET) and +12.5 from you. Is there an evening that works for you?
I am a learner so time isn't a hurdle for me :), any time would be fine.

Regards,
Sufyan
yn2000
2017-11-14 20:07:09 UTC
Reply
Permalink
Raw Message
Yup, I am based in California.
Rgds. YN.

Loading...