将Linq中的元素覆盖为XML

时间:2013-06-20 03:31:20

标签: c# linq-to-xml

所以我生成了这个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>

我可以使用

成功定位Element的部分内容
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");
    }

2 个答案:

答案 0 :(得分: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");

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

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

答案 1 :(得分:1)

LINQ是Lazy-Evaluated(或Deferred Executed,请参阅this),因此上一个示例中的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