web-dev-qa-db-fra.com

Modifier un élément spécifique dans XDocument

J'ai récemment commencé à apprendre C # et j'ai rencontré un problème en utilisant XML.Linq pour stocker des données. J'espère que la question est compréhensible car je ne connais pas encore tous les termes corrects et comme l'anglais n'est pas ma langue maternelle.

J'ai lu beaucoup de questions/googlé mais je ne peux pas le comprendre moi-même.

Je souhaite mettre à jour un fichier XDocument existant qui ressemble à ceci:

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

Quelle est la façon la plus simple de modifier une valeur dans un élément spécifique?

Disons que je veux changer le balance d'un savegame spécifique.

Je veux accéder à la sauvegarde par IdNumber (ces numéros sont uniques)

Ensuite, je veux changer la valeur de balance (par exemple à 50), puis enregistrer ces modifications dans mon document.

34
Matthias Weiß

Avec using System.Xml.Linq; il devient

 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);
42
Henk Holterman

Je pense que la façon la plus compacte de le faire est d'utiliser XDocument (System.Xml.Linq) et les extensions XPath (System.Xml.XPath):

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

Une fois que vous avez appris XPath, vous ne voulez plus vraiment revenir à l'énumération manuelle des nœuds.

EDIT: que signifie la requête:

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

Vous pouvez trouver l'aide XPath ici , et le lien mis à jour ici .

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

   }
4
Suraj Singh

voici un moyen simple de le faire:

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

ce code ne change que le solde de l'identifiant "1"

il le fait en passant par les enfants de "savegames" et en vérifiant pour chaque élément le "IdNumber"

4
No Idea For Name