C# XML Reader

OP #6538804
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
Gast #6538909
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.
Gast #6539197
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?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren