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 d'analyse et de création de documents XML, etc.
EDIT: Les suggestions .Net 3.5 sont également les bienvenues.
Réponses:
Le principal moyen de lecture et d'écriture en C # 2.0 se fait via la classe XmlDocument . Vous pouvez charger la plupart de vos paramètres directement dans le XmlDocument via le XmlReader qu'il accepte.
Chargement direct de 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 / le plus rapide de lire un document XML est d'utiliser XPath.
Lire un document XML à l'aide de XPath (à l'aide de 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 de 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 de XML par rapport à 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 }
Ecrire 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 cependant 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'initialiseurs 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)
Un bon moyen dans .NET 3.5 est d'utiliser XDocument pour créer du XML ci-dessous. Cela fait apparaître le code dans un modèle 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>
Tout le reste échoue, vous pouvez consulter cet article MSDN qui contient de nombreux exemples dont j'ai discuté ici et plus encore. http://msdn.microsoft.com/en-us/library/aa468556.aspx
la source
Cela dépend de la taille; pour les xml de petite à moyenne taille, 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 à l'aide d'un XmlReader , et un XmlReader accepte (pour créer ) un XmlReaderSettings . Les objets XmlReaderSettings ont une propriété Schemas qui peut être utilisée pour effectuer la validation xsd (ou dtd).
Pour l'écriture de XML, les mêmes choses s'appliquent, notant qu'il est un peu plus facile de mettre en page le contenu avec LINQ-to-XML (XDocument) qu'avec l'ancien XmlDocument.
Cependant, pour un XML énorme, un DOM peut chomp trop de mémoire, auquel cas vous devrez peut-être utiliser directement XmlReader / XmlWriter.
Enfin, pour manipuler xml, vous souhaiterez peut-être 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 compatible xsd, charger simplement le xml en tant qu'objets , le manipuler avec OO, puis sérialiser à nouveau ces objets; vous faites cela avec XmlSerializer .
la source
La réponse de nyxtom est très bonne. J'ajouterais quelques choses à cela:
Si vous avez besoin d'un accès en lecture seule à un document XML,
XPathDocument
est un objet beaucoup plus léger queXmlDocument
.L'inconvénient de l'utilisation
XPathDocument
est que vous ne pouvez pas utiliser les méthodesSelectNodes
et lesSelectSingleNode
méthodes familières deXmlNode
. À la place, vous devez utiliser les outilsIXPathNavigable
fournis par le: utilisezCreateNavigator
pour créer unXPathNavigator
, et utilisezXPathNavigator
pour créerXPathNodeIterator
s pour parcourir les listes de nœuds que vous trouvez via XPath. Cela nécessite généralement quelques lignes de code de plus que lesXmlDocument
méthodes.Mais: les classes
XmlDocument
etXmlNode
implémententIXPathNavigable
, donc tout code que vous écrivez pour utiliser ces méthodes sur unXPathDocument
fonctionnera également sur unXmlDocument
. Si vous vous habituez à écrireIXPathNavigable
, vos méthodes peuvent fonctionner avec l'un ou l'autre des objets. (C'est pourquoi l'utilisation deXmlNode
etXmlDocument
dans les signatures de méthode est marquée par FxCop.)Malheureusement,
XDocument
etXElement
(etXNode
etXObject
) ne sont pas implémentésIXPathNavigable
.Une autre chose qui n'est pas présente dans la réponse de nyxtom est
XmlReader
. Vous utilisez généralementXmlReader
pour éviter la surcharge de l'analyse du flux XML dans un modèle objet avant de commencer à le traiter. Au lieu de cela, vous utilisez unXmlReader
pour traiter le flux d'entrée un nœud XML à la fois. C'est essentiellement la réponse de .NET à SAX. Il vous permet d'écrire du code très rapide pour le traitement de très gros documents XML.XmlReader
fournit également le moyen le plus simple de traiter des fragments de document XML, par exemple le flux d'éléments XML sans élément englobant renvoyé par l'option FOR XML RAW de SQL Server.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 plus faiblement couplé au XML, c'est pourquoi c'est généralement la bonne réponse. Mais lorsque vous avez besoin de l'utiliserXmlReader
, vous en avez vraiment besoin.la source
XPathNavigator CreateNavigator(this XNode node)
pour créer unXPathNavigator
from anXNode
(qui inclut la classe dérivéeXDocument
).Tout d'abord, apprenez à connaître les nouvelles classes XDocument et XElement , car elles constituent une amélioration par rapport à la famille XmlDocument précédente.
Cependant , vous devrez peut-être continuer à utiliser les anciennes classes pour travailler avec le code hérité, en particulier les proxys 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 gestion XML.
Je pense que votre question est assez large et exigerait 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 elle sert de point de départ.
la source
101 échantillons Linq
http://msdn.microsoft.com/en-us/library/bb387098.aspx
et Linq vers des exemples XML
http://msdn.microsoft.com/en-us/vbasic/bb688087.aspx
Et je pense que Linq facilite le XML.
la source
Si vous travaillez sous .NET 3.5 et que vous n'avez pas peur du code expérimental, vous pouvez consulter LINQ to XSD ( http://blogs.msdn.com/xmlteam/archive/2008/02/21/linq-to- xsd-alpha-0-2.aspx ) qui générera des classes .NET à partir d'un XSD (y compris les règles intégrées du XSD).
Il a ensuite la possibilité d'écrire directement dans un fichier et de lire à partir d'un fichier en s'assurant qu'il est conforme aux règles XSD.
Je suggère vraiment d'avoir un XSD pour tout document XML avec lequel vous travaillez:
Je trouve que Liquid XML Studio est un excellent outil pour générer des XSD et c'est gratuit!
la source
Ecrire du XML avec la classe XmlDocument
//itemValues is collection of items in Key value pair format //fileName i name of XML file which to creatd or modified with content private void WriteInXMLFile(System.Collections.Generic.Dictionary<string, object> itemValues, string fileName) { string filePath = "C:\\\\tempXML\\" + fileName + ".xml"; try { if (System.IO.File.Exists(filePath)) { XmlDocument doc = new XmlDocument(); doc.Load(filePath); XmlNode rootNode = doc.SelectSingleNode("Documents"); XmlNode pageNode = doc.CreateElement("Document"); rootNode.AppendChild(pageNode); foreach (string key in itemValues.Keys) { XmlNode attrNode = doc.CreateElement(key); attrNode.InnerText = Convert.ToString(itemValues[key]); pageNode.AppendChild(attrNode); //doc.DocumentElement.AppendChild(attrNode); } doc.DocumentElement.AppendChild(pageNode); doc.Save(filePath); } else { XmlDocument doc = new XmlDocument(); using(System.IO.FileStream fs = System.IO.File.Create(filePath)) { //Do nothing } XmlNode rootNode = doc.CreateElement("Documents"); doc.AppendChild(rootNode); doc.Save(filePath); doc.Load(filePath); XmlNode pageNode = doc.CreateElement("Document"); rootNode.AppendChild(pageNode); foreach (string key in itemValues.Keys) { XmlNode attrNode = doc.CreateElement(key); attrNode.InnerText = Convert.ToString(itemValues[key]); pageNode.AppendChild(attrNode); //doc.DocumentElement.AppendChild(attrNode); } doc.DocumentElement.AppendChild(pageNode); doc.Save(filePath); } } catch (Exception ex) { } } OutPut look like below <Dcouments> <Document> <DocID>01<DocID> <PageName>121<PageName> <Author>Mr. ABC<Author> <Dcoument> <Document> <DocID>02<DocID> <PageName>122<PageName> <Author>Mr. PQR<Author> <Dcoument> </Dcouments>
la source
Si vous créez un ensemble de données typé dans le concepteur, vous obtenez automatiquement un xsd, un objet fortement typé, et pouvez charger et enregistrer le xml avec une seule ligne de code.
la source
Mon opinion personnelle, en tant que programmeur C #, est que la meilleure façon de gérer XML en C # est de déléguer cette partie du code à un projet VB .NET. Dans .NET 3.5, VB .NET a des littéraux XML, ce qui rend la gestion de XML beaucoup plus intuitive. Voir ici, par exemple:
Vue d'ensemble de LINQ to XML dans Visual Basic
(Assurez-vous de configurer la page pour afficher le code VB, pas le code C #.)
J'écrirais le reste du projet en C #, mais gérerais le XML dans un projet VB référencé.
la source
nyxtom,
"Doc" et "xdoc" ne devraient-ils pas correspondre dans l'exemple 1?
XDocument **doc** = XDocument.Load(pathToXml); List<Person> people = (from xnode in **xdoc**.Element("People").Elements("Person") select new Person { Name = xnode.Attribute("Name").Value }).ToList();
la source
La réponse de Cookey est bonne ... mais voici des instructions détaillées sur la façon de créer un objet fortement typé à partir d'un XSD (ou XML) et de sérialiser / désérialiser en quelques lignes de code:
Instructions
la source
Si jamais vous avez besoin de convertir des données entre
XmlNode
<=>XNode
<=>XElement
(par exemple pour utiliser LINQ), ces extensions peuvent vous être utiles:
public static class MyExtensions { public static XNode GetXNode(this XmlNode node) { return GetXElement(node); } public static XElement GetXElement(this XmlNode node) { XDocument xDoc = new XDocument(); using (XmlWriter xmlWriter = xDoc.CreateWriter()) node.WriteTo(xmlWriter); return xDoc.Root; } public static XmlNode GetXmlNode(this XElement element) { using (XmlReader xmlReader = element.CreateReader()) { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(xmlReader); return xmlDoc; } } public static XmlNode GetXmlNode(this XNode node) { return GetXmlNode(node); } }
Usage:
XmlDocument MyXmlDocument = new XmlDocument(); MyXmlDocument.Load("MyXml.xml"); XElement MyXElement = MyXmlDocument.GetXElement(); // Convert XmlNode to XElement List<XElement> List = MyXElement.Document .Descendants() .ToList(); // Now you can use LINQ ...
la source