I am trying to work with XML data from an https.request and display it to a web page in table format. I'm trying to follow this tutorial which describes what I would like to do very well: https://programmerblog.net/parse-xml-using-nodejs/
However, I am having an issue filtering the results of XML.
Here is my code:
// MODULES - INCLUDES
var xml2js = require('xml2js');
var parser = new xml2js.Parser();
module.exports = function (app) {
// FORM - SUBMIT - CUCMMAPPER
app.post('/cucmmapper/submit', function (req, res) {
// FORM - DATA COLLECTION
var cucmpub = req.body.cucmpub;
var cucmversion = req.body.cucmversion;
var username = req.body.username;
var password = req.body.password;
// JS - VARIABLE DEFINITION
var authentication = username + ":" + password;
var soapreplyx = '';
var cssx = '';
// HTTP.REQUEST - BUILD CALL
var https = require("https");
var headers = {
'SoapAction': 'CUCM:DB ver=' + cucmversion + ' listCss',
'Authorization': 'Basic ' + new Buffer(authentication).toString('base64'),
'Content-Type': 'text/xml; charset=utf-8'
};
// SOAP - AXL CALL
var soapBody = new Buffer('<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://www.cisco.com/AXL/API/11.5">' +
'<soapenv:Header/>' +
'<soapenv:Body>' +
'<ns:listCss sequence="?">' +
'<searchCriteria>' +
'<name>%</name>' +
'</searchCriteria>' +
'<returnedTags uuid="?">' +
'<name>?</name>' +
'<description>?</description>' +
'<clause>?</clause>' +
'</returnedTags>' +
'</ns:listCss>' +
'</soapenv:Body>' +
'</soapenv:Envelope>');
// HTTP.REQUEST - OPTIONS
var options = {
host: cucmpub, // IP ADDRESS OF CUCM PUBLISHER
port: 8443, // DEFAULT CISCO SSL PORT
path: '/axl/', // AXL URL
method: 'POST', // AXL REQUIREMENT OF POST
headers: headers, // HEADER VAR
rejectUnauthorized: false // REQUIRED TO ACCEPT SELF-SIGNED CERTS
};
// HTTP.REQUEST - Doesn't seem to need this line, but it might be useful anyway for pooling?
options.agent = new https.Agent(options);
// HTTP.REQUEST - OPEN SESSION
let soapRequest = https.request(options, soapResponse => {
soapResponse.setEncoding('utf8');
soapResponse.on('data', chunk => {
soapreplyx += chunk
});
// HTTP.REQUEST - RESULTS + RENDER
soapResponse.on('end', () => {
console.log(soapreplyx);
parser.parseString(soapreplyx, function (err, result) {
// console.dir(result);
var cssx = result['soapenv']['ns']['return']['css'];
console.log(cssx);
res.render('cucmmapper-results.html', {
title: 'CUCM 2.1',
soapreply: soapreplyx,
css: cssx,
});
});
});
});
// SOAP - SEND AXL CALL
soapRequest.write(soapBody);
soapRequest.end();
});
}
I am specifically getting the following console error.
TypeError: Cannot read property 'ns' of undefined
at C:\Users\PetersonA16\Desktop\listlineapp\listlineapp\routes\cucmmapper.js:68:39
The result of the following:
console.log(soapreplyx);
Replies back with this (edited) data.
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns:listCssResponse xmlns:ns="http://www.cisco.com/AXL/API/11.0">
<return>
<css uuid="{E85C54E1-5737-7516-FFFC-14E97B1D0504}">
<description>description1</description>
<clause>something1</clause>
<name>name1</name>
</css>
<css uuid="{AFFC55A7-CD16-E250-09E8-9A12ABBE0C9E}">
<description>description2</description>
<clause>something2</clause>
<name>name2</name>
</css>
</return>
</ns:listCssResponse>
</soapenv:Body>
</soapenv:Envelope>
If I un-comment out the line:
console.dir(result);
I do get the following console output:
{ 'soapenv:Envelope':
{ '$': { 'xmlns:soapenv': 'http://schemas.xmlsoap.org/soap/envelope/' },
'soapenv:Body': [ [Object] ] } }
My theory is that I need to use an xml2js option. After some experimentation though, I haven't been able to make any headway.
I'm still new to JS, so any help, pointer, or suggestions would be greatly appreciated!
if you want to get all css nodes, you can try this
const transform = require('camaro')
const xml = `
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns:listCssResponse xmlns:ns="http://www.cisco.com/AXL/API/11.0">
<return>
<css uuid="{E85C54E1-5737-7516-FFFC-14E97B1D0504}">
<description>description1</description>
<clause>something1</clause>
<name>name1</name>
</css>
<css uuid="{AFFC55A7-CD16-E250-09E8-9A12ABBE0C9E}">
<description>description2</description>
<clause>something2</clause>
<name>name2</name>
</css>
</return>
</ns:listCssResponse>
</soapenv:Body>
</soapenv:Envelope>
`
const json = transform(xml, {
css: ['//css', {
uuid: '@uuid',
name: 'name',
description: 'description',
clause: 'clause'
}]
})
console.log(json.css)
Output:
[ { clause: 'something1',
description: 'description1',
name: 'name1',
uuid: '{E85C54E1-5737-7516-FFFC-14E97B1D0504}' },
{ clause: 'something2',
description: 'description2',
name: 'name2',
uuid: '{AFFC55A7-CD16-E250-09E8-9A12ABBE0C9E}' } ]