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>
#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; }
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>
#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; }
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"/>
#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; }
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 |