Entwickler-Ecke
IO, XML und Registry - TreeView und XML
bambam77 - Do 10.09.09 09:56
Titel: TreeView und XML
Hallo
Seit paar Tagen beschäftige ich mich mit C#. Ich muss eine kleine winform-Applikationb mit TreeView erstellen. Als Quelle für TreeVie nutze ich folgendes XML Dokument (hier nur ein Abschnitt):
XML-Daten
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| <?xml version="1.0" encoding="utf-8" ?> <storage> <documents> <doc id="" prod="Product A" name="Product A - Manual1" ... file="Product-A-Manual1.pdf" /> <doc id="" prod="Product A" name="Product A - Manual2" ... file="Product-A-Manual2.pdf" /> <doc id="" prod="Product A" name="Product A - Manual3" ... file="Product-A-Manual3.pdf" /> <doc id="" prod="Product A" name="Product A - Manual4" ... file="Product-A-Manual4.pdf" /> <doc id="" prod="Product B" name="Product B - Manual1" ... file="Product-B-Manual1.pdf" /> <doc id="" prod="Product B" name="Product B - Manual2" ... file="Product-B-Manual2.pdf" /> <doc id="" prod="Product B" name="Product B - Manual3" ... file="Product-B-Manual3.pdf" /> <doc id="" prod="Product B" name="Product B - Manual4" ... file="Product-B-Manual4.pdf" /> <doc id="" prod="Product C" name="Product C - Manual1" ... file="Product-C-Manual1.pdf" /> <doc id="" prod="Product C" name="Product C - Manual2" ... file="Product-C-Manual2.pdf" /> <doc id="" prod="Product D" name="Product D - Manual1" ... file="Product-D-Manual1.pdf" /> <doc id="" prod="Product E" name="Product E - Manual1" ... file="Product-E-Manual1.pdf" /> <doc id="" prod="Product F" name="Product F - Manual1" ... file="Product-F-Manual1.pdf" /> <doc id="" prod="Product F" name="Product F - Manual2" ... file="Product-F-Manual2.pdf" /> </documents> </storage> |
Ich habe leider kein Einfluss auf die Struktur...
Ich eine ein Problem mit den Produkten (<doc ... prod="..."/>). Wie man es oben sehen kann, für einen Produkt können mehree Dokumente vorhanden werden.
Und genau das gleiche sehe ich im TreeView:
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:
| - Produkt A -- doc1 -- doc2 -- doc3 - Produkt A -- doc1 -- doc2 -- doc3 - Produkt A -- doc1 -- doc2 -- doc3 - Produkt A -- doc1 -- doc2 -- doc3 - Produkt B -- doc4 -- doc5 -- doc6 - Produkt B -- doc4 -- doc5 -- doc6 - Produkt B -- doc4 -- doc5 -- doc6 - Produkt B -- doc4 -- doc5 -- doc6 |
Das aber entspricht meinem Plan nicht :)
Und mein Plan sieht so aus:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| - Produkt A -- doc1 -- doc2 -- doc3 - Produkt B -- doc4 -- doc5 -- doc6 |
Wie kann ich es erreichen?
Anbei mein Code fürs TreeView:
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:
| private void populateTreeView() { try { TreeNode t1, t2; if (xmlFile != null && xmlTree != null) { XmlDocument doc = new XmlDocument(); doc.Load(xmlFile); XmlNodeList nodeList = doc.SelectNodes("storage/products/doc"); foreach (XmlNode node in nodeList) {
t1 = new TreeNode(node.Attributes["prod"].Value); string prodName = node.Attributes["prod"].InnerText; xmlTree.Nodes.Add(t1); foreach (XmlNode nod in node.SelectNodes("//doc[@prod=" + '"' + prodName + '"' + "]")) { t2 = new TreeNode(nod.Attributes["file"].Value); t1.Nodes.Add(t2); }
} } } catch(Exception exp) { MessageBox.Show(exp.Message); } } |
Kann mir jemand ein Tipp geben, wie kann ich es lösen?
Danke in Voraus
bb
Moderiert von
Christian S.: Code- durch XML- und C#-Tags ersetzt
bambam77 - Do 10.09.09 13:08
Da ich gerade es nicht auprobieren kann, kann mir jemand sagen, ob ich richtig denke:
Quelltext
1: 2: 3: 4: 5:
| t1 = new TreeNode(node.Attributes["prod"].Value); string prodName = node.Attributes["prod"].InnerText; if (t1 != node.previousSibling("@prod=" + t1 + ")) //etwas wie das hier... xmlTree.Nodes.Add(t1); |
natürlich Kode ist kann syntaktisch nicht ganz korrekt sein, es geht mir nur um die Idee :)
danke
bb
Kha - Do 10.09.09 17:45
:welcome:
Die Logik stimmt, ich würde aber nicht über die TreeNode-Variable gehen:
C#-Quelltext
1: 2:
| if (node.PreviousSibling != null && node.PreviousSibling.Attributes["prod"].Value == node.Attributes["prod"].Value) continue; |
bambam77 - So 13.09.09 08:35
Kha hat folgendes geschrieben : |
:welcome:
Die Logik stimmt, ich würde aber nicht über die TreeNode-Variable gehen:
C#-Quelltext 1: 2:
| if (node.PreviousSibling != null && node.PreviousSibling.Attributes["prod"].Value == node.Attributes["prod"].Value) continue; | |
Danke Kha, es hat mir weitergeholfen :)
Ich habe es weitergenutzt um die Dateien (files) bei jedem Produkt in Gruppen zu gliedern:
XML-Daten
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| <documents> <doc id="" prod="Product A" ... gr="A" file="Product-A-Manual.pdf" /> <doc id="" prod="Product A" ... gr="A" file="Product-A-Manual1.pdf" /> <doc id="" prod="Product A" ... gr="Install Drivers" file="Product-A-Stuerung-Treiber-Install.msi" /> <doc id="" prod="Product A" ... gr="Execute Drivers" file="Product-A-Stuerung-Treiber-Execute.zip" /> <doc id="" prod="Product A" ... gr="Execute Drivers" file="Product-A-Stuerung-Treiber-Execute.zip" /> <doc id="" prod="Product B" ... gr="B" file="Product-B-Manual2.pdf" /> <doc id="" prod="Product B" ... gr="B" file="Product-B-Manual.pdf" /> <doc id="" prod="Product B" ... gr="B" file="Product-B-Manual1.pdf" /> <doc id="" prod="Product B" ... gr="Install Drivers" file="Product-B-Stuerung-Treiber-Install.msi" /> <doc id="" prod="Product B" ... gr="Execute Drivers" file="Product-B-Stuerung-Treiber-Execute.zip" /> <doc id="" prod="Product C" ... gr="Execute Drivers" file="Product-C-Stuerung-Treiber-Execute.zip" /> <doc id="" prod="Product C" ... gr="Install Drivers" file="Product-C-Stuerung-Install-Treiber.zip" /> <doc id="" prod="Product D" ... gr="A" file="Product-D-Manual.pdf" /> <doc id="" prod="Product D" ... gr="B" file="Product-D-Manual1.pdf" /> <doc id="" prod="Product E" ... gr="Install Drivers" file="Product-E-Stuerung-Treiber-Install.msi" /> </documents> |
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:
| foreach (XmlNode nodeProd in nodeList) { t1 = new TreeNode(nodeProd.Attributes["prod"].Value); string prodName = nodeProd.Attributes["prod"].InnerText; if (nodeProd.PreviousSibling == null) xmlTree.Nodes.Add(t1); if (nodeProd.PreviousSibling != null && nodeProd.PreviousSibling.Attributes["prod"].Value != nodeProd.Attributes["prod"].Value) xmlTree.Nodes.Add(t1); foreach (XmlNode nodeGroup in doc.SelectNodes("storage/documents/doc[@prod=" + '"' + prodName + '"' + "]")) { t2 = new TreeNode(nodeGroup.Attributes["gr"].Value); string grName = nodeGroup.Attributes["gr"].InnerText;
if (nodeGroup.PreviousSibling == null) t1.Nodes.Add(t2); if (nodeGroup.PreviousSibling != null && nodeGroup.PreviousSibling.Attributes["gr"].Value != nodeGroup.Attributes["gr"].Value) t1.Nodes.Add(t2);
foreach (XmlNode nodeDoc in doc.SelectNodes("//doc[@gr=" + '"' + grName + '"' + "][@prod=" + '"' + prodName + '"' + "]")) { t3 = new TreeNode(nodeDoc.Attributes["file"].Value); t2.Nodes.Add(t3); } } |
Es funktioniert soweit, aber ich habe ein Problem, nämlich, wenn im "Produkt B" die letzte und im "Produkt C" die erste Gruppe "Execute Drivers" ist, wird es bei dem Produkt C nicht angezeigt.
Ich habe gedacht, dass ich dem Spielraum schon mit dem "nodeGroup" nur an die jeweilige Produkte begrenzt habe, aber es sieht nicht so aus.
Kann mir jemand noch einen Tipp geben?
Danke :)
Kha - So 13.09.09 10:08
Du musst die Bedingung in der inneren Schleife wiederholen:
C#-Quelltext
1:
| if (nodeGroup.PreviousSibling != null && (nodeGroup.PreviousSibling.Attributes["gr"].Value != grName || nodeGroup.PreviousSibling.Attributes["prod"].Value != prodName)) |
Wenn ich das richtig sehe, müsstest du allerdings viele doppelte Einträge erhalten, da du die Schleife nicht verlässt, wenn die Bedingung nicht zutrifft (s. mein
continue).
bambam77 - So 13.09.09 14:44
Kha hat folgendes geschrieben : |
Du musst die Bedingung in der inneren Schleife wiederholen:
C#-Quelltext 1:
| if (nodeGroup.PreviousSibling != null && (nodeGroup.PreviousSibling.Attributes["gr"].Value != grName || nodeGroup.PreviousSibling.Attributes["prod"].Value != prodName)) |
Wenn ich das richtig sehe, müsstest du allerdings viele doppelte Einträge erhalten, da du die Schleife nicht verlässt, wenn die Bedingung nicht zutrifft (s. mein continue). |
Danke, jetzt sehe ich, wie wenig ich weiss... :)
Ich habe Dein Cod genutzt und es funktioniert. Ich kriege auch keine doppelte Einträge (vielleicht liegt es an dem doc.SelectNodes bei nodeGroup), ausser eine Ausnahme, wenn XML wie folgend aufgebaut ist:
XML-Daten
1: 2: 3: 4: 5: 6: 7: 8: 9:
| <documents> <doc id="" prod="Product A" ... gr="A" file="Product-A-Manual.pdf" /> <doc id="" prod="Product A" ... gr="A" file="Product-A-Manual1.pdf" /> <doc id="" prod="Product A" ... gr="Install Drivers" file="Product-A-Stuerung-Treiber-Install.msi" /> <doc id="" prod="Product A" ... gr="Execute Drivers" file="Product-A-Stuerung-Treiber-Execute.zip" /> <doc id="" prod="Product A" ... gr="Execute Drivers" file="Product-A-Stuerung-Treiber-Execute.zip" /> <doc id="" prod="Product A" ... gr="A" file="Product-A-Manual2.pdf" /> <doc id="" prod="Product B" ... gr="B" file="Product-B-Manual2.pdf" /> ... |
Leider mit precvioussibling kann man nur die unmittelbar vorausgehende Knoten prüfen. Ich habe bis jetzt darüf keine Lösung gefunden.
Danke und Grüsse
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 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!