Как сохранить узел XML обратно в файл XML с помощью LINQ-to-XML? - PullRequest
0 голосов
/ 11 июня 2009

У меня есть файл XML, который я использую для создания объектов, изменения объектов, а затем сохранения объектов обратно в файл XML.

Что я должен изменить в следующем коде , чтобы он извлекал узел из XML на основе идентификатора, заменял этот узел новым и сохранял его обратно в XML?

Следующее дает мне 'System.Xml.Linq.XElement' не содержит конструктор, который принимает '0' аргументов ':

//GET ALL SMARTFORMS AS XML
XDocument xmlDoc = null;
try
{
    xmlDoc = XDocument.Load(FullXmlDataStorePathAndFileName);
}
catch (Exception ex)
{
    HandleXmlFileNotFound(ex);
}

//EXTRACT THE NODE THAT NEEDS TO BE REPLACED
XElement oldElementToOverwrite = xmlDoc.Descendants("smartForm")
    .Where(sf => (int)sf.Element("id") == 2)
    .Select(sf => new XElement());

//CREATE THE NODE THAT WILL REPLACE IT
XElement newElementToSave = new XElement("smartForm",
                              new XElement("id", this.Id),
                              new XElement("idCode", this.IdCode),
                              new XElement("title", this.Title)
                              );

//OVERWRITE OLD WITH NEW
oldElementToOverwrite.ReplaceWith(newElementToSave);

//SAVE XML BACK TO FILE
xmlDoc.Save(FullXmlDataStorePathAndFileName);

XML-файл:

<?xml version="1.0" encoding="utf-8" ?>
<root>
  <smartForm>
    <id>1</id>
    <whenCreated>2008-12-31</whenCreated>
    <itemOwner>system</itemOwner>
    <publishStatus>published</publishStatus>
    <correctionOfId>0</correctionOfId>
    <idCode>customerSpecial</idCode>
    <title>Edit Customer Special</title>
    <description>This form has a special setup.</description>
    <labelWidth>200</labelWidth>
  </smartForm>
  <smartForm>
    <id>2</id>
    <whenCreated>2008-12-31</whenCreated>
    <itemOwner>system</itemOwner>
    <publishStatus>published</publishStatus>
    <correctionOfId>0</correctionOfId>
    <idCode>customersMain</idCode>
    <title>Edit Customer</title>
    <description>This form allows you to edit a customer.</description>
    <labelWidth>100</labelWidth>
  </smartForm>
  <smartForm>
    <id>3</id>
    <whenCreated>2008-12-31</whenCreated>
    <itemOwner>system</itemOwner>
    <publishStatus>published</publishStatus>
    <correctionOfId>0</correctionOfId>
    <idCode>customersNameOnly</idCode>
    <title>Edit Customer Name</title>
    <description>This form allows you to edit a customer's name only.</description>
    <labelWidth>100</labelWidth>
  </smartForm>
</root>

Ответы [ 2 ]

2 голосов
/ 11 июня 2009

Мне кажется, проблема в том, что вы просто используете вызов Select в операторе присваивания oldElementToOverwrite. Похоже, вам действительно нужен метод расширения Single.

XElement oldElementToOverwrite = xmlDoc.Descendants("smartForm")
    .Single(sf => (int)sf.Element("id") == 2)
2 голосов
/ 11 июня 2009

Ну, ошибка не имеет ничего общего с сохранением или даже с заменой - она ​​связана с тем, что вы пытаетесь создать XElement без указания имени. Почему вы пытаетесь использовать Select вообще? Я думаю, вы просто хотите использовать Single:

XElement oldElementToOverwrite = xmlDoc.Descendants("smartForm")
    .Where(sf => (int)sf.Element("id") == 2)
    .Single();

(Как отмечает Нолдорин, вы можете дать Single предикат, чтобы вообще не использовать Where. Лично мне очень нравится разделять две операции, но они будут семантически эквивалентны.)

Это вернет единственный элемент в последовательности или сгенерирует исключение, если имеется 0 элементов или более одного. Альтернативы могут использовать SingleOrDefault, First или FirstOrDefault:

  • SingleOrDefault если законно иметь 0 или 1
  • First если законно иметь 1 или более
  • FirstOrDefault если законно иметь 0 или более

Если вы используете «OrDefault», результат будет null, если совпадений нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...