将Linq中的元素覆盖为XML

本文关键字:覆盖 XML 元素 Linq | 更新日期: 2023-09-27 18:19:03

生成的XML文件是这样的

<?xml version="1.0" encoding="utf-8"?>
<Members xmlns="urn:lst-emp:emp">
  <Member xmlns="">
    <!--Info for Member TESTER-->
    <AccountName>Test Name</AccountName>
    <AccountNumber>Test Number</AccountNumber>
    <AccountBalance>Test Balance</AccountBalance>
  </Member>
  <Member xmlns="">
    <!--Info for Member Jeff Reed-->
    <AccountName>Jeff Reed</AccountName>
    <AccountNumber>5929</AccountNumber>
    <AccountBalance>9223.01</AccountBalance>
  </Member>
</Members>

我可以用

成功地定位元素的某些部分
XElement xelement = XElement.Load(Application.LocalUserAppDataPath + "''members.xml");
IEnumerable<XElement> members = xelement.Elements();
members.Where(x => x.Element("AccountName").Value == memberName).Select(x => x.Element("AccountNumber").Value).Single();

并将其分配给一个变量或其他东西,但是在我更改了这个变量之后,我如何将它覆盖回XML文件中的Element中呢?我试过以下方法,但没有成功。还有其他想法吗?

internal static void overwriteAccountBalance(string memberName, string newBalance)
    {
        XElement xelement = XElement.Load(Application.LocalUserAppDataPath + "''members.xml");
        IEnumerable<XElement> members = xelement.Elements();
        members.Where(x => x.Element("AccountName").Value == memberName).Select(x => x.Element("AccountBalance").Value = newBalance);
        xelement.Save(Application.LocalUserAppDataPath + "''members.xml");
    }

将Linq中的元素覆盖为XML

您需要选择元素,然后设置值。像这样:

XElement xelement = XElement.Load("C:''members.xml");
IEnumerable<XElement> members = xelement.Elements();
members.First(x => x.Element("AccountName").Value == memberName).Element("AccountBalance").Value = newBalance;
xelement.Save("C:''members.xml");

这就是说,给我第一个成员元素它的AccountName元素等于memberName,然后然后设置它的AccountBalance元素为newBalance

LINQ是延迟计算的(或延迟执行的,参见此),因此上一个示例中的select语句将永远不会执行。要强制LINQ查询求值,请使用返回非IEnumerable形式的数据的方法(如ToArray()、First()、Single()、ToList()等)。

internal static void overwriteAccountBalance(string memberName, string newBalance)
{
    XElement xelement = XElement.Load(Application.LocalUserAppDataPath + "''members.xml");
    IEnumerable<XElement> members = xelement.Elements();
    //ToArray() forces the query to evaluate
    members.Where(x => x.Element("AccountName").Value == memberName).Select(x => x.Element("AccountBalance").Value = newBalance).ToArray();
    xelement.Save(Application.LocalUserAppDataPath + "''members.xml");
}

将结果存储在foreach循环中并对其求值,使其也执行。

internal static void overwriteAccountBalance(string memberName, string newBalance)
{
    XElement xelement = XElement.Load(Application.LocalUserAppDataPath + "''members.xml");
    IEnumerable<XElement> members = xelement.Elements();
    //Evaluate part of the query and do the rest yourself
    foreach(XElement member in members.Where(x => x.Element("AccountName").Value == memberName))
    {
        XElement accountBalance = member.Element("AccountBalance");
        if(accountBalance != null)
        {
             accountBalance.Value = newBalance;
        }
    }
    xelement.Save(Application.LocalUserAppDataPath + "''members.xml");
}

我更喜欢第二种,因为它允许您轻松地提供更好的条件处理(如检查null)