Node.js xml2js http.request标记匹配

时间:2017-10-20 14:52:44

标签: javascript node.js xml xml2js

我正在尝试使用https.request中的XML数据并以表格格式显示到网页。我正在尝试按照本教程描述我想要做的非常好:https://programmerblog.net/parse-xml-using-nodejs/

但是,我在过滤XML结果时遇到了问题。

这是我的代码:

// 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();
  });
}

我特意收到以下控制台错误。

TypeError: Cannot read property 'ns' of undefined
    at C:\Users\PetersonA16\Desktop\listlineapp\listlineapp\routes\cucmmapper.js:68:39

以下结果:

console.log(soapreplyx);

回复此(已编辑)数据。

<?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>

如果我取消注释掉该行:

console.dir(result);

我得到以下控制台输出:

{ 'soapenv:Envelope':
   { '$': { 'xmlns:soapenv': 'http://schemas.xmlsoap.org/soap/envelope/' },
     'soapenv:Body': [ [Object] ] } }

我的理论是我需要使用xml2js选项。经过一些实验,我未能取得任何进展。

我还是JS的新手,所以非常感谢任何帮助,指针或建议!

2 个答案:

答案 0 :(得分:0)

如果你想获得所有的css节点,你可以尝试这个

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)

输出:

[ { clause: 'something1',
    description: 'description1',
    name: 'name1',
    uuid: '{E85C54E1-5737-7516-FFFC-14E97B1D0504}' },
  { clause: 'something2',
    description: 'description2',
    name: 'name2',
    uuid: '{AFFC55A7-CD16-E250-09E8-9A12ABBE0C9E}' } ]

答案 1 :(得分:0)

作为一个说明,我确实让它与xml2js一起工作。这是我的代码。

// 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 = '';
    var spacer = '-----';
    var rmline1 = '';
    var rmline2 = '';
    var rmline3 = '';
    var rmline4 = '';
    var rmbottomup1 = '';
    var rmbottomup2 = '';
    var rmbottomup3 = '';

    // 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', () => {

        // EDIT - SCRUB XML OUTPUT
        var rmline1 = soapreplyx.replace(/<\?xml\sversion='1\.0'\sencoding='utf-8'\?>/g, '');
        var rmline2 = rmline1.replace(/<soapenv:Envelope\sxmlns:soapenv="http:\/\/schemas.xmlsoap.org\/soap\/envelope\/">/g, '');
        var rmline3 = rmline2.replace(/<soapenv:Body>/g, '');
        var rmline4 = rmline3.replace(/<ns:listCssResponse\sxmlns:ns="http:\/\/www\.cisco\.com\/AXL\/API\/[0-9]*\.[0-9]">/g, '');
        var rmbottomup1 = rmline4.replace(/<\/soapenv:Envelope>/g, '');
        var rmbottomup2 = rmbottomup1.replace(/<\/soapenv:Body>/g, '');
        var xmlscrubbed = rmbottomup2.replace(/<\/ns:listCssResponse>/g, '');
        // console.log(xmlscrubbed);
        // console.log(spacer);

        // XML2JS - TESTING
        parser.parseString(xmlscrubbed, function (err, result) {
          var cssx = result['return']['css'];
        //   console.log(cssx);
        //   console.log(spacer);
          res.render('cucmmapper-results.html', {
            title: 'CUCM 2.0',
            cucmpub: cucmpub,
            cssx: cssx,
            soapreply: soapreplyx,
            xmlscrubbed: xmlscrubbed
          });
        });
      });
    });

    // SOAP - SEND AXL CALL
    soapRequest.write(soapBody);
    soapRequest.end();
  });
}

这是我的HTML表格。

<div class="row">
                    <div class="col-md-12" class="pull-left">
                        <table class="table table-hover table-condensed">
                            <thread>
                                <tr>
                                    <th>CSS</th>
                                    <th>DESCRIPTION</th>
                                    <th>PARTITIONS</th>
                                </tr>
                            </thread>
                            <tbody>
                                {{#each cssx}}
                                <tr>
                                    <td>{{this.name}}</td>
                                    <td>{{this.description}}</td>
                                    <td>{{this.clause}}</td>
                                </tr>
                                {{/each}}
                            </tbody>
                        </table>
                    </div>
                </div>