Entwickler-Ecke

IO, XML und Registry - XML Datei editieren


doubleII - Fr 23.02.18 17:17
Titel: XML Datei editieren
Hallo zusammen,

könnte mir jemand Tip geben.

ich möchte in einer xml Datei folgendes editieren (logger/minlevel= "Trace"). Der minlevel Wert möchte ich ändern. Das Problem ist, ich habe keinen Zugriff auf den Attributen.

xml code:

XML-Daten
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
<?xml version="1.0" encoding="utf-8"?>

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

  <targets>
    <target name="file" xsi:type="File"
            fileName="${specialfolder:folder=LocalApplicationData}"
            layout="${longdate} | ${Level:uppercase=true} | ${message} | ${exception:format=ToString,Message:maxInnerExceptionLevel=4:innerFormat=ToString,Message:innerExceptionSeparator=|}" />
  </targets>

  <rules>
    <logger name="*" minlevel="Trace" writeTo="file" />
  </rules>
</nlog>


C# Code:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
                try
                {                   
                    XmlDocument doc = new XmlDocument();
                    string xPath = @"C:\Users\SupportLayer\NLog.config";

                    doc.Load(xPath);
        
                                               
                    XmlNode n = doc.SelectSingleNode("nlog/rules/logger").Attributes["minlevel"].Value = level;
            
                    if (selectedNode == null)
                    {
                        Console.WriteLine("n is null");
                    }

                    doc.Save(xPath);
                }


das Problem ist, dass XmlNode n bleibt null. hat jemand eine Idee, was ich falsch mache.

Danke!


Moderiert von user profile iconTh69: Topic aus Sonstiges (.NET) verschoben am Fr 23.02.2018 um 17:25
Moderiert von user profile iconTh69: C#-Tags hinzugefügt
Moderiert von user profile iconTh69: Titel geändert ("problem" entfernt).


Th69 - Fr 23.02.18 18:31

Bist du sicher, daß der Code kompiliert?
Du hast in der SelectSingleNode-Zeile zwei Zuweisungen drin (mit unterschiedlichen Typen).
Außerdem fragst du danach selectedNode anstatt n ab.


doubleII - Fr 23.02.18 19:43

stimmt du hast recht ich muss mich korrigieren.



C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
 try
                {                   
                    XmlDocument doc = new XmlDocument();
                    string xPath = @"C:\Users\SupportLayer\NLog.config";

                    doc.Load(xPath);
                                   
                    doc.SelectNodes("nlog/rules/logger").Attributes["minlevel"].Value = level;
            
                    if (selectedNode == null)
                    {
                        Console.WriteLine("n is null");
                    }

                    doc.Save(xPath);
                }


so funktioniert auch nicht:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
 try
                {                   
                    XmlDocument doc = new XmlDocument();
                    string xPath = @"C:\Users\SupportLayer\NLog.config";

                    doc.Load(xPath);
                                   
                    var n = doc.SelectSingleNode("nlog/rules/logger:minlevel"); // der Pfad wird nicht gefunden 
            
                    if (c == null)
                    {
                        Console.WriteLine("n is null");
                    }
                    else
                    {
                        n.InnerText = level;
                        doc.Save(xPath);
                    }
                    
                }


Ich habe über XmlNameSpace Klasse gelesen, aber ich habe keine namespace bei logger.


Ralf Jansen - Fr 23.02.18 20:50

logger steckt aber in einem Knoten der zu einem Namespace gehört.
Mußt daher leider den Namespace angeben.


C#-Quelltext
1:
2:
3:
XmlNamespaceManager mgr = new XmlNamespaceManager(doc.NameTable);
mgr.AddNamespace("x""http://www.nlog-project.org/schemas/NLog.xsd");     
var selectedNode = doc.SelectSingleNode("x:nlog/x:rules/x:logger", mgr);


doubleII - Fr 23.02.18 21:31

ja das stimmt, ich habe auch mit XmlNameSpaceManager versucht.
Es war mir aber nicht klar, was man in Zeile 3 schreibt. Jetzt verstehe ich.
Danke!

Übrigens, wenn ich nach einer bestimmten Knote(node) suchen möchte.

Z.B.


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:
 public static void OpenXlmFile(string str)
            {
                XmlDocument doc = new XmlDocument();
                string path = "XML/NLog.config";
                try
                {
                    doc.Load(path);
                    XmlNode node = doc.DocumentElement; // hier stürzt das Program ab.
                    if (node != null)
                    {
                        foreach (var n in node.ChildNodes)
                        {
                            if (node.Name.Equals("logger"))
                            {
                                // tue was bitte
                            }
                        }                      
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    throw;
                }
                
            }


Brauche ich XmlNameSpaceManager Klass, oder?

hier noch ein Beispiel:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
XmlDocument doc = new XmlDocument();
            string path = @"C:\MyFiles\XMLFile1.xml";
            doc.Load(path);
            IEnumerator ie = doc.SelectNodes("/appSettings/add").GetEnumerator();

            while (ie.MoveNext())
            {
                if ((ie.Current as XmlNode).Attributes["key"].Value == "ServerAddress")
                {
                    (ie.Current as XmlNode).Attributes["value"].Value = "hello";
                }
            }

            doc.Save(path);


Ralf Jansen - Fr 23.02.18 21:42

Iterieren sollte eigentlich auch funktionieren. logger ist aber nicht direkt in dem Knoten. Du müßtest da noch eine weiter Schleife einbauen. Erst in den ChildNodes rules suchen. Und im rules node dann wiederum in dessen ChildNodes den logger Node. Da ist XPath (sobald das funktioniert :wink: ) irgendwie einfacher.


doubleII - Fr 23.02.18 23:44

ja du hast recht, mit XPath ist es super einfach. Ich habe mir nur gedacht, wie man den ganzen tree durchlaufen kann.

Danke noch mal!


:beer: