stoperror - Do 02.07.09 15:59
Titel: XMLReader benutzen, aber das folgende Child-Element auslesen
Hallo zusammen,
ich schlage mich gerade mit einem XML-Parser herum.
Ich muss ein XML parsen, das so aussieht:
XML-Daten
1: 2: 3: 4: 5: 6: 7: 8:
| <OneTopic>
<Topic> <SubTopics> <Topic oder weitere SubTopics... </SubTopics> <Text Plaintext="TopicTitle"></Text> </Topic> |
Ich verwende den XmlTextReader, weil die Dateien groß werden können...
Und möchte aber vom Element Topic auf das Attribut Plaintext zugreifen, ohne im Parser Tags zu überspringen.
Ich habe schon diverse Möglichkeiten, mit XPath und Co ausprobiert, bin aber noch auf keinen grünen Zweig gekommen...
Reader.Readtofollowing war auch nicht das richtige, weil er dan Tags auslässt...
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37:
| XmlTextReader reader = new XmlTextReader(this.Importfiletextbox.Text); while (reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element:
switch (reader.Name.ToString()) { case "OneTopic": outputbuffer.Write(createheader()); break; case "Topic": outputbuffer.Write(createtopic(uid));
uid = uid + 1;
break; case "SubTopics": outputbuffer.Write(createsubtopics()); break; case "Text": outputbuffer.Write(createtitle(reader.GetAttribute("PlainText"))); outputbuffer.Write("</node>\r\n"); break;
.... |
Bin für jede Hilfe dankbar!
Dankeschön!
Moderiert von
Christian S.: XML-Tags hinzugefügt
Moderiert von
Christian S.: C#-Tags hinzugefügt
Kha - Fr 03.07.09 13:30
:welcome:
stoperror hat folgendes geschrieben : |
Und möchte aber vom Element Topic auf das Attribut Plaintext zugreifen, ohne im Parser Tags zu überspringen. |
Das geht nicht, denn genau daraus zieht der XmlReader schließlich seine Geschwindigkeit:
Zitat: |
Represents a reader that provides fast, non-cached, forward-only access to XML data. |
Damit du dem Topic seinen Titel zuordnen kannst, bieten sich rekursive Methoden zum Einlesen an, also für jedes Element eine Methode. XmlReader.ReadSubtree dürfte dabei nützlich sein, aber für Genaueres müsstest du erstmal erläutern, welcher Output erwartet wird. Auch die Xml-Struktur ist bei deinem Beispiel nicht ganz klar.
stoperror - Fr 03.07.09 14:39
Kha hat folgendes geschrieben : |
:welcome:
stoperror hat folgendes geschrieben : | Und möchte aber vom Element Topic auf das Attribut Plaintext zugreifen, ohne im Parser Tags zu überspringen. | Das geht nicht, denn genau daraus zieht der XmlReader schließlich seine Geschwindigkeit: Zitat: | Represents a reader that provides fast, non-cached, forward-only access to XML data. |
Damit du dem Topic seinen Titel zuordnen kannst, bieten sich rekursive Methoden zum Einlesen an, also für jedes Element eine Methode. XmlReader.ReadSubtree dürfte dabei nützlich sein, aber für Genaueres müsstest du erstmal erläutern, welcher Output erwartet wird. Auch die Xml-Struktur ist bei deinem Beispiel nicht ganz klar. |
Erstmal danke für die Antwort.
ich versuch das ganze im Anschluss noch mal klarer zu beschreiben.
Input z. B.:
OneTopic ist das Wurzelelement, es enthält das Haupttopic 1 (hier Home)
Und dieses Haupttopic kann wiederum Suptopics enthalten. Diese Subtopics können wieder aus Topics und Subtopics bestehen in beliebiger Tiefe...
Also hier:
Home
- Unternehmen
- Leistungen
-- Leistung A
--- Leistung A1
-- Leistung B
XML-Daten
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34:
| <OneTopic> <Topic> <SubTopics> <Topic> <Text PlainText="Unternehmen"> </Text> </Topic> <Topic> <SubTopics> <Topic> <SubTopics> <Topic> <Text PlainText="Leistung A1"> </Text> </Topic> </SubTopics> <Text PlainText="Leistung A"> </Text> </Topic> <Topic> <Text PlainText="Leistung B"> </Text> </Topic> </SubTopics> <Text PlainText="Leistungen"> </Text>
</Topic> </SubTopics> <Text PlainText="HOME"> </Text> </Topic> </OneTopic> |
Der Output soll t3d (Typo 3-xml) werden, wobei ich die obige Struktur mehrfach abbilden muss:
T3D-Header... (schreib ich einfach so raus)
<T3RecordDocument>
XML-Daten
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| <header type="array"> <charset>iso-8859-1</charset> <XMLversion>1.0</XMLversion> <meta type="array"> </meta> <static_tables index="relStaticTables" type="array"> <tablename index="0">_ALL</tablename> </static_tables> <excludeMap type="array"> </excludeMap> <softrefCfg type="array"> </softrefCfg> <extensionDependencies type="array"> </extensionDependencies> |
T3D header pagetree mit den ids, die ich beim parsen generieren muss (uids):
XML-Daten
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27:
| <pagetree type="array"> <node index="0" type="array"> <uid>0</uid> <node index="subrow" type="array"> <node index="37" type="array"> <uid>37</uid> <node index="subrow" type="array"> <node index="39" type="array"> <uid>39</uid> </node> <node index="47" type="array"> <uid>47</uid> </node> <node index="45" type="array"> <uid>45</uid> </node> <node index="43" type="array"> <uid>43</uid> </node> <node index="41" type="array"> <uid>41</uid> </node> </node> </node> </node> </node> </pagetree> |
Das funktioniert auch schon mal soweit.
header records: da muss ich die von mir generierte uid und den Topicnamen irgendwie zusammenkriegen -> und da liegt mein Problem:
XML-Daten
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26:
| <records type="array"> <table index="pages" type="array"> <rec index="uid-Home" type="array"> <uid>uid-Home</uid> <pid>uid-Home</pid> <title>Home</title> <size>1687</size> <relations index="rels" type="array"> </relations> <softrefs type="array"> </softrefs> </rec> <rec index="uid-Leistung" type="array"> <uid>uid-Leistung</uid> <pid>uid-Leistung</pid> <title>Leistung</title> <size>1692</size> <relations index="rels" type="array"> </relations> <softrefs type="array"> </softrefs> </rec> .... </table> </records> </header> |
Und dann muss ich im Body nochmal so eine Liste mit uid und Title generieren
XML-Daten
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| <records type="array"> <tablerow index="pages:uid-Home" type="array"> <fieldlist index="data" type="array"> <field index="uid">uid-Home</field> <field index="pid">uid-Home</field> <field index="title">Home</field> </fieldlist> <related index="rels" type="array"> </related> </tablerow> <tablerow index="pages:uid-Leistung" type="array"> <fieldlist index="data" type="array"> <field index="uid">uid-Leistung</field> <field index="pid">uid-Leistung</field> <field index="title">Leistung</field> </fieldlist> <related index="rels" type="array"> </related> </tablerow> ... </records> </T3RecordDocument> |
ich hoffe das macht die Sache nun klarer...
Das gesamte <pagetree> kann ich problemlos mit meiner Lösung nachbauen, würde aber im selben Rutsch auch gerne die beiden anderen Strukturen (records) gleich mit erstellen in einen Stringbuffer schreiben und anschliessend in die Datei schreiben.
Bei meiner Lösung krieg ich aber nicht raus, welche uid zu welchem Topictitle gehört....
Moderiert von
Kha: XML-Tags hinzugefügt
WEnn ich subtree verwende:
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
switch (reader.Name.ToString())
{
case "ap:OneTopic":
//write header
outputbuffer.Write(createheader());
break;
case "ap:Topic":
//write topic
outputbuffer.Write(createtopic(uid));
//write records to buffers
XmlReader test = reader.ReadSubtree();
dann ist mein SubtreeReader übrigens leer.. [System.Xml.XmlSubtreeReader] {None} System.Xml.XmlSubtreeReader