"Selfmade" XML-Pasrer
-
Hallo liebe Community!
In meinem Modul (C++) stehe ich vor der Aufgabe einen XML-Parser zu programmieren.
Da ich bislang meist mit dem Kopf durch die Wand programmiert habe, wollte ich diesmal ein paar erfahrene Coder um Rat bitten.
Das Programm soll...
...die Hierarchie erkennen und in entsprechende Strukturen oder Objekte ablegen
...die Hierachie bis zu einem bestimmten Wert wieder ausgeben
...Ausgabe ohne Attribute
...Ausgabe des Elementtextes unterdrückenDie Hauptfragen die sich mir stellen:
Wie soll ich die Elemente(Elementtexte, Attribute) speichern?
Als Liste? Stack? (Binär)Baum?
Und:
Wie sollte ich die XML-Datei einlesen?
Zeichen für Zeichen? Zeilenweise?
Über ein paar Denkanstöße würde ich mich sehr freuen.
Vielen Dank!
Edit: Fertige Parser wie tinyXML sind (natürlich) nicht erlaubt.
-
Die Datenstruktur würde ich mir selbst bauen (da es ja eine Übung ist, sonst eher was fertiges für alles nehmen). Stichwort Composite-Pattern -> also so rekursive Klassen (wurde das gerne mal bei uns genannt)
-
Ok...schon mal danke dafür.
Ich denke ich werde eine (einfach) verkettete Liste nehmen. Ist dies möglich oder stehe ich so irgendwann vor einer Wand?
-
pop schrieb:
Ich denke ich werde eine (einfach) verkettete Liste nehmen. Ist dies möglich oder stehe ich so irgendwann vor einer Wand?
Ich kenne deine Grundkenntnisse nicht, aber ich hätte ganz pragmatisch ein
struct xml_element { std::string name; std::map<std::string, xml_element> atributes; std::vector<xml_element> content; };genommen.
Wenn die Standardbibliothek von C++ erlaubt ist, gibt es eigentlich keinen Grund, auf sie zu verzichten.
Mit selbergebauten Listen wird der Code erfahrungsgemäss sehr unübersichtlich, was zu Pointerfehlern, Memory-Leaks und weiteren Übeln führt, die Anfänger eher abschrecken, als nützen. Und abgesehen davon ist das mit Listen auch langsamer.
-
Vielen Dank für eure Hilfe. Ich habe mich dennoch dazu entschieden, eine einfach verkette Liste zu benutzen. Denn auch dies muss ich noch üben
.
-
Ich würde auch einen (mehrere?) Iterator einbasteln, dann kann die Klasse alle möglichen Algorithmen nutzen, das ist sehr hilfreich.
-
modul schrieb:
struct xml_element { std::string name; std::map<std::string, xml_element> atributes; std::vector<xml_element> content; };genommen.
super, und wo kommen dann die inhalte hin

-
pop schrieb:
Zeichen für Zeichen? Zeilenweise?
Zeilenweise macht keinen Sinn, da XML nicht Zeilenorientiert ist. Also Zeichenweise und damit einen stateful parser füttern.
-
pop schrieb:
Hallo liebe Community!
Wie soll ich die Elemente(Elementtexte, Attribute) speichern?Als Liste? Stack? (Binär)Baum?
Wäre es nicht sinnvoll einen Baum zu nehmen, wie beim DOM?
-
TNA schrieb:
pop schrieb:
Hallo liebe Community!
Wie soll ich die Elemente(Elementtexte, Attribute) speichern?Als Liste? Stack? (Binär)Baum?
Wäre es nicht sinnvoll einen Baum zu nehmen, wie beim DOM?
std::vector<xml_element> content; da kommt doch der baum her, oder fehlt dir der parent

-
crispin kenton schrieb:
std::vector<xml_element> content; da kommt doch der baum her, oder fehlt dir der parent

Ok, ich glaube jetzt verstehe ich das. Aber warum ist ein Attribute ein xml_element?
-
TNA schrieb:
crispin kenton schrieb:
std::vector<xml_element> content; da kommt doch der baum her, oder fehlt dir der parent

Ok, ich glaube jetzt verstehe ich das. Aber warum ist ein Attribute ein xml_element?
Kpl. vllt. weil ein Attribut ein String sein kann und ein String ein xml_element. Am besten fragst mal den Mr. modul, der hat sich die Grütze schließlich ausgedacht

-
crispin kenton schrieb:
modul schrieb:
struct xml_element { std::string name; std::map<std::string, xml_element> atributes; std::vector<xml_element> content; };genommen.
super, und wo kommen dann die inhalte hin

Sind die Attributwerte nicht einfach Strings?
Für die Inhalte bietet sichboost::variantan.struct xml_element { std::string name; std::map<std::string, std::string> attributes; std::vector<boost::variant<xml_element, std::string>> content; };pop schrieb:
Wie sollte ich die XML-Datei einlesen?
Zeichen für Zeichen? Zeilenweise?
Mach es mit Iteratoren, sodass es zum Beispiel mit
std::string::const_iterator,std::istreambuf_iterator<char>undchar const *funktioniert.
-
wegen sowas gleich boost bemühen? reicht da nicht ein
struct xml_element { std::string name; std::map<std::string, std::string> attributes; std::vector<xml_element> childs; std::string content; };dann schreibt man auf content einen getter und gibt das einfach aus wenn childs.length == 0 ist
@edit: brrrr....
-
Ich würd mir mal die Interfaces von XML DOM der W3C ansehen, XML ist etwas komplizierter als Elemente und Attribute.
MfG SideWinder
-
SideWinder schrieb:
Ich würd mir mal die Interfaces von XML DOM der W3C ansehen, XML ist etwas komplizierter als Elemente und Attribute.
MfG SideWinder
Link?
-
http://www.w3.org/XML bzw. detaillierter http://www.w3.org/TR/2006/REC-xml11-20060816
Die Aufgabe einen XML-Parser selbst zu schreiben ist also in etwa vergleichbar mit der Aussage "Ich baue mal gerade ein Auto"...
-
Th69 schrieb:
Die Aufgabe einen XML-Parser selbst zu schreiben ist also in etwa vergleichbar mit der Aussage "Ich baue mal gerade ein Auto"...
Kommt drauf an, was man damit machen möchte. Einen generischen, High-Level XML-Parser zu schreiben ist natürlich schon sehr anspruchsvoll, aber das will er ja anscheinend gar nicht.
-
crispin kenton schrieb:
childs
parentren
-
hustbaer schrieb:
crispin kenton schrieb:
childs
parentren
parents bitte!