web-dev-qa-db-fra.com

Ajout d'éléments à un fichier XML en C #

J'ai un fichier XML formaté comme ceci:

<Snippets>
  <Snippet name="abc">
    <SnippetCode>
      testcode1
    </SnippetCode>
  </Snippet>

  <Snippet name="xyz">
    <SnippetCode>      
     testcode2
    </SnippetCode>
  </Snippet>

  ...

</Snippets>

Je peux charger avec succès les éléments en utilisant XDocument, mais j'ai de la difficulté à en ajouter de nouveaux (il y a beaucoup de fonctions et la plupart de celles que j'ai essayées ne fonctionnaient pas bien pour moi). Comment cela serait-il fait? Le nouvel élément contiendrait la balise de nom d'extrait et la balise de code d'extrait. Mon approche précédente consistait à ouvrir le fichier et à créer manuellement l'élément à l'aide d'une chaîne qui, bien que fonctionnant, est une très mauvaise idée.

Ce que j'ai essayé

XDocument doc = XDocument.Load(spath);
XElement root = new XElement("Snippet");
root.Add(new XElement("name", "name goes here"));
root.Add(new XElement("SnippetCode", "SnippetCode"));
doc.Element("Snippets").Add(root);
doc.Save(spath);

Et le résultat est le suivant:

<Snippet>
    <name>name goes here</name>
    <SnippetCode>
    code goes here
    </SnippetCode>
</Snippet>

Cela fonctionne très bien, sauf que l’étiquette de nom n’est pas générée correctement. CA devrait etre 

<Snippet name="abc"> 

mais je ne peux pas générer cela correctement.

31
rayanisran

Vous êtes proche, mais vous voulez que le nom soit une XAttribute plutôt que XElement:

 XDocument doc = XDocument.Load(spath); 
 XElement root = new XElement("Snippet"); 
 root.Add(new XAttribute("name", "name goes here")); 
 root.Add(new XElement("SnippetCode", "SnippetCode")); 
 doc.Element("Snippets").Add(root); 
 doc.Save(spath); 
57
Jim Wooley

Vous devez créer une nouvelle XAttribute au lieu de XElement. Essayez quelque chose comme ça:

public static void Test()
{
    var xdoc = XDocument.Parse(@"
        <Snippets>

          <Snippet name='abc'>
            <SnippetCode>
              testcode1
            </SnippetCode>
          </Snippet>

          <Snippet name='xyz'>
            <SnippetCode>      
             testcode2
            </SnippetCode>
          </Snippet>

        </Snippets>");

    xdoc.Root.Add(
        new XElement("Snippet",
            new XAttribute("name", "name goes here"),
            new XElement("SnippetCode", "SnippetCode"))
    );
    xdoc.Save(@"C:\TEMP\FOO.XML");
}

Cela génère la sortie:

<?xml version="1.0" encoding="utf-8"?>
<Snippets>
  <Snippet name="abc">
    <SnippetCode>
      testcode1
    </SnippetCode>
  </Snippet>
  <Snippet name="xyz">
    <SnippetCode>      
     testcode2
    </SnippetCode>
  </Snippet>
  <Snippet name="name goes here">
    <SnippetCode>SnippetCode</SnippetCode>
  </Snippet>
</Snippets>
6
JohnD

Si vous voulez ajouter un attribut, et non un élément, vous devez le dire:

XElement root = new XElement("Snippet");
root.Add(new XAttribute("name", "name goes here"));
root.Add(new XElement("SnippetCode", "SnippetCode"));

Le code ci-dessus produit l'élément XML suivant:

<Snippet name="name goes here">
  <SnippetCode>SnippetCode</SnippetCode>
</Snippet> 
5
svick

Vous pouvez créer des classes correspondant à la structure et ajouter une instance à une collection, puis sérialiser et désérialiser la collection pour charger et enregistrer le document.

4
Kell

J'ai utilisé XDocument.Root . Add pour ajouter des éléments. La racine retourne XElement qui a une fonction Add pour des XElements supplémentaires 

2
Rob Haupt

Ceci est une extension des réponses ci-dessus, si votre xml a un espace de noms défini (xmlns), vous aurez un effet secondaire désagréable lors de l'ajout d'enfants - xmlns = "" étant ajouté à votre nouvel élément enfant.

Ce que vous voulez faire (en supposant que l'élément que vous ajoutez appartient au même espace de nom que son parent) est de prendre l'espace de nom de l'élément parent parentElement.GetDefaultNamespace()

var child = new XElement(parentElement.GetDefaultNamespace()+"Snippet", new XAttribute("Attr1", "42"), new XAttribute("Attr2", "22"));
child.Add(new XAttribute("Attr3", "777"));
parentElement.Add(child);

pour les éléments parents avec plusieurs espaces de noms, vous pouvez choisir lequel utiliser en passant de parentElement.GetDefaultNamespace()+"Snippet" à parentElement.GetNamespaceOfPrefix("namespacePrefixThatGoesWithColon")+"Snippet" e.g

var child = new XElement(parentElement.GetNamespaceOfPrefix("namespacePrefixThatGoesWithColon")+"Snippet", new XAttribute("Attr1", "42"), new XAttribute("Attr2", "22"));
1
Matas Vaitkevicius
<Snippet name="abc"> 

nom est un attribut, pas un élément. C'est pourquoi ça échoue. Recherchez l’utilisation de SetAttribute sur l’élément <Snippet>

root.SetAttribute("name", "name goes here");

est le code dont vous avez besoin avec ce que vous avez. 

0
Yatrix