XML Parsing in JavaScript With xml2js

Most web APIs these days are JSON APIs. JSON is fantastic, and very easy to work with. However older web APIs still use XML, and that can be a problem when you’re a JavaScript developer. Using the xml2js package, we can convert an XML string to a JavaScript object – making our lives much easier as JavaScript developers.

<?xml version="1.0" encoding="utf-8"?>
<GetDataResponse>
    <ResponseStatus>Success</ResponseStatus>
    <Records>
        <Record>
            <CompanyID>42</CompanyID>
            <CompanyName>Apple</CompanyName>
            <CompanyCountry>US</CompanyCountry>
        </Record>
        <Record>
            <CompanyID>53</CompanyID>
            <CompanyName>Google</CompanyName>
            <CompanyCountry>US</CompanyCountry>
        </Record>
        <Record>
            <CompanyID>64</CompanyID>
            <CompanyName>Alibaba</CompanyName>
            <CompanyCountry>CH</CompanyCountry>
        </Record>
    </Records>
</GetDataResponse>
/***************************************************
***  Step 1: Import libraries
***************************************************/
const fetch = require('node-fetch');
const xml2js = require('xml2js');

/***************************************************
***  Step 2: Convert parseString to a promise
***          (optional but recommended)
***************************************************/
function XMLStringToObject(string) {
  return new Promise((resolve, reject) => {
    xml2js.parseString(string, (err, result) => {
      if (err) reject(err);
      
      return resolve(result);
    });
  });
}

/***************************************************
***  Step 3: Format API response
***
***  Before:
***    [{
***      CompanyCountry: ["US"],
***      CompanyID: ["42"],
***      CompanyName: ["Apple"]
***    }]
***    
***  After:
***    [{
***      CompanyCountry: "US",
***      CompanyID: "42",
***      CompanyName: "Apple"
***    }]
***************************************************/
function formatAPIResponse(records) {
  return new Promise((resolve, reject) => {
    let formattedRecords = [];
    
    records.forEach(record => {
      let formattedRecord = {};
      
      Object.keys(record).map(key => (formattedRecord[key] = record[key][0]));
      
      formattedRecords.push(formattedRecord);
    });
    
    resolve(formattedRecords);
  });
}

/***************************************************
***  Step 4: Make API call and print final object
***************************************************/
const options = {
  method: 'GET',
  headers: { 'content-type': 'application/xml' },
}
const url = 'input.xml';

fetch(url, options)
  .then(res => res.text())
  // Convert the XML string to an object
  .then(XMLStringToObject)
  // Just return the records array that we care about
  .then(res => res.GetDataResponse.Records[0].Record)
  // Format records
  .then(formatAPIResponse)
  .then(console.log)
  .catch(console.error);

Recommended reading: