C# поиск и замена атрибутов XML



У меня есть выходной XML-файл со следующей структурой



<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>


Комбинация даты и времени уникальна. Как на основе времени и даты я могу проанализировать значение, которое изменит атрибут saveName?
Как лучше всего это сделать?

Вот что я написал



    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);

}


Тоже пробовал это



            //  <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);
};


ПС. Однако мой код ничего не меняет.

543   2  

2 ответов:

Если у вас есть только фрагмент Xml (как в вашем примере) , вы можете использовать этот код:

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

root это ваш элементOFBM ... поэтому root.Element("OFBM") равно нулю

Правка:

Если у вас есть xml с несколькимиOFBM элементами (я думаю, что у вас есть более одного). Используйте это:

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:

<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>

Есть пара проблем:

XElement root = XElement.Load(pathToXml);

Здесь, root есть OFBM. Поэтому при запросе root.Elements() возвращаемые элементы будут дочерними по отношению к OFBM, т. е. 3 folder элемента. Это означает, что ваш запрос root.Elements("OFBM") никогда не вернет никаких элементов.

Во-вторых, ReplaceWith заменит весь элемент некоторым текстом. Вы хотите задать значение атрибута saveName.

Этот код будет работать:

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");

Comments

    Ничего не найдено.