90 votes

Comment traiter le XML en C#

Quelle est la meilleure façon de traiter les documents XML, XSD, etc. en C# 2.0 ?

Quelles classes utiliser, etc. Quelles sont les meilleures pratiques pour analyser et créer des documents XML, etc.

EDIT : Les suggestions concernant .Net 3.5 sont également les bienvenues.

1 votes

Pour ceux qui essaient également de trouver une solution plus pratique, ignorez ceci. C'est une ancienne bibliothèque .NET. Utilisez XDocument à la place, et vous éviterez de vous arracher les yeux de frustration.

185voto

nyxtom Points 2147

Le principal moyen de lire et d'écrire en C# 2.0 se fait par l'intermédiaire de la fonction XmlDocument classe. Vous pouvez charger la plupart de vos paramètres directement dans le XmlDocument grâce au XmlReader qu'il accepte.

Chargement direct du XML

XmlDocument document = new XmlDocument();
document.LoadXml("<People><Person Name='Nick' /><Person Name='Joe' /></People>");

Chargement de XML à partir d'un fichier

XmlDocument document = new XmlDocument();
document.Load(@"C:\Path\To\xmldoc.xml");
// Or using an XmlReader/XmlTextReader
XmlReader reader = XmlReader.Create(@"C:\Path\To\xmldoc.xml");
document.Load(reader);

Je trouve que le moyen le plus simple et le plus rapide de lire un document XML est d'utiliser XPath.

Lecture d'un document XML à l'aide de XPath (en utilisant XmlDocument qui nous permet d'éditer)

XmlDocument document = new XmlDocument();
document.LoadXml("<People><Person Name='Nick' /><Person Name='Joe' /></People>");

// Select a single node
XmlNode node = document.SelectSingleNode("/People/Person[@Name = 'Nick']");

// Select a list of nodes
XmlNodeList nodes = document.SelectNodes("/People/Person");

Si vous devez travailler avec des documents XSD pour valider un document XML, vous pouvez l'utiliser.

Validation des documents XML par rapport aux schémas XSD

XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidateType = ValidationType.Schema;
settings.Schemas.Add("", pathToXsd); // targetNamespace, pathToXsd

XmlReader reader = XmlReader.Create(pathToXml, settings);
XmlDocument document = new XmlDocument();

try {
    document.Load(reader);
} catch (XmlSchemaValidationException ex) { Trace.WriteLine(ex.Message); }

Validation du XML par rapport au XSD à chaque nœud (UPDATE 1)

XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidateType = ValidationType.Schema;
settings.Schemas.Add("", pathToXsd); // targetNamespace, pathToXsd
settings.ValidationEventHandler += new ValidationEventHandler(settings_ValidationEventHandler);

XmlReader reader = XmlReader.Create(pathToXml, settings);
while (reader.Read()) { }

private void settings_ValidationEventHandler(object sender, ValidationEventArgs args)
{
    // e.Message, e.Severity (warning, error), e.Error
    // or you can access the reader if you have access to it
    // reader.LineNumber, reader.LinePosition.. etc
}

Écrire un document XML (manuellement)

XmlWriter writer = XmlWriter.Create(pathToOutput);
writer.WriteStartDocument();
writer.WriteStartElement("People");

writer.WriteStartElement("Person");
writer.WriteAttributeString("Name", "Nick");
writer.WriteEndElement();

writer.WriteStartElement("Person");
writer.WriteStartAttribute("Name");
writer.WriteValue("Nick");
writer.WriteEndAttribute();
writer.WriteEndElement();

writer.WriteEndElement();
writer.WriteEndDocument();

writer.Flush();

(MISE À JOUR 1)

Dans .NET 3.5, vous utilisez XDocument pour effectuer des tâches similaires. La différence est que vous avez l'avantage d'exécuter des requêtes Linq pour sélectionner les données exactes dont vous avez besoin. Avec l'ajout d'initialisateurs d'objets, vous pouvez créer une requête qui renvoie même des objets de votre propre définition directement dans la requête elle-même.

    XDocument doc = XDocument.Load(pathToXml);
    List<Person> people = (from xnode in doc.Element("People").Elements("Person")
                       select new Person
                       {
                           Name = xnode.Attribute("Name").Value
                       }).ToList();

(MISE À JOUR 2)

Une façon agréable dans .NET 3.5 est d'utiliser XDocument pour créer le XML est ci-dessous. Cela permet de faire apparaître le code de manière similaire à la sortie souhaitée.

XDocument doc =
        new XDocument(
              new XDeclaration("1.0", Encoding.UTF8.HeaderName, String.Empty),
              new XComment("Xml Document"),
              new XElement("catalog",
                    new XElement("book", new XAttribute("id", "bk001"),
                          new XElement("title", "Book Title")
                    )
              )
        );

crée

<!--Xml Document-->
<catalog>
  <book id="bk001">
    <title>Book Title</title>
  </book>
</catalog>

En cas d'échec, vous pouvez consulter cet article de MSDN qui contient de nombreux exemples dont j'ai parlé ici et d'autres encore. http://msdn.microsoft.com/en-us/library/aa468556.aspx

3 votes

Vous pouvez préciser que vous utilisez XDocument dans le dernier exemple, car XDocument est très différent de XmlDocument.

2 votes

Correction : il n'y a pas de C# 3.5 ; vous voulez dire .NET 3.5 et C# 3.0.

0 votes

Oh, et les [initialisateurs d'objets] "à la volée" fonctionneraient largement de la même manière avec C# 3.0 et XmlDocument - mais c'est quand même une bonne réponse (+1)

31voto

Marc Gravell Points 482669

Cela dépend de la taille ; pour un xml de taille petite à moyenne, un DOM tel que XmlDocument (toutes les versions C#/.NET) ou XDocument (.NET 3.5/C# 3.0) est le gagnant évident. Pour utiliser xsd, vous pouvez charger xml en utilisant un fichier XmlReader et un XmlReader accepte (pour Créer ) et XmlReaderSettings . L'objet XmlReaderSettings possède un objet Schémas qui peut être utilisée pour effectuer une validation xsd (ou dtd).

Pour écrire du xml, les mêmes choses s'appliquent, en notant qu'il est un peu plus facile de mettre en page le contenu avec LINQ-to-XML (XDocument) que l'ancien XmlDocument.

Cependant, pour les fichiers xml volumineux, un DOM peut prendre trop de mémoire, auquel cas vous devrez utiliser directement XmlReader/XmlWriter.

Enfin, pour manipuler du xml, vous pouvez utiliser XslCompiledTransform (une couche xslt).

L'alternative au travail avec xml est de travailler avec un modèle objet ; vous pouvez utiliser xsd.exe pour créer des classes qui représentent un modèle conforme à xsd, et simplement charger le xml en tant qu'objets de les manipuler avec OO, puis de sérialiser à nouveau ces objets. XmlSerializer .

0 votes

Pour manipuler (ajouter/supprimer des éléments) un gros document XML (40 000 lignes). Quel est le meilleur moyen ? J'avais l'habitude d'utiliser LINQ-to-XML.

12voto

Robert Rossney Points 43767

La réponse de nyxtom est très bonne. J'y ajouterais deux ou trois choses :

Si vous avez besoin d'un accès en lecture seule à un document XML, XPathDocument est un objet beaucoup plus léger que XmlDocument .

L'inconvénient d'utiliser XPathDocument est que vous ne pouvez pas utiliser le familier SelectNodes et SelectSingleNode méthodes de XmlNode . Au lieu de cela, vous devez utiliser les outils que les IXPathNavigable prévoit : utilisation CreateNavigator pour créer un XPathNavigator et utiliser le XPathNavigator pour créer XPathNodeIterator pour itérer sur les listes de nœuds que vous trouvez via XPath. Cela nécessite généralement quelques lignes de code supplémentaires par rapport à la fonction XmlDocument méthodes.

Mais : le XmlDocument et XmlNode les classes mettent en œuvre IXPathNavigable Ainsi, tout code écrit pour utiliser ces méthodes sur un objet XPathDocument fonctionnera également sur un XmlDocument . Si vous vous habituez à écrire contre IXPathNavigable vos méthodes peuvent fonctionner sur les deux objets. (C'est pourquoi l'utilisation de XmlNode et XmlDocument dans les signatures de méthodes est signalé par FxCop).

C'est regrettable, XDocument et XElement (et XNode et XObject ) ne mettent pas en œuvre IXPathNavigable .

Une autre chose qui n'est pas présente dans la réponse de nyxtom est XmlReader . Vous utilisez généralement XmlReader pour éviter les frais généraux liés à l'analyse du flux XML dans un modèle objet avant de commencer à le traiter. Au lieu de cela, vous utilisez un XmlReader pour traiter le flux d'entrée un nœud XML à la fois. Il s'agit essentiellement de la réponse de .NET à SAX. Il vous permet d'écrire un code très rapide pour le traitement de très gros documents XML.

XmlReader fournit également le moyen le plus simple de traiter les fragments de documents XML, par exemple le flux d'éléments XML sans élément d'inclusion que l'option FOR XML RAW de SQL Server renvoie.

Le code que vous écrivez en utilisant XmlReader est généralement très étroitement lié au format du XML qu'il lit. L'utilisation de XPath permet à votre code d'être beaucoup, beaucoup moins lié au XML, c'est pourquoi c'est généralement la bonne réponse. Mais lorsque vous devez utiliser XmlReader si vous en avez vraiment besoin.

3 votes

Notez qu'il existe une méthode d'extension XPathNavigator CreateNavigator(this XNode node) pour créer un XPathNavigator d'un XNode (qui comprend la classe dérivée XDocument ).

5voto

hurst Points 1192

Tout d'abord, apprenez à connaître le nouveau XDocument et XElement car elles constituent une amélioration par rapport à la famille XmlDocument précédente.

  1. Ils fonctionnent avec LINQ
  2. Ils sont plus rapides et plus légers

Cependant En revanche, il se peut que vous deviez continuer à utiliser les anciennes classes pour travailler avec le code existant, notamment les proxies générés précédemment. Dans ce cas, vous devrez vous familiariser avec certains modèles d'interopérabilité entre ces classes de traitement du XML.

Je pense que votre question est assez large et qu'il faudrait trop de détails dans une seule réponse, mais c'est la première réponse générale à laquelle j'ai pensé et qui sert de point de départ.

0 votes

Je suis d'accord pour dire qu'ils (XDocument, etc.) sont excellents, mais l'OP a posé une question sur C# 2.0.

3voto

emremp Points 41

101 échantillons de Linq

http://msdn.microsoft.com/en-us/library/bb387098.aspx

et Exemples de Linq to XML

http://msdn.microsoft.com/en-us/vbasic/bb688087.aspx

Et je pense que Linq rend le XML facile.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X