Entwickler-Ecke
IO, XML und Registry - XML Elemente auslesen
Luna1987 - Fr 13.03.09 12:09
Titel: XML Elemente auslesen
Hy @ all.
Wiedermal habe ich ein Problem und versuche schon ne ganz eWeile die Lösung zu finden :-(
Es wird ein XML Dokument erzeugt, wo verschiedene Elemente mit verschiedenen Einträgen vorhanden sind (achneee ;-))
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: 35: 36: 37: 38:
| <?xml version="1.0" encoding="UTF-8" ?> <sourcemonitor_metrics> <project version="2.5"> // Hier werden die Namen der einzelnen Spalten erwähnt <metric_names name_count="15"> <metric_name id="M0" type="number">Lines</metric_name> <metric_name id="M1" type="number">Statements </metric_name> … </metric_names> <checkpoints checkpoint_count="1"> <checkpoint checkpoint_name="Baseline"> <files file_count="2"> // Hier wird der erste Dateiname, der geprüft wird, erwähnt <file file_name="CopyFromMainForm.cs"> <metrics metric_count="15"> // Hier sind die verschiedenen Analyseergebnisse der einzelnen Spalten der ersten Datei <metric id="M0">18</metric> <metric id="M1">11</metric> <metric id="M2">0.0</metric> <metric id="M3">0.0</metric> <metric id="M4">1</metric> ... </metrics> </file> // Hier wird der zweite Dateiname, der geprüft wird, erwähnt <file file_name="CopyFromProgram.cs"> <metrics metric_count="15"> // Hier sind die verschiedenen Analyseergebnisse der einzelnen Spalten der zweiten Datei <metric id="M0">25</metric> <metric id="M1">9</metric> <metric id="M2">20.0</metric> <metric id="M3">16.0</metric> <metric id="M4">1</metric> ... </metrics> </file> ... </sourcemonitor_metrics> |
Ich möchte nun die metric Einträge JEDER Datei (file) in einer ListView haben. Habe also eine Art Tabelle.
Sollte so z.B. aussehen:
File Lines Statement
1.cs 11111 34
2.cs 34322 1
(das ist ein Beispiel, keine relevanten Werte!!!)
Das die verschiedenen Dateien in der Spalte „File“ angezeigt werden funktioniert schon, aber irgendwas stimmt mit diesem foreach Teil nicht (siehe Programmcode unten), denn er zeigt mir immer nur die metric Inhalte der ersten Datei an, bei jeder Datei also das Gleiche!!!
Liegt das irgendwie an der XmlNode = doc.SelectSingleNode(Pfad)? Denn soweit ich weiß wird ja nur das erste metric Element aus dem Dokument ausgewählt, aber wenn ich das Ganze mit XmlNodeList erzeuge, dann macht er die ganzen Analyseergebnisse in eine Spalte. Ist wahrscheinlich nur ne Kleinigkeit, aber ich bekomme es einfach nicht hin!
Danke euch für eure Hilfe :-)
So sieht ein Teil des Codes aus:
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: 38: 39: 40: 41:
| XmlDocument doc2 = new XmlDocument(); doc2.Load(export_file.InnerText);
XmlNode metric_names = doc2.SelectSingleNode("/sourcemonitor_metrics/project/metric_names"); XmlNode metrics = doc2.SelectSingleNode("/sourcemonitor_metrics/project/checkpoints/checkpoint/files/file/metrics"); listView.Columns.Add("File");
foreach (XmlNode metric_name in metric_names) { listView.Columns.Add(metric_name.InnerText); }
if (_fileTextBox.Text.Length > 0 && _fileRadioButton.Checked) { for (int i = 0; i < _selectedFilesListBox.Items.Count; i++) { string fileName = _selectedFilesListBox.Items[i].ToString();
ListViewItem item = new ListViewItem(fileName); foreach (XmlNode metric in metrics) { item.SubItems.Add(metric.InnerText); }
listView.Items.Add(item); } } |
Kha - Fr 13.03.09 12:48
Mit SelectNodes("/sourcemonitor_metrics/project/checkpoints/checkpoint/files/file") bekommst du erstmal eine Liste alle file-Nodes. Innerhalb der for-Schleife (warum dort nicht auch foreach ;) ) suchst du dann in dieser Liste den Node, der das ListBox-Item als "file_name"-Attribut hat. Und wenn du dann von diesem Node SelectNodes("metrics/metric") aufrufst, hast du die dazugehörigen Metrics.
PS: Angaben wie metric_count="15" sind etwas redundant, oder ;) ?
Luna1987 - Fr 13.03.09 13:04
Hy Kha.
Vielen dank für deine schnelle Antwort.
Aber könntest du mir dieses foreach usw. evtl als C# Code schreiben, stehe etwas auf´m Schlauch :oops:
Danke :-)
PS: metric_conut="15"; wird unter anderem von dem externen Programm automatisch erzeugt, da sind soooo viele Dinge nicht sinnvoll, zumindestens nicht für meine Bedürfnisse ;-) hehe.
Luna1987 - Mo 16.03.09 09:40
Habe es weiter probiert, es will aber einfach nicht hinhauen bei mir :-(
Habe es ein u.a kontrolliert, indem ich mir zwischendurch mal "fileName" oder so per NessageBox ausgeben lasse. Bis ca. Zeile 31 funktionierts, aber ab 32 zeigt er mir gar nichts an, d.h. er wird diese foreach Dinge gar nicht ausfürhen. Liegt wohl immer noch an dieser XmlNodeList. Wie muss ich das Ganze abfragen??????? Habe nun echt keine Ahnung mehr wie ich das realisieren soll.
Danke für eure Hilfe!
Hier mal der aktuelle Code:
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: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51:
| XmlNodeList metrics = doc2.SelectNodes("/sourcemonitor_metrics/project/checkpoints/checkpoint/files/file/metrics/metric"); XmlNode files = doc2.SelectNodes("/sourcemonitor_metrics/projects/checkpoints/checkpoint/files/file");
listView.Columns.Add("File");
foreach (XmlNode metric_name in metric_names) { listView.Columns.Add(metric_name.InnerText); }
if (_fileTextBox.Text.Length > 0 && _fileRadioButton.Checked) { for (int i = 0; i < _selectedFilesListBox.Items.Count; i++) { string fileName = _selectedFilesListBox.Items[i].ToString(); string[] worrds = fileName.Split(new char[] { '\\' }); foreach (string worrd in worrds) { if (worrd.EndsWith(".cs")) { fileName = worrd; } ListViewItem item = new ListViewItem(fileName); foreach (XmlNode file in files) { if (fileName == file.Attributes["file_name"].ToString()) { foreach (XmlNode metric in metrics) { item.SubItems.Add(metric.InnerText); } listView.Items.Add(item); } } } } } |
Kha - Mo 16.03.09 17:03
Luna1987 hat folgendes geschrieben : |
Habe es ein u.a kontrolliert, indem ich mir zwischendurch mal "fileName" oder so per NessageBox ausgeben lasse. |
Uff, dazu gibt es eigentlich den Debugger ;) . Also z.B. auf die erste Zeile einen Breakpoint setzen und dann mit F10 durchsteppen.
Dann hättest du bemerkt, dass du bei der inneren foreach-Schleife die schließende Klammer vergessen hast. Du brauchst aber die ganze Schleife nicht, denn dafür gibt's
Path.GetFileName. Dürfte dann etwa so aussehen:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| XmlNodeList file = doc2.SelectNodes("/sourcemonitor_metrics/projects/checkpoints/checkpoint/files/file");
if (_fileTextBox.Text.Length > 0 && _fileRadioButton.Checked) { foreach (string path in _selectedFilesListBox.Items) { ListViewItem item = new ListViewItem(path); string fileName = Path.GetFileName(path); foreach (XmlNode file in files) { if (file.Attributes["file_name"].Value == fileName) { foreach (XmlNode metric in file.SelectNodes("metrics/metric")) { item.SubItems.Add(metric.InnerText); } listView.Items.Add(item); break; } } } } |
Luna1987 - Di 17.03.09 08:36
Vielen Dank :lol: Super nett von dir, hat mir sehr geholfen :!:
Nur zur kurzen Info: Mit den (geschweiften) Klammern an bestimmten Stellen setzen usw. ist vorgeschrieben bei uns, benutzen extra ReSharper und StyleCop, damit bestimmte Regeln eingesetzt und eingehalten werden. Der korrigiert sozusagen alles automatisch :wink:
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!