static void

Xml Patterns

XLinq

private static Dictionary<string, string> ReadWithXLinq(string path)
{
    XNamespace ns = "randomURI"; //define the namespace
    var doc = XElement.Load(path); //don't need an XDocument
    //Xname = "randomURI"+"data" or "(randomURI)data"
    var dict = from data in doc.Elements(ns + "data")
    select new {
                    Name = data.Attribute("name").Value ,
                    //casting does not throw NullReference
                    Value = (string)data.Element(ns+"value")
                };
 
    return dict.ToDictionary(d => d.Name, d => d.Value );
}
 
private static void SaveWithXLinq(Dictionary<string, string> dict, string path)
{
    XNamespace ns = "randomURI"; //define the namespace
    var doc = new XElement(ns + "root",
        from d in dict
        select new XElement(ns + "data",
            new XAttribute("name", d.Key),
            new XElement(ns + "value", d.Value)
            ));
    doc.Save(path);
}

XmlDocument

    private static Dictionary<string, string> ReadWithDocument(string path)
    {
        Dictionary<string, string> dict = new Dictionary<string, string>();
 
        XmlDocument doc = new XmlDocument();
        doc.Load(path);
        //document has a default namespace <root xmlns="randomURI">
        XmlNamespaceManager nsm = new XmlNamespaceManager(doc.NameTable);
        nsm.AddNamespace("b", "randomURI"); //prefix all elements
        XmlNodeList dataList = doc.SelectNodes("/b:root/b:data", nsm);
        foreach (XmlElement data in dataList)
        {
            string name = data.GetAttribute("name");
            XmlElement value = data.SelectSingleNode("b:value", nsm) as XmlElement;
            if (value != null)
            {
                string val = value.InnerText;
                dict.Add(name, val);
            }
        }
        return dict;
    }
 
    private static void SaveWithDocument(Dictionary<string, string> dict, string path)
    {
        XmlDocument doc = new XmlDocument();
        doc.LoadXml("<root xmlns=\"randomURI\"/>"); //we have to load the namespace in
        //doc.DocumentElement.Prefix = "b"; //if rqd
        //document has a default namespace <root xmlns="randomURI">
        string nsURI = "randomURI";
        foreach (KeyValuePair<string, string> kvp in dict)
        {
            XmlElement data = doc.CreateElement("data", nsURI); //factory
            doc.DocumentElement.AppendChild(data);
            data.SetAttribute("name", kvp.Key);
            XmlElement value = doc.CreateElement("value", nsURI);
            data.AppendChild(value);
            value.InnerText = kvp.Value;
        }
        doc.Save(path);
    }

XmlReader/Writer

    private static Dictionary<string, string> ReadWithReader(string path)
    {
        Dictionary<string, string> dict = new Dictionary<string, string>();
 
        XmlReaderSettings settings = new XmlReaderSettings();
        NameTable nt = new NameTable();
        object dataNT = nt.Add("data"); //optimize comparisons with NT objects instead of string
        settings.NameTable = nt;
 
        using (XmlReader rdr = XmlReader.Create(path, settings))
        {
            while (rdr.Read())
            {
                if (rdr.NodeType == XmlNodeType.Element && rdr.LocalName.Equals(dataNT)) //NamteTable object
                { //you could jump to the next sibling (skipping childnodes) with ReadToNextSibling
                    string name = rdr.GetAttribute("name");
                    if (rdr.ReadToDescendant("value"))
                    {
                        string val = rdr.ReadElementContentAsString();
                        dict.Add(name, val);
                    }
                }
            }
        }
        return dict;
    }
 
    private static void SaveWithWriter(Dictionary<string, string> dict, string path)
    {
        string nsURI = "randomURI";
        XmlWriterSettings settings = new XmlWriterSettings();
        settings.Indent = true;
        using (XmlWriter writer = XmlWriter.Create(path, settings))
        {
            writer.WriteStartDocument(); //xml declaration
            writer.WriteStartElement("root", nsURI); //automatically add xmlns without prefix
            //writer.WriteAttributeString("xmlns", "x", null, "randomURI2"); how to add a prefix namespace
            foreach (KeyValuePair<string, string> kvp in dict)
            {
                writer.WriteStartElement("data", nsURI);
                writer.WriteAttributeString("name", "", kvp.Key);
                //writer.WriteAttributeString("x", "nspaced", "randomURI2", "value"); //adding the prefx
                writer.WriteStartElement("value", nsURI);
                writer.WriteValue(kvp.Value);
                writer.WriteEndElement();
                writer.WriteEndElement();
            }
            writer.WriteEndElement();
        }
    }

XPathDocument

 private static Dictionary<string, string> ReadWithXPath(string path)
    {
        Dictionary<string, string> dict = new Dictionary<string, string>();
 
        XPathDocument doc = new XPathDocument(path); //Load
        XPathNavigator nav = doc.CreateNavigator();
        //for the namespace we reference the navigator
        XmlNamespaceManager nsm = new XmlNamespaceManager(nav.NameTable);
        nsm.AddNamespace("b", "randomURI"); //prefix all elements
 
        XPathNodeIterator iter = nav.Select("b:root/b:data", nsm); //SelectNodes
 
        XPathExpression findValue = nav.Compile("b:value"); //optimize
        findValue.SetContext(nsm);
        while (iter.MoveNext())
        {
            XPathNavigator dataNav = iter.Current;
            string name = dataNav.GetAttribute("name", ""); //namespace is rqd
            XPathNavigator value = dataNav.SelectSingleNode(findValue);
            //you can also XmlReader rdr = dataNav.ReadSubtree();
            if (value != null)
                dict.Add(name, value.Value);
        }
        return dict;
    }
 
    private static void SaveWithXPath(Dictionary<string, string> dict, string path)
    {
        string nsURI = "randomURI";
        XmlDocument doc = new XmlDocument(); //need a document as XPathDocument is readonly
        doc.LoadXml("<root xmlns=\"randomURI\"/>"); //we have to load the namespace in
        XPathNavigator nav = doc.CreateNavigator(); //the navigator has CanEdit= true
        nav.MoveToRoot();
        nav.MoveToFirstChild(); //=/document element
        foreach (KeyValuePair<string, string> kvp in dict)
        {
            XmlWriter writer = nav.AppendChild(); //use a writer
            writer.WriteStartElement("data", nsURI);
            writer.WriteAttributeString("name", kvp.Key);
            writer.WriteStartElement("value", nsURI);
            writer.WriteValue(kvp.Value);
            writer.WriteEndElement();
            writer.Close();
            System.Diagnostics.Debug.WriteLine(nav.OuterXml);
        }
        doc.Save(path);
    }