XMLStorage - eine leichtgewichtige XML-Library für C++ und Java (current version: 1.4)

Die XMLStorage-Library erlaubt auf recht einfache Weise, XML-Files zu verarbeiten. Es ist sowohl möglich, XML-Files einzulesen, also auch modifiziert oder komplett neu aufgebaut zu schreiben. Die Library steht sowohl in einer C++-Version als auch in einer funktional weitgehend identischen Java-Implementation zur Verfügung.

Features

Konzept
Der Inhalt einer XML-Datei ("Dokument" genannt) wird in einer aus Knoten bestehenden, baumförmigen Datenstruktur innerhalb des Speichers verwaltet. Um innerhalb des Baums zu navigieren, wird ein entsprechender Iterator verwendet. Zum Zugriff auf Dateninhalte der Knoten existieren vordefinierte Datentypkonverter.

Implementation
Der Inhalt einer XML-Datei wird in die Klasse XMLDoc eingelesen, und dort als baumförmige Strukur von verketteten XMLNode-Objekten verwaltet. Die Klasse XMLPos wird vergleichbar einem Iterator verwendet, um innerhalb des XML-Baums zu navigieren. Sämtliche Klassen der Library sind im Namespace XMLStorage gekapselt. Zusätzliche Iterator-Klassen wie XMLNode::Children und  XMLChildrenFilter erlauben, die Kindelemente eines Knotens innerhalb einer for-Schleife anzusprechen und dabei bei Bedarf eine Vorfilterung durchzuführen. Beim Zugriff auf in den Knoten gespeicherte Daten können Klasen wie XMLBool und XMLInt verwendet werden, um automatische Datentypkonvertierungen durchzuführen.

XMLStorage/C++ Quellcode-Dokumentation

XMLStorage/D Quellcode-Dokumentation

XMLStorage/Java Quellcode-Dokumentation


Beispiele

Die folgende drei kleinen Beispielsprogramme zeigen, wie eine komplett neue XML-Datei erzeugt, und anschließend wieder eingelesen wird, wobei jeweils verschiedene Teilaspakte der Library-Nutzung beleuchtet werden. Zunächst ist die erzeugte XML-Datei zu sehen. Anschließend folgt jeweils der Beispielscode in der Variante für die Sprachen C++ und Java.


1.) 

[example1.xml]
<?xml version="1.0" encoding="UTF-8"?>
<PARAMS>
 <TEXT>Testgruppe</TEXT>
 <COLOR>
 <RED>234</RED>
 <GREEN>22</GREEN>
 <BLUE>33</BLUE>
 </COLOR>
 <FONT>
 <FONT_FILENAME>Arial.ttf</FONT_FILENAME>
 <SIZE>12</SIZE>
 </FONT>
</PARAMS>

[example1.cpp]

#include <xmlstorage.h>
using namespace XMLStorage;

#include <iostream>
using namespace std;


void test_write()
{
	XMLDoc doc;
	XMLPos pos(&doc);

	 // Zusammenstellen der XML-Struktur im Dokument 'doc'
	pos.create("PARAMS");
	  pos.create("TEXT");
		pos->set_content("Testgruppe");
	  pos.back(); // </TEXT>

	  pos.create("COLOR");
		pos.create("RED");
		pos->set_content("234");
		pos.back(); // </RED>

		pos.create("GREEN");
		pos->set_content("22");
		pos.back(); // </GREEN>

		pos.create("BLUE");
		pos->set_content("33");
		pos.back(); // </BLUE>
	  pos.back(); // </COLOR>

	  pos.create("FONT");
		pos.create("FONT_FILENAME");
		pos->set_content("Arial.ttf");
		pos.back(); // </FONT_FILENAME>

		pos.create("SIZE");
		pos->set_content("12");
		pos.back(); // </SIZE>
	  pos.back(); // </FONT>
	pos.back(); // </PARAMS>

	 // Schreiben der XML-Datei
	doc.write("example1.xml");
}


void test_read()
{
	XMLDoc doc;

	 // Einlesen des XML-Files
	doc.read("example1.xml");

	XMLPos pos(&doc);
	string filename;

	 // Abfrage eines Elementinhalts, beispielsweise von FONT_FILENAME
	if (pos.go("PARAMS/FONT/FONT_FILENAME")) {
		filename = pos->get_content();
		pos.back();
	}

	 // Ausgabe des ermittelten Werts
	cout << "font filename: " << filename << '\n';
}


int main()
{
	test_write();
	test_read();

	return 0;
}

[Example1.java]

import java.io.IOException;

import de.mfuchs.xmlstorage.XMLDoc;
import de.mfuchs.xmlstorage.XMLPos;

public class Example1
{
	static void test_write() throws IOException
	{
		XMLDoc doc = new XMLDoc();
		XMLPos pos = new XMLPos(doc);

		 // Zusammenstellen der XML-Struktur im Dokument 'doc'
		pos.create("PARAMS");
		  pos.create("TEXT");
			pos.setContent("Testgruppe");
		  pos.back(); // </TEXT>

		  pos.create("COLOR");
			pos.create("RED");
			pos.setContent("234");
			pos.back(); // </RED>

			pos.create("GREEN");
			pos.setContent("22");
			pos.back(); // </GREEN>

			pos.create("BLUE");
			pos.setContent("33");
			pos.back(); // </BLUE>
		  pos.back(); // </COLOR>

		  pos.create("FONT");
			pos.create("FONT_FILENAME");
			pos.setContent("Arial.ttf");
			pos.back(); // </FONT_FILENAME>

			pos.create("SIZE");
			pos.setContent("12");
			pos.back(); // </SIZE>
		  pos.back(); // </FONT>
		pos.back(); // </PARAMS>

		 // Schreiben der XML-Datei
		doc.write("example1.xml");
	}


	static void test_read() throws Exception
	{
		XMLDoc doc = new XMLDoc();

		 // Einlesen des XML-Files
		doc.read("example1.xml");

		XMLPos pos = new XMLPos(doc);
		String filename = "";

		 // Abfrage eines Elementinhalts, beispielsweise von FONT_FILENAME
		if (pos.go("PARAMS/FONT/FONT_FILENAME")) {
			filename = pos.getContent();
			pos.back();
		}

		 // Ausgabe des ermittelten Werts
		System.out.println("font filename: " + filename);
	}

	public static void main(String[] args)
	{
		try {
			test_write();
			test_read();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
}

2.)

[example2.xml]

<?xml version="1.0" encoding="UTF-8"?>
<PARAMS text="Testgruppe">
 <COLOR blue="33" green="22" red="234"/>
 <FONT font_filename="Arial.ttf" size="12"/>
</PARAMS>

[example2.cpp]

#include <xmlstorage.h>
using namespace XMLStorage;

#include <iostream>
using namespace std;


void test_write()
{
	XMLDoc doc;
	XMLPos pos(&doc);

	 // Zusammenstellen der XML-Struktur im Dokument 'doc'
	pos.create("PARAMS");
	  pos["text"] = "Testgruppe";

	  pos.create("COLOR");
		pos["red"] = XMLInt(234);
		pos["green"] = XMLInt(22);
		pos["blue"] = XMLInt(33);
	  pos.back(); // </COLOR>

	  pos.create("FONT");
		pos["font_filename"] = "Arial.ttf";
		pos["size"] = XMLInt(12);
		pos.back(); // </SIZE>
	  pos.back(); // </FONT>
	pos.back(); // </PARAMS>

	 // Schreiben der XML-Datei
	doc.write("example2.xml");
}


void test_read()
{
	XMLDoc doc;

	 // Einlesen des XML-Files
	doc.read("example2.xml");

	XMLPos pos(&doc);
	string filename;

	 // Abfrage eines Attributwerts, beispielsweise von "font_filename"
	if (pos.go("PARAMS/FONT")) {
		filename = pos["font_filename"];
		pos.back();
	}

	 // Ausgabe des ermittelten Werts
	cout << "font filename: " << filename << '\n';
}


int main()
{
	test_write();
	test_read();

	return 0;
}

[Example2.java]

import java.io.IOException;

import de.mfuchs.xmlstorage.XMLDoc;
import de.mfuchs.xmlstorage.XMLIntRef;
import de.mfuchs.xmlstorage.XMLPos;
import de.mfuchs.xmlstorage.XMLStringRef;

public class Example2
{
	static void test_write() throws IOException
	{
		XMLDoc doc = new XMLDoc();
		XMLPos pos = new XMLPos(doc);

		 // Zusammenstellen der XML-Struktur im Dokument 'doc'
		pos.create("PARAMS");
		  pos.put("text", "Testgruppe");

		  pos.create("COLOR");
			new XMLIntRef(pos.cur(), "red").assign(234);
			new XMLIntRef(pos.cur(), "green").assign(22);
			new XMLIntRef(pos.cur(), "blue").assign(33);
		  pos.back(); // </COLOR>

		  pos.create("FONT");
			new XMLStringRef(pos.cur(), "font_filename").assign("Arial.ttf");
			new XMLIntRef(pos.cur(), "size").assign(12);
			pos.back(); // </SIZE>
		  pos.back(); // </FONT>
		pos.back(); // </PARAMS>

		 // Schreiben der XML-Datei
		doc.write("example2.xml");
	}


	static void test_read() throws Exception
	{
		 // Einlesen des XML-Files
		XMLDoc doc = new XMLDoc("example2.xml");

		XMLPos pos = new XMLPos(doc);
		String filename = "";

		 // Abfrage eines Attributwerts, beispielsweise von "font_filename"
		if (pos.go("PARAMS/FONT")) {
			filename = pos.get("font_filename");
			pos.back();
		}

		 // Ausgabe des ermittelten Werts
		System.out.println("font filename: " + filename);
	}

	public static void main(String[] args)
	{
		try {
			test_write();
			test_read();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
}

3.)

[example3.xml]

<?xml version="1.0" encoding="UTF-8"?>
<Y_ACHSE Parity="N" Stopbits="1"/>

[example3.cpp]

#include <xmlstorage.h>
using namespace XMLStorage;

#include <iostream>
using namespace std;


void test_write()
{
	XMLDoc doc;
	XMLPos pos(&doc);

	 // Zusammenstellen der XML-Struktur im Dokument 'doc'
	pos.create("Y_ACHSE");
	  pos["Stopbits"] = XMLInt(1);
	  pos["Parity"] = "N";
	pos.back();

	 // Schreiben der XML-Datei
	doc.write("example3.xml");
}


void test_read()
{
	XMLDoc doc;

	 // Einlesen des XML-Files
	doc.read("example3.xml");

	XMLPos pos(&doc);

	int stopbits = 0;
	string parity;

	 // Abfrage der Attributwerte des Elements "Y_ACHSE"
	if (pos.go("Y_ACHSE")) {
		stopbits = XMLInt(pos, "Stopbits");
		parity = pos["Parity"];

		pos.back();
	}

	 // Ausgabe der ermittelten Werte
	cout << "Stopbits: " << stopbits << '\n';
	cout << "Parity: " << parity << '\n';
}


int main()
{
	test_write();
	test_read();

	return 0;
}

[Example3.java]

import java.io.IOException;

import de.mfuchs.xmlstorage.XMLDoc;
import de.mfuchs.xmlstorage.XMLInt;
import de.mfuchs.xmlstorage.XMLIntRef;
import de.mfuchs.xmlstorage.XMLPos;

public class Example3
{
	static void test_write() throws IOException
	{
		XMLDoc doc = new XMLDoc();
		XMLPos pos = new XMLPos(doc);

		 // Zusammenstellen der XML-Struktur im Dokument 'doc'
		pos.create("Y_ACHSE");
		  new XMLIntRef(pos.cur(), "Stopbits").assign(1);
		  pos.put("Parity", "N");
		pos.back();

		 // Schreiben der XML-Datei
		doc.write("example3.xml");
	}


	static void test_read() throws Exception
	{
		XMLDoc doc = new XMLDoc();

		 // Einlesen des XML-Files
		doc.read("example3.xml");

		XMLPos pos = new XMLPos(doc);

		int stopbits = 0;
		String parity = "";

		 // Abfrage der Attributwerte des Elements "Y_ACHSE"
		if (pos.go("Y_ACHSE")) {
			stopbits = new XMLInt(pos.cur(), "Stopbits").intValue();
			parity = pos.get("Parity");

			pos.back();
		}

		 // Ausgabe der ermittelten Werte
		System.out.println("Stopbits: " +  stopbits);
		System.out.println("Parity: " +  parity);
	}


	public static void main(String[] args)
	{
		try {
			test_write();
			test_read();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
}

Das folgende Beispiel zeigt die Verwendnung der rudimentär implementierten XPath-Unterstützung:

[xmltest.cpp]
#include <xmlstorage.h>
using namespace XMLStorage;

#include <iostream>
using namespace std;


bool xml_test()
{
	XMLDoc doc;
	bool ret;

	//ret = doc.read("poem.xml");
	//ret = doc.read("machines.xml");
	ret = doc.read("packets.xml");

	if (!ret) {
		std::cerr << doc._last_error << std::endl;
		return false;
	}

	doc.write("out.xml");

	XMLPos pos(&doc);

//	if (pos.go("get_packets/packet"))
//	if (pos.go("/get_packets/packet"))
//	if (pos.go("/get_packets/packet[5]"))
	if (pos.go("/get_packets/packet[@db_id=\"7628\"]"))
//	if (pos.go("get_machines/machine[@wsid=\"client2\"]"))
	{
		cout << "db_id = " << XMLInt(pos, "db_id") << endl;
		cout << "name = " << XMLString(pos, "name").c_str() << endl;
		cout << "short_name = " << XMLString(pos, "short_name").c_str() << endl;

		pos.back();
	}

	return true;
}


int main()
{
	return xml_test()? EXIT_SUCCESS: EXIT_FAILURE;
}
Download

Hauptseite