← coderrocketfuel.com

Parse, Edit, & Write Changes to XML Files With Node.js

This article will show you how to read, parse and make updates to an Extensible Markup Language (XML) file with Node.js. We'll be using the xml2json NPM package to parse the XML.

Let's get started!

Table of Contents

What is XML?

XML is a markup language (HTML is also a markup language) that gives a set of rules for encoding files in a format that can be read efficiently by both humans and machines. It was designed with simplicity and usability.

Its most widely used application is for sitemaps. Sitemaps are used to tell search engines about the pages and structure of a website. These are commonly written in XML because it is easy to use and easy for Google and Bing's search engines to read and parse the data.

That was a quick and dirty explanation of XML. If you want more information, here are some good sources for you to check out:

Set Up Project

Before we start writing code, let's set up our project folder.

Above anything else, you'll need Node.js installed if you don't have it already.

If you need one, we created a guide on installing Node.js.

Create Project Folder

Let's quickly create a directory for our code:

mkdir xml-nodejs

And then cd into your new directory:

cd xml-nodejs

NPM Init & Install Dependencies

Next, run npm init to create a package.json file that will hold the configuration for our code:

npm init

Then you can install the xml2json and xml-formatter packages we will be using later on:

npm install xml2json xml-formatter --save

Create Index.js File

Next, create the index.js file where the meat of our code will reside:

touch index.js

We will come back to this file later. But for now, you can keep it empty.

Next, create an XML file in the root of your project that we will use for testing purposes:

touch data.xml

And fill the file with this XML content:

<breakfast_menu>
  <food id="1">
    <name>Belgian Waffles</name>
    <price>$5.95</price>
    <description>Two of our famous Belgian Waffles with plenty of real maple syrup</description>
    <calories>650</calories>
  </food>
  <food id="2">
    <name>Strawberry Belgian Waffles</name>
    <price>$7.95</price>
    <description>Light Belgian waffles covered with strawberries and whipped cream</description>
    <calories>900</calories>
  </food>
  <food id="3">
    <name>Berry-Berry Belgian Waffles</name>
    <price>$8.95</price>
    <description>Light Belgian waffles covered with an assortment of fresh berries and whipped cream</description>
    <calories>900</calories>
  </food>
</breakfast_menu>

We now have a project setup with a test XML file. Now we are ready to start parsing and editing our XML file.

Parse The XML File

First, let's read the data.xml file, which should be in the root directory of your folder. All we need to do is import the fs package and use the readFile function.

Open your index.js file and add the following code to it:

const fs = require("fs")
const xmlParser = require("xml2json")

fs.readFile( "./data.xml", function(err, data) {
  const xmlObj = xmlParser.toJson(data, {reversible: true, object: true})
  console.log(xmlObj)
})

The first two lines of the file import the fs and xml2json NPM packages for use. Then, we use the fs.readFile to read the XML file and return its data. Once we have the XML data, we use the xml2json package to transform the XML into a JavaScript object.

The reversible option will allow us to switch the object back to XML later on. And the object option returns the XML as a JavaScript object instead of a JSON string. And the console.log line will print the result to the command line.

To test the code, run the node index.js command:

node index.js

You should see an output similar to this:

{ breakfast_menu: { food: [ [Object], [Object], [Object] ] } }

Make Edits to the XML Object

We are now ready to make edits to the xmlObj. For testing purposes, lets find the food item with an id value equal to "3" and update its name to something different.

To acheive this, make the following updates to the conents of the index.js file:

const fs = require("fs")
const xmlParser = require("xml2json")

fs.readFile( "./data.xml", function(err, data) {
  const xmlObj = xmlParser.toJson(data, {reversible: true, object: true})
  const foodItemsArray = xmlObj["breakfast_menu"]["food"]

  for (let i = 0; i < foodItemsArray.length; i++) {
    if (foodItemsArray[i].id === "3") {
      xmlObj["breakfast_menu"]["food"][i].name.$t = "Belgian Waffles with Assorted Berries"
    }
  }
})

The first thing we added is a foodItemsArray that holds the array of objects of all the food items. Then, we loop through each of the food items and update the name of the item with an id of "3".

Write Changes to The XML File

Now we are ready to write the changes to the data.xml file using the fs module again.

Update the index.js file to look like this:

const fs = require("fs")
const xmlParser = require("xml2json")
const formatXml = require("xml-formatter")

fs.readFile( "./data.xml", function(err, data) {
  const xmlObj = xmlParser.toJson(data, {reversible: true, object: true})
  const foodItemsArray = xmlObj["breakfast_menu"]["food"]

  for (let i = 0; i < foodItemsArray.length; i++) {
    if (foodItemsArray[i].id === "3") {
      xmlObj["breakfast_menu"]["food"][i].name.$t = "Belgian Waffles with Assorted Berries"
    }
  }

  const stringifiedXmlObj = JSON.stringify(xmlObj)
  const finalXml = xmlParser.toXml(stringifiedXmlObj)

  fs.writeFile("./data.xml", formatXml(finalXml, {collapseContent: true}), function(err, result) {
    if (err) {
      console.log("err")
    } else {
      console.log("Xml file successfully updated.")
    }
  })
})

We just made several changes to our index.js file so let's go over them.

First, we added a new package called xml-formatter that will be used to format the XML we write to the file later on in our code. Next, we created the stringifiedXmlObj variable that transforms our xmlObj into a JSON string. And we created our finalXml variable by using xml2json package to switch the JSON back into an XML string.

At this point, we have the new XML data we want to write to the data.xml file. So, we then use the fs package to write the new XML data to the file. Notice we use the xml-formatter package to make our xml data more human-readable.