Forum: PC-Programmierung C# XML Reader


von Robin F. (gehacktes)


Lesenswert?

Hallo,

ich habe hier eine XML Datei wo ich mehrere "ComplexTable" Tags habe und 
ich immer nur die ComplexTable mit dem Attribute TableType="Wirelist" 
und "BOM" auslesen will. Es sollen dort die Attribute in dem Tag Cell 
Text="..." ausgelesen und später in eine Excel eingetragen werden. Die 
Anzahl der ComplexTables kann variieren, daher benötige ich eine Abfrage 
der Attribute.

Hier ist ein Beispiel wo die Struktur der XML Datei abgespeckt 
dargestellt ist:
1
<Harnessdata>
2
 <Harness>
3
  <ComplexTable TableType="csv">
4
   <SubTable>
5
    <Row>
6
     <Cell Text="bla"/>
7
     <Cell Text="blabla"/>
8
     <Cell Text="blablabla"/>
9
    </Row>
10
   </SubTable>
11
  </ComplexTable>
12
  <ComplexTable TableType="Wirelist">
13
   <SubTable>
14
    <Row>
15
     <Cell Text="14"/>
16
     <Cell Text="Leitung"/>
17
     <Cell Text="Farbe"/>
18
    </Row>
19
    <Row>
20
     <Cell Text="15"/>
21
     <Cell Text="Leitung"/>
22
     <Cell Text="Farbe"/>
23
    </Row>
24
   </SubTable>
25
  </ComplexTable>
26
  <ComplexTable TableType="BOM">
27
   <SubTable>
28
    <Row>
29
     <Cell Text="VWS"/>
30
     <Cell Text="Kurzname"/>
31
    </Row>
32
    <Row>
33
     <Cell Text="VWS1"/>
34
     <Cell Text="Kurzname1"/>
35
    </Row>
36
   </SubTable>
37
  </ComplexTable>
38
 </Harness>
39
</Harnessdata>

Problem ist jetzt, ich kann zwar in die richtige CpmplexTable 
reinspringen aber ich kann dann nicht "nur" die jeweiligen Attribute in 
der ComplexTable auslesen. Das Programm liest immer alles aus was Tag 
Cell mit Attribute Text hat.
1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using System.Text;
5
using System.Threading.Tasks;
6
using System.Xml;
7
8
namespace XML
9
{
10
    class Program
11
    {
12
        static void Main(string[] args)
13
        {
14
            XmlDocument xdoc = new XmlDocument();
15
            xdoc.PreserveWhitespace = true;
16
            try
17
            {
18
                xdoc.Load("Test.xml");
19
20
                XmlNodeList cTables = xdoc.GetElementsByTagName("ComplexTable");
21
22
                foreach (XmlNode table in cTables)
23
                {
24
                    string tableType = table.Attributes["TableType"].Value;
25
                    Console.WriteLine(tableType);
26
27
                    XmlNodeList subTables = xdoc.GetElementsByTagName("SubTable");
28
                    if (tableType == "Wirelist")
29
                    {
30
                        foreach (XmlNode subTable in subTables)
31
                        {
32
                            XmlNodeList rows = xdoc.GetElementsByTagName("Row");
33
34
                            foreach (XmlNode row in rows)
35
                            {
36
                                XmlNodeList cells = xdoc.GetElementsByTagName("Cell");
37
38
                                foreach (XmlNode cell in cells)
39
                                {
40
                                    string text = cell.Attributes["Text"].Value;
41
                                    Console.Write(text + " ");
42
                                }
43
                                //Console.WriteLine("-------------");
44
                            }
45
                        }
46
                    }
47
                }
48
            }
49
            catch (System.IO.FileNotFoundException)
50
            {
51
                Console.WriteLine("Datei konnte nicht gefunden werden!");
52
            }
53
            Console.ReadKey();
54
        }
55
    }
56
}

Ich habe das ganze auch in Python programmiert und dort funktioniert es 
genau so wie ich es haben will. Ich möchte das ganze aber in C# 
Programmieren.

Hier nochmal der Python Script:
1
from xml.dom import minidom
2
import xlsxwriter
3
import os
4
5
# XML Datei laden
6
xmldoc = minidom.parse("Test2.xml")
7
ctables = xmldoc.getElementsByTagName("ComplexTable")
8
9
# Excel Dokumente für Wire, BOM und Wire_Bom erstellen
10
workbook = xlsxwriter.Workbook(os.path.join(os.path.dirname(os.path.abspath(__file__)),"Wire.xlsx"))
11
worksheet = workbook.add_worksheet("Wirelist")
12
13
# Zähler für die Zeilen und Spalten
14
c = 0
15
r = 0
16
17
# Schleife durch alle ComplexTable
18
for table in ctables:
19
# Attribute der ComplexTable auslesen
20
  tableType = table.getAttribute("TableType")
21
  subTables = table.getElementsByTagName("SubTable")
22
# wenn TableType = Wirelist
23
  if tableType == "Wirelist":
24
    print("-" * 40)
25
    print("Wirelist")
26
    print("-" * 40)
27
# spring in die subTable der Wirelist    
28
    for subTable in subTables:
29
      rows = subTable.getElementsByTagName("Row")
30
# von dort aus in die einzelnen Rows
31
      for row in rows:
32
        cells = row.getElementsByTagName("Cell")
33
# jede Celle durchlaufen
34
        for cell in cells:
35
# Attribut Text von der Cell auslesen
36
          textName = cell.getAttribute("Text")
37
# Ausgabe des Attributes          
38
          print(textName, end=" ")
39
# in Excel Dokument schreiben
40
          worksheet.write_string(c,r,textName)
41
          r = r + 1
42
# wenn alle Spalten gefüllt sind, in nächste Zeile springen          
43
        r = 0
44
        c = c + 1
45
        print("")
46
        print("-" * 40)

Das Problem sehe ich hier:
1
...
2
XmlNodeList rows = xdoc.GetElementsByTagName("Row");
3
...
4
XmlNodeList cells = xdoc.GetElementsByTagName("Cell");
5
...
Ich kann hier nur xdoc (XmlNodeList) mit GetElementsByTagName arbeiten 
aber nicht mit subTable , row (XmlNode). Mit Python funktioniert genau 
das.

Hat einer einen Tipp wie ich gezielt in bestimmten Bereichen "nur" diese 
Tags auslesen kann?

Danke und Gruß
Robin

von bluppdidupp (Gast)


Lesenswert?

1
foreach (XmlNode subTable in subTables)
2
{
3
   XmlNodeList rows = xdoc.GetElementsByTagName("Row");

...da solltest du theoretisch statt mit xdoc.GetElementsByTagName(...) 
mit subTable.SelectNodes(...) weiter kommen können.

von Robin F. (gehacktes)


Lesenswert?

Es werden trotzdem noch alle "<Cell Text=".."/> im gesamten XML 
ausgegeben.

von bluppdidupp (Gast)


Lesenswert?

1
XmlNodeList cTables = xdoc.GetElementsByTagName("ComplexTable");
2
3
                foreach (XmlNode table in cTables)
4
                {
5
                    string tableType = table.Attributes["TableType"].Value;
6
                    Console.WriteLine(tableType);
7
8
                    XmlNodeList subTables = table.SelectNodes("SubTable");
9
                    if (tableType == "Wirelist")
10
                    {
11
                        foreach (XmlNode subTable in subTables)
12
                        {
13
                            XmlNodeList rows = subTable.SelectNodes("Row");
14
15
                            foreach (XmlNode row in rows)
16
                            {
17
                                XmlNodeList cells = row.SelectNodes("Cell");
18
19
                                foreach (XmlNode cell in cells)
20
                                {
21
                                    string text = cell.Attributes["Text"].Value;
22
                                    Console.Write(text + " ");
23
                                }
24
                                //Console.WriteLine("-------------");
25
                            }
26
                        }
27
                    }
28
                }
gibt bei mir nur die Wirelist Cell-Attribute aus und nicht alle?

von Robin F. (gehacktes)


Lesenswert?

Super.

Ich hatte die subTable nicht mit angepasst auf SelectNodes.
Jetzt funktioniert es.

Herzlichen Dank für den schnellen Support.

Beste Grüße
Robin

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.