jsonnode.jsxmlxmldom

How to parse JSON created from XML response of SOAP WS?


I need help in parsing a JSON created from an XML response of a SOAP web-service in NodeJS. I want a JSON array of notifications.

XML is as below:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <ns2:getNotificationsResponse xmlns:ns2="---url---">
         <return>
            <notifications>
               <ackRequired>false</ackRequired>
               <body>Testing Notitfications</body>
               <created>1498798404874</created>
               <gpsAlt>1.0</gpsAlt>
               <gpsLat>1.0</gpsLat>
               <gpsLong>1.0</gpsLong>
               <messageId>253</messageId>
               <priority>INFORMATIONAL</priority>
               <senderClientId>PMC0</senderClientId>
               <status>SENT</status>
               <subject>Test Notification</subject>
               <updated>1498798404874</updated>
               <userId>1</userId>
               <userLogin>ipics</userLogin>
            </notifications>
            <notifications>
               <ackRequired>false</ackRequired>
               <body>Test notitfication</body>
               <created>1498797535714</created>
               <gpsAlt>0.0</gpsAlt>
               <gpsLat>0.0</gpsLat>
               <gpsLong>0.0</gpsLong>
               <messageId>244</messageId>
               <priority>HIGH</priority>
               <senderClientId>PMC_1234</senderClientId>
               <status>SENT</status>
               <subject>Test</subject>
               <updated>1498797535714</updated>
               <userId>1</userId>
               <userLogin>ipics</userLogin>
            </notifications>
            <notifications>
               <ackRequired>false</ackRequired>
               <body>Testing Notitfications</body>
               <created>1498794764538</created>
               <gpsAlt>1.0</gpsAlt>
               <gpsLat>1.0</gpsLat>
               <gpsLong>1.0</gpsLong>
               <messageId>239</messageId>
               <priority>INFORMATIONAL</priority>
               <senderClientId>PMC0</senderClientId>
               <status>SENT</status>
               <subject>Test Notification</subject>
               <updated>1498794764538</updated>
               <userId>1</userId>
               <userLogin>ipics</userLogin>
            </notifications>
            <notifications>
               <ackRequired>false</ackRequired>
               <body>Testing Notitfications</body>
               <created>1498794760123</created>
               <gpsAlt>1.0</gpsAlt>
               <gpsLat>1.0</gpsLat>
               <gpsLong>1.0</gpsLong>
               <messageId>234</messageId>
               <priority>INFORMATIONAL</priority>
               <senderClientId>PMC0</senderClientId>
               <status>SENT</status>
               <subject>Test Notification</subject>
               <updated>1498794760123</updated>
               <userId>1</userId>
               <userLogin>ipics</userLogin>
            </notifications>
         </return>
      </ns2:getNotificationsResponse>
   </soap:Body>
</soap:Envelope>

I'm using xmldom node module.
My code is as follows, but it doesn't give a proper response.

var doc = new DOMParser().parseFromString(data.response, 'text/xml');
var valueXML = doc.getElementsByTagName('return');
var temp = valueXML[0].getElementsByTagName("notifications")[0];
var output = temp.getElementsByTagName("nextSibling")._node.childNodes.parentNode

Solution

  • const transform = require('camaro')
    const fs = require('fs')
    
    const xml = fs.readFileSync('so.xml', 'utf-8')
    const template = {
        notifications: ['//notifications', {
            ackRequired: 'ackRequired',
            body: 'body',
            created: 'created',
            gpsAlt: 'number(gpsAlt)'
        }]
    }
    
    const result = transform(xml, template)
    console.log(JSON.stringify(result, null, 2))
    

    And output:

    {
      "notifications": [
        {
          "ackRequired": "false",
          "body": "Testing Notitfications",
          "created": "1498798404874",
          "gpsAlt": 1
        },
        {
          "ackRequired": "false",
          "body": "Test notitfication",
          "created": "1498797535714",
          "gpsAlt": 0
        },
        {
          "ackRequired": "false",
          "body": "Testing Notitfications",
          "created": "1498794764538",
          "gpsAlt": 1
        },
        {
          "ackRequired": "false",
          "body": "Testing Notitfications",
          "created": "1498794760123",
          "gpsAlt": 1
        }
      ]
    }
    

    I just add a few fields in template to test. You can add more base on what you need.