使用Linq在C#中更新XML

17

我的XML文件结构

<items>
  <item>
    <itemID>1</itemID>
    <isGadget>True</isGadget>
    <name>Star Wars Figures</name>
    <text1>LukeSkywalker</text1>
  </item>
</items>

通过 ItemId 从 XML 中读取数据

XDocument xmlDoc = XDocument.Load(HttpContext.Current.Server.MapPath("data.xml"));
var items = from item in xmlDoc.Descendants("item")
            where item.Element("itemID").Value == itemID
            select new
            {
                itemID = item.Element("itemID").Value,
                isGadget = bool.Parse(item.Element("isGadget").Value),
                name = item.Element("name").Value,
                text1 = item.Element("text1").Value,
             }

foreach (var item in items)
{
     ....
}

如何通过itemID更新XML数据? 谢谢!


1
我不明白为什么这些LINQ-to-XML问题目前如此普遍。答案就在这里。http://msdn.microsoft.com/en-us/library/bb387087.aspx - Gusdor
3个回答

19

要更新你的xml,请使用XElement的SetElementValue方法:


var items = from item in xmlDoc.Descendants("item")
    where item.Element("itemID").Value == itemID
    select item;

foreach (XElement itemElement in items)
{
    itemElement.SetElementValue("name", "Lord of the Rings Figures");
}

编辑:是的,我尝试了您的示例,它将更新的数据保存到文件中。使用XDocument的Save方法保存您的更新后的xml,以下是我尝试的代码:

string xml = @"<items>
           <item>
            <itemID>1</itemID>
            <isGadget>True</isGadget>
            <name>Star Wars Figures</name>
            <text1>LukeSkywalker</text1>
           </item>
        </items>";

XDocument xmlDoc = XDocument.Parse(xml);

var items = from item in xmlDoc.Descendants("item")
            where item.Element("itemID").Value == "1"
            select item;

foreach (XElement itemElement in items)
{
    itemElement.SetElementValue("name", "Lord of the Rings Figures");
}

xmlDoc.Save("data.xml");

无法工作。也许我漏掉了什么。我需要添加 xmlDoc.Save("data.xml") 吗?即使有 xmlDoc.Save,它仍然无法更新。 - user180485
Canavar,我希望直接更新XML文件,而不必先将其转换为字符串。谢谢! - user180485

9

要更新您的xml,请使用XElement的element方法:

XDocument xmlDoc = XDocument.Load(HttpContext.Current.Server.MapPath("data.xml"));
var items = (from item in xmlDoc.Descendants("item")
            where item.Element("itemID").Value == itemID
            select item).ToList();
         foreach (var item in items)
         {
                item.Element("itemID").Value=NewValue;
                bool.Parse(item.Element("isGadget").Value)=Newvalue;
                item.Element("name").Value=Newvalue;
                item.Element("text1").Value=Newvalue;
         }
xmlDoc.Save(HttpContext.Current.Server.MapPath("data.xml"));

或者
XDocument xmlDoc = XDocument.Load(HttpContext.Current.Server.MapPath("data.xml"));
             foreach (var item in (from item in xmlDoc.Descendants("item")
                where item.Element("itemID").Value == itemID
                select item).ToList())
             {
                    item.Element("itemID").Value=NewValue;
                    bool.Parse(item.Element("isGadget").Value)=Newvalue;
                    item.Element("name").Value=Newvalue;
                    item.Element("text1").Value=Newvalue;
             }
    xmlDoc.Save(HttpContext.Current.Server.MapPath("data.xml"));

您可以从动态中获取信息,并在按钮单击事件中更新这些更改,这意味着首先检查页面加载时是否存在以下代码:

if(!Page.IsPostBack) { .... } 

4

您的查询正在投射到一个匿名类型。如果您只想修改元素本身,您需要像这样:

var items = from item in xmlDoc.Descendants("item")
            where item.Element("itemID").Value == itemID
            select item;

又称为:

var items = xmlDoc.Descendants("item")
                  .Where(item => item.Element("itemID").Value == itemID);

我建议您也调用ToList()方法,这样整个查询将会被执行并且结果会被存储在一个列表中,在您开始修改之前:

var items = xmlDoc.Descendants("item")
                  .Where(item => item.Element("itemID").Value == itemID)
                  .ToList();

你能提供一个简单的 toList() 调用更新 XML 的例子吗?我需要使用 foreach 循环来 setElementValue 吗? - user180485
1
调用ToList()不会更新XML,是的,你需要使用foreach。不过你没有说你想如何更新XML,所以很难给出一个例子。 - Jon Skeet
不确定更新XML文档的选项是什么。也许您可以建议最有效的方法。 :) - user180485
我们真的可以推荐使用 ToList 吗?我见过初级开发人员想当然地认为无论如何都需要在每个查询之后添加 ToList 或 ToArray。我认为应该有更好的使用指南。这毕竟是使用 List<T>.ForEach() 的入口。糟糕! - Gusdor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接