Comment analyser les fichiers XML? [fermé]


492

Existe-t-il une méthode simple d'analyse des fichiers XML en C #? Si oui, quoi?


vous pouvez utiliser cette implémentation: stackoverflow.com/a/34813985/5784646
Eulogy

Ok, j'ai rouvert ça. Le doublon était une solution de lecteur XML où il s'agit d'analyser des fichiers XML. Le doublon possible peut être vu dans les questions de modification de l' historique ps @GeorgeStocker
Jeremy Thompson

1
@JeremyThompson L'une des raisons pour lesquelles il s'agissait d'un doublon est que l'autre question a une bien meilleure réponse. La première réponse étant une simple réponse "lien uniquement" n'est pas utile.
George Stocker

1
@GeorgeStocker les questions sont suffisamment différentes pour coexister et les deux ont d' excellentes réponses, et celles acceptées utilisent des technologies différentes. C'est pourquoi j'ai voté pour que nous laissions cela ouvert, je sais que celui-ci n'est qu'un lien, mais il est MSDN et a été écrit à un moment avant ce qui était inacceptable, j'espère qu'un effet secondaire de la réouverture encourage un peu Jon, lisez son profil . Quoi qu'il en soit, bravo.
Jeremy Thompson

Réponses:



314

C'est très simple. Je sais que ce sont des méthodes standard, mais vous pouvez créer votre propre bibliothèque pour mieux gérer cela.

Voici quelques exemples:

XmlDocument xmlDoc= new XmlDocument(); // Create an XML document object
xmlDoc.Load("yourXMLFile.xml"); // Load the XML document from the specified file

// Get elements
XmlNodeList girlAddress = xmlDoc.GetElementsByTagName("gAddress");
XmlNodeList girlAge = xmlDoc.GetElementsByTagName("gAge"); 
XmlNodeList girlCellPhoneNumber = xmlDoc.GetElementsByTagName("gPhone");

// Display the results
Console.WriteLine("Address: " + girlAddress[0].InnerText);
Console.WriteLine("Age: " + girlAge[0].InnerText);
Console.WriteLine("Phone Number: " + girlCellPhoneNumber[0].InnerText);

En outre, il existe d' autres méthodes avec lesquelles travailler. Par exemple, ici . Et je pense qu'il n'y a pas de meilleure méthode pour le faire; vous devez toujours le choisir vous-même, ce qui vous convient le mieux.


47
+1 pour mentionner XmlDocument, qui est beaucoup plus pratique que les interfaces de sérialisation dans certains cas. Si vous recherchez un élément spécifique, vous pouvez accéder aux éléments enfants avec l'indexeur: xmlDoc ["Root"], et ceux-ci peuvent être chaînés: xmlDoc ["Root"] ["Folder"] ["Item"] pour creuser le hiérarchie (bien qu'il soit judicieux de valider que ces éléments existent réellement)
Jason Williams

1
InnerTextobtient ici la valeur de ce nœud, concaténée avec toutes les valeurs des nœuds enfants - non? On dirait une chose étrange à vouloir.
Don Cheadle

17
Un programmeur avec une liste d'amis féminines? Shenanigans!
E. van Putten

1
@ E.vanPutten pas de nos jours. Ce n'est pas la vengeance des nerds
user4052054

@DonCheadle Si vous ne vous attendez pas à ce qu'il y ait des nœuds enfants, alors InnerTextje retournerai simplement la valeur du nœud - c'est ce que moi (et probablement tous les autres lisant cette question) analysons le XML pour trouver en premier lieu.
F1Krazy

48

Utilisez un bon schéma XSD pour créer un ensemble de classes avec xsd.exe et utilisez un XmlSerializerpour créer une arborescence d'objets à partir de votre XML et vice versa. Si vous avez peu de restrictions sur votre modèle, vous pouvez même essayer de créer un mappage direct entre vos classes de modèle et le XML avec les attributs Xml *.

Il existe un article d'introduction sur la sérialisation XML sur MSDN.

Conseil de performance: la construction d'un XmlSerializerest coûteux. Conservez une référence à votre XmlSerializerinstance si vous avez l'intention d'analyser / écrire plusieurs fichiers XML.



5
Un bon exemple est l '"exemple de bon de commande" au milieu de cet exemple de Microsoft. msdn.microsoft.com/en-us/library/58a18dwa.aspx . Vous évitez d'avoir à créer un schéma - votre classe c # est le schéma, orné d'attributs C #.
Mark Lakata

25

Si vous traitez une grande quantité de données (plusieurs mégaoctets), vous souhaitez utiliser XmlReaderpour analyser le flux XML.

Tout le reste ( XPathNavigator, XElement, XmlDocumentet même XmlSerializersi vous gardez le plein objet graphique généré) se traduira par une utilisation élevée de la mémoire et aussi un temps de chargement très lent.

Bien sûr, si vous avez quand même besoin de toutes les données en mémoire, vous n'aurez peut-être pas beaucoup de choix.



10

Je viens récemment de devoir travailler sur une application qui impliquait l'analyse d'un document XML et je suis d'accord avec Jon Galloway que l'approche basée sur LINQ to XML est, à mon avis, la meilleure. J'ai cependant dû creuser un peu pour trouver des exemples utilisables, donc sans plus tarder, en voici quelques-uns!

Tous les commentaires sont les bienvenus car ce code fonctionne mais n'est peut-être pas parfait et j'aimerais en savoir plus sur l'analyse XML pour ce projet!

public void ParseXML(string filePath)  
{  
    // create document instance using XML file path
    XDocument doc = XDocument.Load(filePath);

    // get the namespace to that within of the XML (xmlns="...")
    XElement root = doc.Root;
    XNamespace ns = root.GetDefaultNamespace();

    // obtain a list of elements with specific tag
    IEnumerable<XElement> elements = from c in doc.Descendants(ns + "exampleTagName") select c;

    // obtain a single element with specific tag (first instance), useful if only expecting one instance of the tag in the target doc
    XElement element = (from c in doc.Descendants(ns + "exampleTagName" select c).First();

    // obtain an element from within an element, same as from doc
    XElement embeddedElement = (from c in element.Descendants(ns + "exampleEmbeddedTagName" select c).First();

    // obtain an attribute from an element
    XAttribute attribute = element.Attribute("exampleAttributeName");
}

Avec ces fonctions, j'ai pu analyser n'importe quel élément et n'importe quel attribut d'un fichier XML sans aucun problème!


8

Si vous utilisez .NET 2.0, essayez XmlReaderses sous XmlTextReader- classes et XmlValidatingReader. Ils fournissent un moyen rapide et léger (utilisation de la mémoire, etc.), de transférer uniquement un fichier XML.

Si vous avez besoin de XPathcapacités, essayez le XPathNavigator. Si vous avez besoin de l'intégralité du document en mémoire, essayez XmlDocument.


7

De plus, vous pouvez utiliser le sélecteur XPath de la manière suivante (moyen facile de sélectionner des nœuds spécifiques):

XmlDocument doc = new XmlDocument();
doc.Load("test.xml");

var found = doc.DocumentElement.SelectNodes("//book[@title='Barry Poter']"); // select all Book elements in whole dom, with attribute title with value 'Barry Poter'

// Retrieve your data here or change XML here:
foreach (XmlNode book in nodeList)
{
  book.InnerText="The story began as it was...";
}

Console.WriteLine("Display XML:");
doc.Save(Console.Out);

La documentation


6

Je ne sais pas s'il existe une "meilleure pratique pour l'analyse XML". Il existe de nombreuses technologies adaptées à différentes situations. Le mode d'utilisation dépend du scénario concret.

Vous pouvez aller avec LINQ pour XML , XmlReader, XPathNavigatorou même des expressions régulières. Si vous expliquez vos besoins, je peux essayer de vous faire quelques suggestions.


3
regex pour xml. Tu es un monstre.
le

3

Vous pouvez analyser le XML à l'aide de cette bibliothèque System.Xml.Linq. Voici l'exemple de code que j'ai utilisé pour analyser un fichier XML

public CatSubCatList GenerateCategoryListFromProductFeedXML()
{
    string path = System.Web.HttpContext.Current.Server.MapPath(_xmlFilePath);

    XDocument xDoc = XDocument.Load(path);

    XElement xElement = XElement.Parse(xDoc.ToString());


    List<Category> lstCategory = xElement.Elements("Product").Select(d => new Category
    {
        Code = Convert.ToString(d.Element("CategoryCode").Value),
        CategoryPath = d.Element("CategoryPath").Value,
        Name = GetCateOrSubCategory(d.Element("CategoryPath").Value, 0), // Category
        SubCategoryName = GetCateOrSubCategory(d.Element("CategoryPath").Value, 1) // Sub Category
    }).GroupBy(x => new { x.Code, x.SubCategoryName }).Select(x => x.First()).ToList();

    CatSubCatList catSubCatList = GetFinalCategoryListFromXML(lstCategory);

    return catSubCatList;
}

1

Vous pouvez utiliser ExtendedXmlSerializer pour sérialiser et désérialiser.

Instalation Vous pouvez installer ExtendedXmlSerializer à partir de nuget ou exécuter la commande suivante:

Install-Package ExtendedXmlSerializer

Sérialisation:

ExtendedXmlSerializer serializer = new ExtendedXmlSerializer();
var obj = new Message();
var xml = serializer.Serialize(obj);

Désérialisation

var obj2 = serializer.Deserialize<Message>(xml);

Le sérialiseur XML standard dans .NET est très limité.

  • Ne prend pas en charge la sérialisation de classe avec référence circulaire ou de classe avec propriété d'interface,
  • Ne prend pas en charge les dictionnaires,
  • Il n'y a pas de mécanisme pour lire l'ancienne version de XML,
  • Si vous souhaitez créer un sérialiseur personnalisé, votre classe doit hériter d'IXmlSerializable. Cela signifie que votre classe ne sera pas une classe POCO,
  • Ne prend pas en charge l'IoC.

ExtendedXmlSerializer peut faire cela et bien plus encore.

ExtendedXmlSerializer prend en charge .NET 4.5 ou supérieur et .NET Core . Vous pouvez l'intégrer à WebApi et AspCore.


1

Vous pouvez utiliser XmlDocument et pour manipuler ou récupérer des données à partir d'attributs, vous pouvez Linq en classes XML.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.