There is a document of the following type:

<?xml version="1.0"?> <Settings> <section idCat="section1"> <key1>value</key1> <key2>value</key2> <key3>value</key3> </section> <section idCat="section2"> <key1>value</key1> <key2>value</key2> <key3>value</key3> </section> </Settings> 

The task is to write a key-value pair into a certain category, and also to read such a pair from a certain category. I'm confused in endless XmlDocument, XPathNavigator and so on, please help me figure it out. Language C #.

  • 2
    Do you have to do it manually? Maybe use serialization in an XML object (Example - ru.stackoverflow.com/questions/207217/… ) - Daniel Protopopov
  • There are a couple of similar issues with solutions that may be useful: one and two . - BlackWitcher
  • Serialization is not suitable, because You need to transfer an existing ini file to the xml format. - Oblfakir

2 answers 2

If you do not want to suffer with all the features of the XML-DOM, then try using LiNQtoXML. The namespace is System.Xml.Linq , the main working class is XElement .

Downloading the original xml:

 var myDoc = XElement.Load("myFile.xml"); 

You can also use the static XElement.Parse(string) method if the source is a string.

We are looking for the desired item:

 var element = myDoc.Descendants("elementName").FirstOrDefault(); 

We read and write the value of the element:

 var elValue = element?.Value; element.Value = "newValue";//элемент должен существовать 

We read and write the attribute:

 var attrValue = element?.Attribute("attrName")?.Value; element.Attribute("attrName").Value = "newAttrValue"; 

Add a nested element with a text value and an attribute

 element.Add(new XElement("subElement", "value", new XAttribute("attrName","AttrValue")); 

Save the result to disk

 myDoc.Save("fileName") 

As you can see everything is quite transparent and clear. XMLtoLiNQ fully supports the classic XML-DOM, but does it more elegantly than the older approach implemented in XmlDocument and related classes.

The link documentation below contains examples in sufficient quantity to understand and links to the description of the accompanying classes.
XDocument class
XElement class

    Different ways of reading xml, and also if the number of keys is unknown, the last specified method

     using System; using System.Collections.Generic; using System.IO; using System.Xml; using System.Xml.Linq; using System.Linq; using System.Xml.Serialization; namespace ConsoleApplication20 { [XmlRoot("Settings")] public class XmlRecordList { [XmlElement("section")] public List<XmlRecord> Items { get; set; } } public class XmlRecord { [XmlAttribute("idCat")] public string idCat { get; set; } [XmlElement("key1")] public string key1 { get; set; } [XmlElement("key2")] public string key2 { get; set; } [XmlElement("key3")] public string key3 { get; set; } } public class SomeOtherClass { public string idCat { get; set; } public string key1 { get; set; } public string key2 { get; set; } public string key3 { get; set; } } public class SomeOtherClass2 { public string idCat { get; set; } public Dictionary<string, string> keys { get; set; } } class Program { static void Main(string[] args) { XmlRecordList result = null; using (StreamReader streamReader = new StreamReader("1.xml")) { var ser = new XmlSerializer(typeof(XmlRecordList)); result = (XmlRecordList)ser.Deserialize(streamReader); } using (StreamWriter streamWriter = new StreamWriter("2.xml")) { var ser = new XmlSerializer(typeof(XmlRecordList)); ser.Serialize(streamWriter, result); } //или Linq List<SomeOtherClass> Records = (from xmlInput in XDocument.Load("1.xml").Descendants("section") select new SomeOtherClass { idCat = xmlInput.Attribute("idCat").Value, key1 = xmlInput.Element("key1").Value, key2 = xmlInput.Element("key2").Value, key3 = xmlInput.Element("key3").Value }).ToList(); //если количество ключей неизвестно, то можно их загрузить в коллекцию следующим образом List<SomeOtherClass2> Settings = (from xmlInput in XDocument.Load("1.xml").Descendants("section") select new SomeOtherClass2 { idCat = xmlInput.Attribute("idCat").Value, keys = xmlInput.Descendants().ToDictionary(x=>x.Name.ToString(), x=>x.Value.ToString()) }).ToList(); } } } 
    • I understand that this option is suitable if each section contains only a specific number of elements with the specified names. The problem is that in my case the elements point to certain settings, and therefore they are called differently and the categories contain different numbers of elements. - Oblfakir
    • Different number of elements can be downloaded, for example, in the Dictionary. Corrected an example. - Ivan Plyusnin