C# finding and replacing attributes XML

Viewed 144

I have an output XML file with the following structure

<OFBM time="10:32" date="06.10.2017" saveName="Unnamed save">
<folder name="file:///C:/Users/AD/Downloads" />
<folder name="file:///C:/Users/AD/Desktop/t" />
<folder name="file:///C:/ProgramData/OFBM" />
</OFBM>

date and time combination are unique. How based on time, and date, I can parse a value that will change the saveName attribute? What's the best way of doing it?

This is what I wrote up

    public void saveNames(string time, string date, string folderName)
    {
    if(folderName == "Unnamed save")
    return;
    XElement root = XElement.Load(pathToXml);
        IEnumerable<XElement> address =
            from el in root.Elements("OFBM")
            where (string)el.Attribute("time") == time
            where (string)el.Attribute("date") == date
            select el;
        foreach (XElement el in address.Elements("saveName"))
        {
            el.ReplaceWith(folderName);

        }
        root.Save(pathToXml);

    }

Also tried this

            //  <OFBM time="10:30" date="06.10.2017" saveName="Unnamed save">
        XPathDocument document = new XPathDocument(pathToXml);
        //The XPathNavigator object is used for read-only XPath queries. The XPath queries may return a resulting value or many nodes
        XPathNavigator documentNav = document.CreateNavigator();
        // This expression uses standard XPath syntax.
        string filter = "@*";
        XPathNodeIterator NodeIter = documentNav.Select(filter);
        while (NodeIter.MoveNext())
        {
            Console.WriteLine("Save: {0}", NodeIter.Current.Value);
        };

PS. My code changes nothing, however.

2 Answers

If you have only the Xml Snippet (like in your example) you can use this code:

if (root.Attribute("time").Value == time && 
    root.Attribute("date").Value == date &&
    root.Attribute("saveName") != null)
{
    root.Attribute("saveName").Value = folderName;
}

root is your OFBM Element ... therefore root.Element("OFBM") is null

EDIT:

If you have a xml with several OFBM elements (i think you have more than one). Use this:

var address = root.Elements("OFBM").Where(element =>
    element.Attribute("time").Value == time &&
    element.Attribute("date").Value == date &&
    element.Attribute("saveName") != null);

foreach (XElement el in address)
{
    el.Attribute("saveName").Value = folderName;
}

Xml Example:

<root>
  <OFBM time="10:32" date="06.10.2017" saveName="Unnamed save">
   <folder name="file:///C:/Users/AD/Downloads" />
   <folder name="file:///C:/Users/AD/Desktop/t" />
   <folder name="file:///C:/ProgramData/OFBM" />
  </OFBM>
  <OFBM time="10:42" date="06.10.2017" saveName="Unnamed save">
   <folder name="file:///C:/Users/AD/Downloads" />
   <folder name="file:///C:/Users/AD/Desktop/t" />
   <folder name="file:///C:/ProgramData/OFBM" />
  </OFBM>
</root>

There are a couple of problems:

XElement root = XElement.Load(pathToXml);

Here, root is OFBM. So when you query root.Elements(), the elements returned will be the children of OFBM, i.e. 3 folder elements. This means your query root.Elements("OFBM") will never return any elements.

Secondly, ReplaceWith will replace the entire element with some text. You want to set the saveName attribute value.

This code would work:

var root = XElement.Load("path/to/file.xml");

if ((string) root.Attribute("time") == "10:32" && 
    (string) root.Attribute("date") == "06.10.2017")
{
    root.SetAttributeValue("saveName", "new folder name");
}

root.Save("path/to/file.xml");
Related