Linq to XML - удалить узел и добавить новый узел в том же месте
У меня есть XDocument, и я должен удалить узел и снова добавить тот же самый узел после некоторых манипуляций (мой узел xelement сложен и также имеет внутренние узлы). У кого-нибудь есть хороший способ сделать это, так как мой новый манипулируемый узел добавляется в самом конце xmldocument. Любые фрагменты кода будут с благодарностью.
3 ответа
Если вы просто редактируете узел, то зачем вообще его удалять? Просто получите ссылку на него в дереве и отредактируйте его на месте.
Если по какой-то причине это не вариант, то один из способов это сделать: как только вы нашли XElement
(или вообще XNode
) нужно заменить в дереве, создать новый XElement
служить заменой, а затем использовать XNode.ReplaceWith
метод для старого элемента, передавая новый в качестве аргумента.
Если я вас правильно понимаю, это должно помочь вам сделать это.
SolarSystem.xml:
<?xml version="1.0" encoding="UTF-8"?>
<SolarSystem>
<Planets>
<Planet Id="1">
<Name>Mercury</Name>
</Planet>
<Planet Id="2">
<Name>Venus</Name>
</Planet>
<Planet Id="3">
<Name>Earth</Name>
</Planet>
</Planets>
</SolarSystem>
Код находит <Planet>
Меркурий, добавляет к нему дополнительный элемент, удаляет его и вставляет в конце <Planets>
коллекция.
XDocument SolarSystem = XDocument.Load(Server.MapPath("SolarSystem.xml"));
IEnumerable<XElement> Planets = SolarSystem.Element("SolarSystem").Element("Planets").Elements("Planet");
// identify and change Mercury
XElement Mercury = Planets.Where(p => p.Attribute("Id").Value == "1").FirstOrDefault();
Mercury.Add(new XElement("YearLengthInDays", "88"));
// remove Mercury from current position, and add back in at the end
Mercury.Remove();
Planets.Last().AddAfterSelf(Mercury);
// save it as new file
SolarSystem.Save(Server.MapPath("NewSolarSystem.xml"));
который дает:
<?xml version="1.0" encoding="UTF-8"?>
<SolarSystem>
<Planets>
<Planet Id="2">
<Name>Venus</Name>
</Planet>
<Planet Id="3">
<Name>Earth</Name>
</Planet>
<Planet Id="1">
<Name>Mercury</Name>
<YearLengthInDays>88</YearLengthInDays>
</Planet>
</Planets>
</SolarSystem>
Это просто основано на примере @Ralph Lavelle выше. Я создал полноценное консольное приложение, чтобы я мог поиграть с кодом и лучше понять его. Я решил поделиться этим. Он использует точно такой же пример XML из приведенного выше, но мне пришлось удалить ссылки на Server.MapPath(), так как я не мог понять, как заставить их работать. Ну вот:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
class LinqDemo
{
static void Main( )
{
XDocument SolarSystem = XDocument.Load("SolarSystem.xml");
IEnumerable<XElement> Planets = SolarSystem.Element("SolarSystem").Element("Planets").Elements("Planet");
// identify and change Mercury
XElement Mercury = Planets.Where(p => p.Attribute("Id").Value == "1").FirstOrDefault();
Mercury.Add(new XElement("YearLengthInDays", "88"));
// remove Mercury from current position, and add back in at the end
Mercury.Remove();
Planets.Last().AddAfterSelf(Mercury);
// save it as new file
SolarSystem.Save("NewSolarSystem.xml");
}
}
Может быть, это поможет другому LINQ Noob, как я.