ESP32 Arduino: Parsing XML

In this tutorial we will learn how to get started parsing XML with the ESP32, using the Arduino core and the tinyxml2 library. The tests from this tutorial were done using a DFRobot’s ESP32 module integrated in a ESP32 development board.

Introduction

In this tutorial we will learn how to get started parsing XML with the ESP32, using the Arduino core.

We will be using tinyxml2, a C++ parser library. You can check here the documentation page for the library.

Before getting started, we need to install tinyxml2 as an Arduino library. The procedure is very simple.

First, you need to navigate to the Arduino libraries folder in your computer. In my case, it is located on C:\Users\MyUserName\Documents\Arduino\libraries, but yours might differ.

On the libraries folder, create a new folder called tinyxml2. After this, go to the GitHub page of the library and download the tinyxml2.cpp and the tinyxml2.h files. Finally, paste them on the tinyxml2 folder you have just created.

The tests from this tutorial were done using a DFRobot’s ESP32 module integrated in a ESP32 development board.

The code

We will start by including the newly installed library.

#include <tinyxml2.h>

Then we will declare the using of the tinyxml2 namespace. This will avoid the use of the scope resolution operator.

using namespace tinyxml2;

Followed by that we will define a string with a very simple XML document. It will contain a root element and a nested element with an integer value.

char * testDocument = "<root><element>7</element></root>";

Moving on to the Arduino setup function, we will start by opening a serial connection, so we can output the results of our program.

Serial.begin(115200);

Then we will declare an object of class XMLDocument. This object will expose to us the methods we need to parse the document.

XMLDocument xmlDocument;

To parse the content, we simply need to call the Parse method on the XMLDocument, passing as input the string with the document.

This method can receive as second optional parameter the number of bytes to be parsed. If nothing is specified (like in the code below), then the library assumes that we are passing a null terminated string.

Note that this method will return XML_SUCCESS in case the parsing is successful, or an error ID in case any problem occurs. We will use this return value for error checking.

if(xmlDocument.Parse(testDocument)!= XML_SUCCESS){
    Serial.println("Error parsing");  
    return;
};

The XMLDocument class inherits from XMLNode, which has a method called FirstChild that returns the first child node (or null in case it doesn’t exist). We will call this method to obtain the root node. Note that the method returns a pointer to an object of class XMLNode.

XMLNode * root = xmlDocument.FirstChild();

Now that we have the root note, we will obtain its child element (the one that contains the data). We do this with a call to the FirstChildElement method.

Note that, when we pass no parameters, this method returns the first child element but, if we pass a string as input, it will return the first child element that has a name equal to that string.

We are going to follow this second approach for illustration purposes, even though our node only has one child element. Note that this method will return a pointer to a XMLElement object.

XMLElement * element = root->FirstChildElement("element");

Finally, to obtain the value of the element, we can use the QueryIntText method of our XMLElement. This method receives as input a pointer to an integer, where the value will be stored.

int val;
element->QueryIntText(&val);

After we obtain the value, we will print it to the serial port.

Serial.println(val);

The final complete code can be seen below.

#include <tinyxml2.h>

using namespace tinyxml2;

char * testDocument = "<root><element>7</element></root>";

void setup() {
    
  Serial.begin(115200);
  
  XMLDocument xmlDocument;

  if(xmlDocument.Parse(testDocument)!= XML_SUCCESS){
    Serial.println("Error parsing"); 
    return; 
  };

  XMLNode * root = xmlDocument.FirstChild();
  XMLElement * element = root->FirstChildElement("element");

  int val;
  element->QueryIntText(&val);
  
  Serial.println(val);
}

void loop() {}

Testing the code

To test the code, simply compile it and upload it to your device using the Arduino IDE. Once the procedure finishes, open the Arduino IDE serial monitor.

You should get a result similar to figure 1. As can be seen, we obtain the value 7, which was the expected value from the XML document.

Output of the program, showing the obtained integer from the parsed XML.
Figure 1 – Output of the program, showing the obtained integer from the parsed XML.

Leave a Reply