2013-08-29 17 views
27

Recentemente ho iniziato a imparare C# e ho riscontrato un problema utilizzando XML.Linq per memorizzare i dati. Spero che la domanda sia comprensibile perché non conosco ancora tutti i termini corretti e poiché l'inglese non è la mia prima lingua.Modifica elemento specifico in XDocument

Ho letto molte domande/googled ma non riesco a capirlo da solo.

voglio aggiornare un file esistente XDocument che assomiglia a questo:

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

Qual è il modo più semplice per modificare un valore in un elemento specifico?

Diciamo che voglio cambiare il equilibrio di uno specifico savegame.

voglio accedere al savegame da IDnumber (questi numeri sono unici)

Poi voglio cambiare il valore di equilibrio (ad esempio a 50) e quindi salvare questi cambiamenti al mio documento.

risposta

34

Con using System.Xml.Linq; diventa

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

per qualche motivo, ho un errore "Riferimento oggetto non impostato su un'istanza ..." quindi l'ho risolto con 'XDocument.Load (fileName);' – newbieguy

6

Ecco un modo semplice per farlo:

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

questo codice solo cambiare l'equilibrio di ID "1"

lo fa passando attraverso i figli di "salvataggi" e il controllo per ogni oggetto la "iDNumber"

+6

XmlDocument non è il modo "semplice". È alla vecchia maniera. –

+1

@HenkHolterman (e upvoter) sei estremamente pedante. Non è stato detto "* THE * simple way", semplicemente ** A ** modo semplice. Era ancora semplice. –

17

Penso che il modo più compatto di farlo sta usando XDocument (System.Xml.Linq) e le estensioni XPath (System.Xml.XPath):

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

volta che si impara XPath mai vuole veramente tornare a enumerare i nodi manualmente.

EDIT: che cosa fa la media query:

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

Potete trovare XPath aiuto here e the updated link here.

+2

qui è il collegamento [aggiornato] (http: // www. w3schools.com/xsl/xpath_intro.asp) alla guida di 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"); 

    } 
Problemi correlati