2013-08-29 37 views
27

Gần đây tôi đã bắt đầu học C# và tôi gặp sự cố khi sử dụng XML.Linq để lưu trữ dữ liệu. Tôi hy vọng câu hỏi này là dễ hiểu vì tôi chưa quen với tất cả các thuật ngữ chính xác và vì tiếng Anh không phải là ngôn ngữ đầu tiên của tôi.Chỉnh sửa phần tử cụ thể trong XDocument

Tôi đọc rất nhiều câu hỏi/googled nhưng tôi không thể tự mình tìm ra.

Tôi muốn cập nhật một tập tin XDocument hiện trông như thế này:

<Data> 
    <IDCounter>2</IDCounter> 
    <Highscores> 
    ....... 
    </Highscores> 
    <savegames> 
    <savegame> 
     <IdNumber>1</IdNumber> 
     <salutation>Mr</salutation> 
     <prename>Prename1</prename> 
     <surname>Surname1</surname> 
     <maximumbalance>100</maximumbalance> 
     <balance>100</balance> 
    </savegame> 
    <savegame> 
     <IdNumber>2</IdNumber> 
     <salutation>Mr</salutation> 
     <prename>Prename2</prename> 
     <surname>Surname2</surname> 
     <maximumbalance>100</maximumbalance> 
     <balance>100</balance> 
    </savegame> 
    </savegames> 
</Data> 

cách dễ nhất để thay đổi một giá trị trong một phần tử cụ thể là gì?

Giả sử tôi muốn thay đổi số dư của một số cụ thể savegame.

tôi muốn truy cập các savegame bởi idnumber (những con số này là duy nhất)

Sau đó, tôi muốn thay đổi giá trị của cân bằng (ví dụ 50) và sau đó lưu những thay đổi này vào tài liệu của tôi.

Trả lời

34

với using System.Xml.Linq; nó trở nên

var doc = XElement.Load(fileName); 
var saveGame = doc 
     .Element("savegames") 
     .Elements("savegame") 
     .Where(e => e.Element("IdNumber").Value == "2") 
     .Single(); 

saveGame.Element("balance").Value = "50"; 

doc.Save(fileName); 
+0

vì một lý do nào đó, tôi có lỗi "Tham chiếu đối tượng không được đặt thành một thể hiện ..." thì tôi đã sửa nó bằng 'XDocument.Load (tên tệp); ' – newbieguy

6

đây là một cách đơn giản để làm điều này:

 XmlDocument doc = new XmlDocument(); 
    doc.Load(@"d:\tmp.xml"); 
    XmlNode node = doc["Data"]["savegames"]; 

    foreach (XmlNode childNode in node.ChildNodes) 
    { 
     if (childNode["IdNumber"].InnerText.Equals("1")) 
     { 
      childNode["balance"].InnerText = "88"; 
     } 

    } 
    doc.Save(@"d:\tmp.xml"); 

mã này chỉ thay đổi sự cân bằng của id "1"

nó có phải nó bằng cách đi qua con cái "savegames" và kiểm tra đối với từng item "idnumber"

+6

XmlDocument không phải là cách 'đơn giản'. Đó là cách cũ. –

+1

@HenkHolterman (và upvoter) bạn đang cực kỳ pedantic. Nó không được nói "* THE * cách đơn giản", chỉ đơn thuần là ** A ** cách đơn giản. Nó vẫn đơn giản. –

17

Tôi nghĩ rằng cách nhỏ gọn nhất để làm việc đó là sử dụng XDocument (System.Xml.Linq) và phần mở rộng XPath (System.Xml.XPath):

var xdoc = XDocument.Load(file); 
xdoc.XPathSelectElement("//savegame/IdNumber[text()='2']/../balance").Value = "50"; 
xdoc.Save(file); 

Một khi bạn học XPath bạn không bao giờ thực sự muốn quay trở lại để liệt kê các nút bằng tay.

EDIT: những gì hiện giá trị trung bình truy vấn:

//savegame/IdNumber[text()='2']/../balance" 
    |  |     |^balance element ... 
    |  |     ^... of parent ... 
    |  ^... of IdNumber element with inner value '2' ... 
^... of any savegame element in the doc 

Bạn có thể tìm sự giúp đỡ XPath herethe updated link here.

+2

đây là [link] được cập nhật (http: // www. w3schools.com/xsl/xpath_intro.asp) để trợ giúp XPath. – Cooter

4
UpdateGameAttr(id , bal); 

    private void UpdateGameAttr(int id, int bal) 
    { 
     XDocument gmaes = XDocument.Load(@"D:\xxx\xxx\Game.xml");    

     XElement upd = (from games in games.Descendants("savegame") 
         where games.Element("IdNumber").Value == id.ToString() 
         select games).Single(); 
     upd.Element("balance").Value = bal.ToString(); 
     gmaes.Save(@"D:\xxxx\xxx\Game.xml"); 

    } 
Các vấn đề liên quan