0

所以我有我生成的这个 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 文件的元素中?我已经尝试了以下没有占上风的方法。还有其他想法吗?

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");
    }
4

2 回答 2

1

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

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");

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

请注意,这没有考虑空值或没有具有指定名称的元素的可能性......

于 2013-06-20T03:47:29.410 回答
1

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

于 2013-06-20T04:12:42.627 回答