Laden...

[gelöst]XmlNode liest nicht die Werte ein die es soll

Erstellt von cenTrem vor 9 Jahren Letzter Beitrag vor 9 Jahren 1.049 Views
C
cenTrem Themenstarter:in
4 Beiträge seit 2014
vor 9 Jahren
[gelöst]XmlNode liest nicht die Werte ein die es soll

verwendetes Datenbanksystem: XML

Moin zusammen,

ich bin neu hier im Forum und auch neu im Umgang mit C#. Im Moment arbeite ich an einem kleinem Tool welches aus einer XML-Datei Werte auslesen soll und diese in ein dataGridView überträgt. Leider stehe ich im Moment etwas aufm Schlauch.

Wenn ich den Code ausführe liest er die XML soweit ein, allerdings fügt er immer nur den Wert des ersten Attributs "SubtypeId" welches "Stone" ist in das dataGridView ein. Ich habe ein Bild angehängt as dabei raus kommt.

Beim debuggen ist mir aufgefallen, dass die Werte in der XmlNode item und result dem Werten aus dem ersten durchlauf entsprechen. In der Quell-XmlNode blueprint sind diese aber korrekt angegeben. Ich verstehe nicht warum er diese nicht übernimmt und stattdessen immer wieder den Wert aus dem ersten durchlauf nimmt.
Für Hilfreiche Tipps, und Gedankenanregungen wäre ich Dankbar.


  <Blueprints>
    <Blueprint>
      <Prerequisites>
        <Item Amount="1" TypeId="Ore" SubtypeId="Stone" />
      </Prerequisites>
      <Result Amount="0.9" TypeId="Ingot" SubtypeId="Stone" />
      <BaseProductionTimeInSeconds>0.1</BaseProductionTimeInSeconds>
    </Blueprint>
    <Blueprint>
      <Prerequisites>
        <Item Amount="1" TypeId="Ore" SubtypeId="Iron" />
      </Prerequisites>
      <Result Amount="0.7" TypeId="Ingot" SubtypeId="Iron" />
      <BaseProductionTimeInSeconds>0.05</BaseProductionTimeInSeconds>
    </Blueprint>
    <Blueprint>
      <Prerequisites>
        <Item Amount="1" TypeId="Ore" SubtypeId="Nickel" />
      </Prerequisites>
      <Result Amount="0.4" TypeId="Ingot" SubtypeId="Nickel" />
      <BaseProductionTimeInSeconds>2</BaseProductionTimeInSeconds>
    </Blueprint>
  </Blueprints>


        public Form1()
        {
            InitializeComponent();
            dataGridViewRessourcen.Columns.Add("ressource", "Ressource (ingot)");
            dataGridViewRessourcen.Columns.Add("costs", "Costs per 1000kg (PL)");
            dataGridViewRessourcen.Columns.Add("amount", "Amount (kg)");

            XmlDocument blueprints = new XmlDocument();
            blueprints.Load(@".\Data\Blueprints.sbc");
            
            XmlNodeList data = blueprints.SelectNodes("//Blueprint");

            foreach (XmlNode blueprint in data)
            {
                XmlNode item = blueprint.SelectSingleNode("//Prerequisites/Item");
                if(item.Attributes["TypeId"].InnerText == "Ore")
                {
                    XmlNode result = blueprint.SelectSingleNode("//Result");
                    Double Wert = Convert.ToDouble(result.Attributes["Amount"].InnerText, CultureInfo.InvariantCulture);
                    dataGridViewRessourcen.Rows.Add(result.Attributes["SubtypeId"].InnerText, Math.Round((1 / Wert / 200)*1000, 4));
                }
  
            }

       }

K
89 Beiträge seit 2013
vor 9 Jahren

Hast du mal geschaut, was in deiner XmlNodeList data alles drin ist? Vielleicht ist da ja schon der Fehler.

C
cenTrem Themenstarter:in
4 Beiträge seit 2014
vor 9 Jahren

Moin und danke erstmal für den Hilfeanschub. Habe dies eben nochmals geprüft. In Data stehen die Werte korrekt drin. Die XmlNode blueprint übernimmt dann auch die richtigen Werte beim jeweiligen Durchlauf der Schleife. Vermutlich wäre hier eine Lösung einfach auf diese Werte direkt zuzugreifen ohne die SubNodes in ein weiteres XmlNode einzulesen. Da hängt es nämlich.

Obwohl in der blueprint sowohl unter //result als auch unter //item "Iron" steht, bekommen die XmlNodes result und item "Stone".

Für mich sieht das eigentlich nach nem Bug in C# aus hust
Aber das kann ich mir nicht vorstellen. Ich muss irgendwas übersehen haben oder irgendwo nen Logikfehler drin haben.

Übrigens. Wenn ich anstelle von SelectNodes() ChildNodes[] verwende und diese in die XmlNodes result und item einlese funktionierts. Allerdings wollte ich gerne die Nodes per Namen ansprechen und nicht über indizies. Oder kann man auch via ChildNodes[] die Nodes per Namen ansprechen?
Zumindest habe ich bisher keinen Weg gefunden oder einfach nicht richtig gegoogelt.

H
523 Beiträge seit 2008
vor 9 Jahren

Entferne mal die beiden Slashes in dieser Zeile, dann sollte es gehen:


XmlNode result = blueprint.SelectSingleNode("//Result");

Neu:


XmlNode result = blueprint.SelectSingleNode("Result");

C
cenTrem Themenstarter:in
4 Beiträge seit 2014
vor 9 Jahren

Hallo hypersurf,

ES FUNKTIONIERT !!! VIELEN VIELEN DANK FÜR DEINE HILFE !!!!

Zwar verstehe ich das noch nicht so ganz da bei "SelectNodes()" ein // verwendet werden kann um direkt auf die Node zuzugreifen.

Danke nochmal für die Hilfe 😃

C
cenTrem Themenstarter:in
4 Beiträge seit 2014
vor 9 Jahren

Das Zauberwort lautet hier XPath
Wenn ich mir das mal vorher zu gemüte geführt hätte wäre diese Frage nicht entstanden.

Thema ist gelöst Vielen Dank nochmal an alle die geholfen haben.