2013-06-20 33 views
0

所以,我有我生成這個XML文件,它看起來像這樣:Linq中改寫到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"); 
    } 
+0

什麼是你需要什麼?爲什麼在執行替換操作後需要重新寫入以前的值?如果您需要再次覆蓋,然後在完成第一次操作後執行相同的操作...但是在反轉模式下... newBalance中where條件和memberName替換值... –

+0

正如您在上面的XML中看到的那樣,我可以獲得「AccountBalance」,甚至將它分配給一個變量使用 --- string accountBalance = members.Where(x => x.Element(「AccountName」)。Value == memberName).Select(x => x.Element ( 「AccountBalance」)值)。單(); ---- 但是我完成修改後無法替換XML中的值。 – Trent

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

所以這是說,讓我有一個帳戶名元素等於成員名稱的第一個成員元素,並然後設置它的AccountBalance元素到新百倫。

注意,這並沒有考慮到零點的可能性或指定名稱的元素...

1

LINQ是懶惰的評估(或延遲執行的,見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檢查)

+0

+1指出它的工作原理,如果評估linq語句。 –