如何使用LINQ-to-XML将XML节点保存回XML文件?

时间:2009-06-11 09:19:27

标签: c# linq-to-xml

我有一个XML文件,我用它来创建对象,更改对象,然后将对象保存回来到XML文件中。

我需要在以下代码中更改,以便它根据ID从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 个答案:

答案 0 :(得分:2)

嗯,错误与保存无关,甚至与更换无关 - 它与您尝试创建XElement而不指定名称有关。你为什么要尝试使用Select?我的猜测是你只想使用Single

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

(正如Noldorin所说,你可以给Single一个谓词来避免使用Where。我个人非常喜欢将这两个操作分开,但它们在语义上是等价的。)< / p>

这将返回序列中的单个元素,或者如果有0个元素或多个元素则抛出异常。替代方案是使用SingleOrDefaultFirstFirstOrDefault

  • SingleOrDefault如果有0或1
  • 是合法的
  • First如果拥有1个或更多
  • 是合法的
  • FirstOrDefault如果拥有0或更多
  • 是合法的

如果您使用的是“OrDefault”,如果没有匹配项,结果将为null

答案 1 :(得分:2)

我认为问题只是您在分配Select的语句中使用oldElementToOverwrite调用。您实际上似乎想要Single扩展方法。

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