2013-08-29 8 views
27

Niedawno zacząłem uczyć się języka C# i natrafiłem na problem z przechowywaniem danych przy użyciu XML.Linq. Mam nadzieję, że pytanie jest zrozumiałe, ponieważ nie znam jeszcze wszystkich prawidłowych terminów, a ponieważ angielski nie jest moim pierwszym językiem.Edytuj konkretny element na XDocumentu

Przeczytałem wiele pytań/googled, ale nie mogę się tego dowiedzieć.

Chcę zaktualizować istniejący plik XDocument, który wygląda tak:

<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> 

Co jest najprostszym sposobem, aby zmienić wartość konkretnego elementu?

Załóżmy, że chcę zmienić saldo o wartości określonego zapisywania.

Chcę uzyskać dostęp do save'a przez IdNumber (numery te są unikalne)

Następnie chcę zmienić wartość bilansu (na przykład do 50), a następnie zapisać te zmiany w moim dokumencie.

Odpowiedz

34

Z using System.Xml.Linq; staje

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

z jakiegoś powodu, mam błąd "Odwołanie do obiektu nie jest ustawione na instancję ...", a następnie naprawiłem to za pomocą 'XDocument.Load (fileName);' – newbieguy

6

oto prosty sposób, aby to zrobić:

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

ten kod zmienia tylko równowagę id „1”

robi to przechodząc przez dzieci „zapisami gry” i sprawdzanie każdego item "IdNumber"

+6

XmlDocument nie jest "prostym" sposobem. To stary sposób. –

+1

@HenkHolterman (i upvoter) jesteś niezwykle pedantyczny. Nie zostało powiedziane "* THE * simple way", po prostu ** A ** prosty sposób. Nadal było proste. –

17

Myślę, że najbardziej zwarty sposób to zrobić jest użycie XDocument (System.Xml.Linq) oraz rozszerzenia XPath (System.Xml.XPath):

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

Gdy nauczysz XPath nigdy naprawdę chcesz wrócić do wyliczania węzłów ręcznie.

EDIT: co robi średnią zapytanie:

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

XPath można znaleźć pomoc here i the updated link here.

+2

tutaj jest zaktualizowany [link] (http: // www. w3schools.com/xsl/xpath_intro.asp) do pomocy 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"); 

    } 
Powiązane problemy