Autor Beitrag
Luna1987
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 16

WinXP

BeitragVerfasst: Fr 13.03.09 12:09 
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 ;-))

ausblenden volle Höhe 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:

ausblenden volle Höhe 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:
// Dateien wurden ausgewählt und in eine ListBox (_selectedFilesListBox) 
// geschrieben

// von SourceMonitor erstelltes XML (Pfad in export_file.InnerText 
// gespeichert) Dokument öffnen
XmlDocument doc2 = new XmlDocument();
doc2.Load(export_file.InnerText);

// Elemente metric_names, metrics werden benötigt
XmlNode metric_names = doc2.SelectSingleNode("/sourcemonitor_metrics/project/metric_names");
XmlNode metrics = doc2.SelectSingleNode("/sourcemonitor_metrics/project/checkpoints/checkpoint/files/file/metrics");
               
// Spalte File hinzufügen, da nicht automatisch von SourceMonitor übergeben
listView.Columns.Add("File");

// Spalten automatisch erzeugen (welche auch bei Sourcemonitor vorhanden sind)
foreach (XmlNode metric_name in metric_names)
{
   listView.Columns.Add(metric_name.InnerText);
}

// testen ob Dateiauswahl überhaupt aktiviert
if (_fileTextBox.Text.Length > 0 && _fileRadioButton.Checked)
{
// für jede Zeile (d.h. jede Datei) in der ListBox
  for (int i = 0; i < _selectedFilesListBox.Items.Count; i++)
  {
    // wird erste Spalte „File“ mit Dateiname gefüllt
    string fileName = _selectedFilesListBox.Items[i].ToString();

            ListViewItem item = new ListViewItem(fileName);
                            
    // alle vorher erzeugten nun Spalten füllen             
    foreach (XmlNode metric in metrics)
    {
              item.SubItems.Add(metric.InnerText);
                   }

            listView.Items.Add(item);
  }
}
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 16

WinXP

BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 16

WinXP

BeitragVerfasst: 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:
ausblenden volle Höhe 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");

// Spalte File hinzufügen, da nicht automatisch von SourceMonitor übergeben
listView.Columns.Add("File");

// Spalten automatisch erzeugen (welche auch bei Sourcemonitor vorhanden sind
foreach (XmlNode metric_name in metric_names)
{
    listView.Columns.Add(metric_name.InnerText);
}

// Testen ob Dateiauswahl überhaupt aktiviert.
if (_fileTextBox.Text.Length > 0 && _fileRadioButton.Checked)
{
    // für jede Zeile in der ListBox
    for (int i = 0; i < _selectedFilesListBox.Items.Count; i++)
    {
        // FileNamen ausgeben in Spalte „File“
        string fileName = _selectedFilesListBox.Items[i].ToString();
        // Spalten des Strings (Pfadname) bei jedem “\”
        string[] worrds = fileName.Split(new char[] { '\\' });
        // jeder Teil des gesplitteten Strings wird untersucht, 
        foreach (string worrd in worrds)
        {     
            // ob es mit “.cs” endet                           
            if (worrd.EndsWith(".cs"))
            {  
                // wenn JA, dann wird es in dem string fileName gespeichert
                fileName = worrd;
            }
      // fileName wird an ListViewItem übergeben
      ListViewItem item = new ListViewItem(fileName);
      
      // für jeden Knoten “file” aus der XmlNodeList „files“
      foreach (XmlNode file in files)
             {
          // wenn “fileName” = dem Attribut “file_name” ist
                 if (fileName == file.Attributes["file_name"].ToString())
                 {  
                     // dann füge die ganzen Metricdinger hinzu…
                     foreach (XmlNode metric in metrics)
                     {
                          item.SubItems.Add(metric.InnerText);
                     }
                     listView.Items.Add(item);
                 }
             }
         }
     }
}
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mo 16.03.09 17:03 
user profile iconLuna1987 hat folgendes geschrieben Zum zitierten Posting springen:
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:
ausblenden 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) {
  // für jede Zeile in der ListBox // Kommentare sollen nicht den Code noch einmal nacherzählen ;)
  foreach (string path in _selectedFilesListBox.Items) { // Ist doch einfach hübscher        
    // Pfad wird an ListViewItem übergeben
    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// Kann nicht schaden
      }
    }
  }
}

_________________
>λ=
Luna1987 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 16

WinXP

BeitragVerfasst: 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: