Read an XML content

The first thing to do when reading or writing a XML file/stream, is to declare the Document interface

Include exml

#include <exml/exml.hpp>

Declare document interface

Read an XML file

File to read: "read.xml"

<?xml version="1.0" encoding="UTF-8" standalone="true"?>
<!-- my comment -->
<exml attributeExample="my data attribute">
coucou
<!-- comment -->
<subNodeA/>
<subNodeB/>
</exml>

Reading a file is done like this:

bool retParse = doc.load("DATA:read.xml");

The file naming is manage by etk::FSNode that provide "DATA:" start string for internal application asset. You can use external path like "./plop/file.xml" too.

Read an XML Stream

Reading a stream is done like this:

std::string stream = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"true\"?>"
"<!-- my comment -->"
"<exml attributeExample=\"my data attribute\">coucou</exml>";
bool retParse = doc.parse(stream);

In C and C++ it is very hard to read string with the \" then to simplify parsing of xml the parser engine support the use of simple ' interface:

std::string stream = "<?xml version='1.0' encoding='UTF-8' standalone='true'?>"
"<!-- my comment -->"
"<exml attributeExample='my data attribute'>coucou</exml>";
bool retParse = doc.parse(stream);

Access at all Element datas

In an exml::Element (or exml::Document) the sub-nodes are accessible threw an abstraction class stores in an element name nodes

Get a node with its name:

exml::Element element = doc.nodes["exml"];

Reading all file nodes:

for (const auto itElem: element.nodes) {
if (itElem.isElement() == true) {
// get the <XXXX ... name
std::string value = itElem.toElement().getValue();
TEST_INFO(" '" << value << "'");
} else {
// simple debug for other type:
TEST_INFO(" ** " << itElem);
}
}

note: the itElem is a simple exml::Node that can be all the xml type. you can change the type by calling: toDocument(), toElement(), toString() ...

In a C style mode:

for (size_t iii=0; iii<element.nodes.size(); ++iii) {
const exml::Node node = element.nodes[iii];
if (node.isElement() == true) {
// get the <XXXX ... name
std::string value = node.toElement().getValue();
TEST_INFO(" '" << value << "'");
} else {
// simple debug for other type:
TEST_INFO(" ** " << node);
}
}

In an exml::Element (or exml::Document or exml::Declaration) the sub-nodes are accessible threw an abstraction class stores in an element name attributes

Reading all Attributes of one node:

for (const auto itElem: element.attributes) {
std::string value = itElem.getValue();
TEST_INFO(" '" << value << "'");
}
TEST_INFO(" list of attribute in C:");

In a C style mode:

for (size_t iii=0; iii<element.attributes.size(); ++iii) {
const exml::Attribute attr = element.attributes[iii];
std::string value = attr.getValue();
TEST_INFO(" '" << value << "'");
}

Get an attribute data:

std::string attributeValue = element.attributes["attributeExample"];
TEST_INFO(" direct get: '" << attributeValue << "'");

In an exml::Element (or exml::Document) the internal data text can be accessible threw the interface:

Get all the data in an element in text mode:

std::string internalData = element.getText();

All example file

#include <test-debug/debug.hpp>
#include <exml/exml.hpp>
#include "read.hpp"
static void readFromFile() {
bool retParse = doc.load("DATA:read.xml");
TEST_INFO("parse ret = " << retParse);
TEST_INFO("Debug display of the tree:");
doc.display();
}
static void readFromString1() {
TEST_INFO("parse");
std::string stream = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"true\"?>"
"<!-- my comment -->"
"<exml attributeExample=\"my data attribute\">coucou</exml>";
bool retParse = doc.parse(stream);
TEST_INFO("parse ret = " << retParse);
TEST_INFO("Debug display of the tree:");
doc.display();
}
static void readFromString2() {
TEST_INFO("parse");
std::string stream = "<?xml version='1.0' encoding='UTF-8' standalone='true'?>"
"<!-- my comment -->"
"<exml attributeExample='my data attribute'>coucou</exml>";
bool retParse = doc.parse(stream);
TEST_INFO("parse ret = " << retParse);
TEST_INFO("Debug display of the tree:");
doc.display();
}
static void readFull() {
TEST_INFO("parse");
bool retParse = doc.load("DATA:read.xml");
TEST_INFO("parse ret = " << retParse);
TEST_INFO("Debug display of the tree:");
doc.display();
TEST_INFO("list of attribute:");
for (auto it: doc.attributes) {
TEST_INFO(" " << it);
}
TEST_INFO("list of sub-node:");
for (const auto it: doc.nodes) {
TEST_INFO(" " << it);
if (it.isElement() == false) {
continue;
}
exml::Element elem = it.toElement();
if (elem.exist() == false) {
continue;
}
TEST_INFO(" list of attribute:");
for (const auto itElem: elem.attributes) {
TEST_INFO(" " << itElem);
}
TEST_INFO(" list of sub-node:");
for (const auto itElem: elem.nodes) {
TEST_INFO(" " << itElem);
}
}
TEST_INFO(" Direct get node exml:");
exml::Element element = doc.nodes["exml"];
TEST_INFO(" list of attribute:");
for (const auto itElem: element.attributes) {
std::string value = itElem.getValue();
TEST_INFO(" '" << value << "'");
}
TEST_INFO(" list of attribute in C:");
for (size_t iii=0; iii<element.attributes.size(); ++iii) {
const exml::Attribute attr = element.attributes[iii];
std::string value = attr.getValue();
TEST_INFO(" '" << value << "'");
}
std::string attributeValue = element.attributes["attributeExample"];
TEST_INFO(" direct get: '" << attributeValue << "'");
TEST_INFO(" list of sub-node:");
for (const auto itElem: element.nodes) {
if (itElem.isElement() == true) {
// get the <XXXX ... name
std::string value = itElem.toElement().getValue();
TEST_INFO(" '" << value << "'");
} else {
// simple debug for other type:
TEST_INFO(" ** " << itElem);
}
}
TEST_INFO(" list of sub-node in C:");
for (size_t iii=0; iii<element.nodes.size(); ++iii) {
const exml::Node node = element.nodes[iii];
if (node.isElement() == true) {
// get the <XXXX ... name
std::string value = node.toElement().getValue();
TEST_INFO(" '" << value << "'");
} else {
// simple debug for other type:
TEST_INFO(" ** " << node);
}
}
std::string internalData = element.getText();
}
void appl::read() {
readFromFile();
readFromString1();
readFromString1();
readFull();
}