a firstworks project
Rudiments
About Documentation Download Licensing News

Using the xmldom and domnode classes

The xmldom and domnode classes provide a framework for DOM parsing of XML documents. The xmldom class provides methods for parsing the document and accessing it's root node. Each node of the document is represented by an instance of the domnode class. The domnode class provides methods for accessing a node's data, attributes, child nodes, parent nodes and sibling nodes. Since the xmldom class creates a representation of the XML document in memory, it should not be used to process arbitrarily large documents which could exhaust system memory.

The following program parses an XML string containing a list of animals, accesses the root node, looks up an attribute by path, walks the tree manually to print each animal's name, type, number of legs, and whether it is domestic, and writes the XML tree back to standard output.

#include <rudiments/xmldom.h>
#include <rudiments/domnode.h>
#include <rudiments/stdio.h>

int main(int argc, const char **argv) {

	xmldom	xml;

	// parse an xml string
	xml.parseString(
		"<animals>"
		"  <animal type=\"mammal\">"
		"    <name>dog</name>"
		"    <legs>4</legs>"
		"    <domestic>yes</domestic>"
		"  </animal>"
		"  <animal type=\"bird\">"
		"    <name>eagle</name>"
		"    <legs>2</legs>"
		"    <domestic>no</domestic>"
		"  </animal>"
		"  <animal type=\"reptile\">"
		"    <name>snake</name>"
		"    <legs>0</legs>"
		"    <domestic>no</domestic>"
		"  </animal>"
		"</animals>");


	// get the root node and first child
	domnode	*root=xml.getRootNode();
	stdoutput.printf("root: %s\n\n",root->getFirstTagChild()->getName());


	// access nodes by path
	const char	*name=xml.getAttributeValueByPath(
						"/animals/animal","type");
	stdoutput.printf("first animal type: %s\n\n",name);


	// walk the tree manually
	stdoutput.write("all animals:\n");
	domnode	*animals=root->getFirstTagChild();
	for (domnode *animal=animals->getFirstTagChild("animal");
			!animal->isNullNode();
			animal=animal->getNextTagSibling("animal")) {

		// get the type attribute
		const char	*type=animal->getAttributeValue("type");

		// get the name child's text
		domnode	*namenode=animal->getFirstTagChild("name");
		const char	*aname=
			namenode->getFirstChild()->getValue();

		// get the legs child's text
		domnode	*legsnode=animal->getFirstTagChild("legs");
		const char	*legs=
			legsnode->getFirstChild()->getValue();

		// get the domestic child's text
		domnode	*domesticnode=animal->getFirstTagChild("domestic");
		const char	*domestic=
			domesticnode->getFirstChild()->getValue();

		stdoutput.printf("  %s (%s) - %s legs - domestic: %s\n",
						aname,type,legs,domestic);
	}
	stdoutput.write('\n');


	// write the xml tree to standard output
	stdoutput.write("xml output:\n");
	xml.writeXml(true);
	stdoutput.write('\n');
}

Here is the output of the program above.

root: animals

first animal type: mammal

all animals:
  dog (mammal) - 4 legs - domestic: yes
  eagle (bird) - 2 legs - domestic: no
  snake (reptile) - 0 legs - domestic: no

xml output:
<animals>  <animal type="mammal">    <name>dog</name>    <legs>4</legs>    <domestic>yes</domestic>  </animal>  <animal type="bird">    <name>eagle</name>    <legs>2</legs>    <domestic>no</domestic>  </animal>  <animal type="reptile">    <name>snake</name>    <legs>0</legs>    <domestic>no</domestic>  </animal></animals>
Copyright 2017 - David Muse - Contact