C# XML auslesen

TresPuntos

Cadet 4th Year
Registriert
Juni 2018
Beiträge
113
Hallo,

habe eine XML-Datei, die ausgelesen werden muss:
XML:
<Rules>
    <CopyRule>
      <Name>Applications</Name>
      <Source>apps</Source>
      <Target>custom\Apps</Target>
      <Filter>*.Bsp.xml</Filter>
    </CopyRule>
    <CopyRule>
      <Name>Authorizations</Name>
      <Source>data</Source>
      <Target>custom\authorizations</Target>
      <Filter>*.Authorization.xml</Filter>
    </CopyRule>
</Rules>

Brauche dabei eure Hilfe.
Habe einen Dateinamen und will ihn mit den vorhandenen <Filter>XX</Filter> Werten vergleichen, wenn dieser gleich ist, muss ich die Datei unter dem jeweiligen <Source>XX</Source> Pfad Wert speichern.
Mein Ansatz sieht wie folgt aus:
Den Dateinamen muss ich lediglich mitgeben
bei If sollte es ein return mit dem Source-Wert geben

C#:
public void XMLReader(String PfadVonXML, String Suchpfad)
        {
            XmlReader Reader = XmlReader.Create(PfadVonXML);
            Reader.ReadStartElement("Rules");

            Suchpfad = "*." + Suchpfad; //um den Namen meiner Datei auf den Filter-Wert setzen
            Reader.ReadStartElement("Filter");
            if(Suchpfad.Equals(Reader.ReadString()))
                //soll er Source nehmen
            else
            {
                //weitersuchen
            }
        }
 
Zuletzt bearbeitet:
C# hat Möglichkeit die XML Knoten direkt anzusteuern. Mit dem rohen String musst du dann nicht arbeiten. Baue eine "CopyRule" Klasse. Die die Eigenschaften dieser sind Strings (Name, Source,...). Vergleiche currentCopyRuleObjekt.Filter mit deinem input und gebe falls es eine Übereinstimmung gibt currentCopyRuleObjekt.Source aus.

E: Die Klasse ist nicht unbedingt notwenig, du könntest auch mit den XML-Knoten arbeiten.
 
Also ich habe jetzt eine "Lösung" erarbeitet, aber es wäre besser den Knoten CopyRule anzusprechen und den Name-Knoten zu vergleichen und wenn er gleich ist den zugehörigen Wert des Source-Knoten mitzugeben.
Aktuell gibt er mit nur den nächsten Wert des Elementes aus, also ist das ziemlich statisch. Es könnte ja sein, dass die Struktur mal anders ist.
@breedmaster im Prinzip habe ich deine Idee mit der Klasse verstanden, nur wie übergebe ich die Inhalte in einer CopyRule weiter?


C#:
public void XMLReader(String wert)
        {
            if (File.Exists(@"C:\Users\tro\Documents\Pfad3\rules.xml"))
            {
                XmlTextReader reader = new XmlTextReader(@"C:\Beispiel\Pfad3\rules.xml");
                bool shouldReadId = false;
                while (reader.Read())
                {
                    if (reader.NodeType == XmlNodeType.Text && shouldReadId)
                    {
                        MessageBox.Show("kk: " + reader.Value);
                        shouldReadId = false;
                    }

                    if (reader.Value.Equals(wert))
                    {
                        shouldReadId = true;
                    }
                }
            }
            else
            {
                MessageBox.Show("Die rules.xml Datei existiert nicht");
            }

        }
    }
 
Zuletzt bearbeitet:
Egal, ob du eine Klasse nutzt oder die Werte direkt ausgibst versuche mal mit dem folgenden zu arbeiten:

https://msdn.microsoft.com/de-de/library/system.xml.xmldocument(v=vs.110).aspx

ChildNodes
NextSibling

Wenn ich das richtig sehe kannst du bei deiner Variante im Moment nicht zwischen den CopyRules unterschieden.

Wenn deine Struktur immer die gleiche ist(Rheienfolge, Anzahl), kannst du - gerade am Anfang - erstmal nach Rheienfolge arbeiten, du muss den Nodename nicht prüfen.
 
@breedmaster Ja genau, die Methode funktioniert zwar, ist aber zu statisch, weil es nach dem <Namen> sucht und dann den <source> Wert nimmt.
Optimal wäre es natürlich das dynamisch zu machen und nach <CopyRule> suchen und die Werte als Eigenschaften zu haben.
Ich versuche mal deinen Vorschlag
 
Ist meine Lösung geworden.
Gibt bestimmt viel bessere Möglichkeiten, die versuche ich aber noch rauszusuchen.
Bei dem String wert wird der eingegebene Wert mit <Name> auf Gleichheit geprüft und dann entsprechend der <Source> Wert ausgegeben, wenn <Name> und wert übereinstimmt.

C#:
        public String XMLReader(String wert, String rulesPfad)
        {
            if (File.Exists(rulesPfad))
            {
                XmlTextReader d = new XmlTextReader(rulesPfad);
                while (d.Read())
                {
                    if (d.NodeType == XmlNodeType.Element)
                    {
                        if (d.Name == "CopyRule")
                        {
                            String k = d.ReadInnerXml();
                            XmlDocument doc = new XmlDocument();
                            doc.LoadXml("<root>" +
                                        "<elem>" + k + "</elem>" +
                                        "</root>");
                            //Display all the book titles
                            XmlNodeList elemList = doc.GetElementsByTagName("Name");
                            for (int i = 0; i < elemList.Count; i++)
                            {
                                if (elemList[i].InnerXml == wert)
                                {
                                    XmlNodeList kk = doc.GetElementsByTagName("Source");
                                    for (int ik = 0; ik < kk.Count; ik++)
                                    {
                                        return kk[ik].InnerXml;
                                    }
                                    continue;
                                }
                                continue;
                            }
                            continue;
                        }
                        else
                        {
                            continue;
                        }
                    }
                    else
                    {
                        continue;
                    }
                }
                MessageBox.Show("Es wurde in der rules.xml kein Pfad für die " + wert + "-Datei gefunden");
                return "";
            }
            else
            {
                MessageBox.Show("Die rules.xml Datei existiert nicht, deswegen wurden alle <AppName>." + wert + ".xml Dateien unter der jeweiligen App gespeichert");
                return "";
            }
        }
 
Ich guckst mir später nochmal genauer an. Aber versuche mal was aufzuräumen. Du läds ja mitten drin auch wieder eine XML, was unnötig ist. Da deine XML deterministisch ist, kannst du auch - zumindest in der Roh-Version - auf "d.Name == "CopyRule"" verzichten.
Du weißt vorher schon wann deine Nodes auftauchen. Du musst eigentlich "nur"
Code:
if(currentNode.Filter == input)
return currentNode.Source
machen.
 
Zurück
Oben