web-dev-qa-db-fra.com

Meilleure façon de lire, modifier et écrire du XML

Mon plan est de lire dans un document XML à l'aide de mon programme C #, de rechercher les entrées particulières que je voudrais modifier, puis d'écrire le document modifié. Cependant, je suis devenu décontenancé, car il est difficile de différencier les éléments, qu'ils commencent ou se terminent avec XmlTextReader, que j'utilise pour lire le fichier. Je pourrais faire quelques conseils pour me mettre sur la bonne voie.

Le document est un document HTML, donc comme vous pouvez l’imaginer, c’est assez compliqué.

Je voudrais rechercher un identifiant d'élément dans le document HTML, par exemple, recherchez-le et changez le src;

<img border="0" src="bigpicture.png" width="248" height="36" alt="" id="lookforthis" />
13
wonea

S'il s'agit réellement d'un code XML valide, et qu'il tiendra facilement dans la mémoire, je choisirais chaque fois LINQ to XML (XDocument, XElement etc.). C'est de loin la plus belle API XML que j'ai utilisée. Il est facile de former des requêtes et de créer de nouveaux éléments.

Vous pouvez utiliser XPath lorsque cela convient, ou les méthodes d'axe intégrées (Elements(), Descendants(), Attributes(), etc.). Si vous pouviez nous dire quels éléments spécifiques vous avez du mal à vivre, je serais ravi de vous aider à les exprimer en LINQ to XML.

Si, par contre, il s'agit de HTML qui n'est pas valide, vous aurez beaucoup plus de difficulté, car les API XML s'attendent généralement à travailler avec des documents XML valides. Vous pouvez utiliser HTMLTidy en premier bien sûr, mais peut avoir des effets indésirables.

Pour votre exemple spécifique:

XDocument doc = XDocument.Load("file.xml");
foreach (var img in doc.Descendants("img"))
{
    // src will be null if the attribute is missing
    string src = (string) img.Attribute("src");
    img.SetAttributeValue("src", src + "with-changes");
}
30
Jon Skeet

Les documents que vous traitez sont-ils relativement petits? Dans ce cas, vous pouvez les charger en mémoire à l'aide d'un objet XmlDocument, le modifier et réécrire les modifications.

XmlDocument doc = new XmlDocument();
doc.Load("path_to_input_file");
// Make changes to the document.
using(XmlTextWriter xtw = new XmlTextWriter("path_to_output_file", Encoding.UTF8)) {
  xtw.Formatting = Formatting.Indented; // optional, if you want it to look Nice
  doc.WriteContentTo(xtw);
}

En fonction de la structure du XML d'entrée, cela pourrait simplifier un peu votre code d'analyse.

4
Pat Daburu

Voici un outil que j'ai écrit pour modifier un fichier de projet IAR EWARM (ewp), en ajoutant un éditeur de liens au projet. À partir de la ligne de commande, vous l'exécutez avec 2 arguments, les noms de fichier d'entrée et de sortie (* .ewp).

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;

    namespace ewp_tool
    {
        class Program
        {
            static void Main(string[] args)
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(args[0]);

                XmlNodeList list = doc.SelectNodes("/project/configuration[name='Debug']/settings[name='ILINK']/data/option[name='IlinkConfigDefines']/state");
                foreach(XmlElement x in list) {
                    x.InnerText = "MAIN_APP=1";
                }

                using (XmlTextWriter xtw = new XmlTextWriter(args[1], Encoding.UTF8))
                {
                    //xtw.Formatting = Formatting.Indented; // leave this out, it breaks EWP!
                    doc.WriteContentTo(xtw);
                }
            }
        }
    }

La structure du XML ressemble à ceci

    <U+FEFF><?xml version="1.0" encoding="iso-8859-1"?>
    <project>
      <fileVersion>2</fileVersion>
      <configuration>
        <name>Debug</name>
        <toolchain>
          <name>ARM</name>
        </toolchain>
        <debug>1</debug>

         ...

        <settings>
          <name>ILINK</name>
          <archiveVersion>0</archiveVersion>
          <data>

            ...

            <option>
              <name>IlinkConfigDefines</name>
              <state>MAIN_APP=0</state>
            </option>
2
Mark Lakata

Pour la tâche en cours - (lire la documentation existante, écrire et modifier de manière formalisée), j'irais avec XPathDocument exécuter un XslCompiledTransform .

Là où vous ne pouvez pas formaliser, n'avez pas de documents préexistants ou avez généralement besoin d'une logique plus adaptative, je choisirais LINQ et XDocument, comme le dit Skeet.

Fondamentalement, si la tâche est une transformation, alors XSLT, si la tâche est une manipulation, puis LINQ.

1
annakata

Mon outil préféré pour ce genre de chose est HtmlAgilityPack . Je l'utilise pour analyser des documents HTML complexes dans des collections interrogeables par LINQ. C'est un outil extrêmement utile pour interroger et analyser HTML (ce qui est souvent un XML non valide).

Pour votre problème, le code ressemblerait à ceci:

var htmlDoc = HtmlAgilityPack.LoadDocument(stringOfHtml);
var images = htmlDoc.DocumentNode.SelectNodes("//img[id=lookforthis]");

if(images != null)
{
  foreach (HtmlNode node in images)  
  {  
      node.Attributes.Append("alt", "added an alt to lookforthis images.");  
  }  
}

htmlDoc.Save('output.html');
1
Peter J

Si vous avez des documents plus petits qui tiennent dans la mémoire de votre ordinateur, vous pouvez utiliser XmlDocument. Sinon, vous pouvez utiliser XmlReader pour parcourir le document.

En utilisant XmlReader, vous pouvez trouver le type d'éléments en utilisant:

while (xml.Read()) {
   switch xml.NodeType {
     case XmlNodeType.Element:
      //Do something
     case XmlNodeType.Text:
      //Do something
     case XmlNodeType.EndElement:  
      //Do something
   }
}
1
codymanix

Une approche assez simple serait de créer une nouvelle variable XmlDocument, puis d’utiliser la méthode Load() pour la remplir. Une fois que vous avez reçu le document, vous pouvez utiliser CreateNavigator() pour obtenir un objet XPathNavigator que vous pouvez utiliser pour rechercher et modifier des éléments dans le document. Enfin, vous pouvez utiliser la méthode Save() sur XmlDocument pour réécrire le document modifié.

0
ngroot