Le moyen le plus rapide pour analyser des fichiers XML en C#?
J'ai pour charger plusieurs fichiers XML à partir d'internet. Mais pour le test avec une meilleure vitesse, j'ai téléchargé tous d'entre eux (plus de 500 fichiers) de la forme suivante.
<player-profile>
<personal-information>
<id>36</id>
<fullname>Adam Gilchrist</fullname>
<majorteam>Australia</majorteam>
<nickname>Gilchrist</nickname>
<shortName>A Gilchrist</shortName>
<dateofbirth>Nov 14, 1971</dateofbirth>
<battingstyle>Left-hand bat</battingstyle>
<bowlingstyle>Right-arm offbreak</bowlingstyle>
<role>Wicket-Keeper</role>
<teams-played-for>Western Australia, New South Wales, ICC World XI, Deccan Chargers, Australia</teams-played-for>
<iplteam>Deccan Chargers</iplteam>
</personal-information>
<batting-statistics>
<odi-stats>
<matchtype>ODI</matchtype>
<matches>287</matches>
<innings>279</innings>
<notouts>11</notouts>
<runsscored>9619</runsscored>
<highestscore>172</highestscore>
<ballstaken>9922</ballstaken>
<sixes>149</sixes>
<fours>1000+</fours>
<ducks>0</ducks>
<fifties>55</fifties>
<catches>417</catches>
<stumpings>55</stumpings>
<hundreds>16</hundreds>
<strikerate>96.95</strikerate>
<average>35.89</average>
</odi-stats>
<test-stats>
.
.
.
</test-stats>
<t20-stats>
.
.
.
</t20-stats>
<ipl-stats>
.
.
.
</ipl-stats>
</batting-statistics>
<bowling-statistics>
<odi-stats>
<matchtype>ODI</matchtype>
<matches>378</matches>
<ballsbowled>58</ballsbowled>
<runsgiven>64</runsgiven>
<wickets>3</wickets>
<fourwicket>0</fourwicket>
<fivewicket>0</fivewicket>
<strikerate>19.33</strikerate>
<economyrate>6.62</economyrate>
<average>21.33</average>
</odi-stats>
<test-stats>
.
.
.
</test-stats>
<t20-stats>
.
.
.
</t20-stats>
<ipl-stats>
.
.
.
</ipl-stats>
</bowling-statistics>
</player-profile>
Je suis en utilisant
XmlNodeList list = _document.SelectNodes("/player-profile/batting-statistics/odi-stats");
Et puis la boucle de cette liste avec foreach
comme
foreach (XmlNode stats in list)
{
_btMatchType = GetInnerString(stats, "matchtype"); //it returns null string if node not availible
.
.
.
.
_btAvg = Convert.ToDouble(stats["average"].InnerText);
}
Même je suis le chargement de tous les fichiers hors connexion, l'analyse est très lent
Est-il un bon moyen plus rapide pour les analyser? Ou est-il problème avec SQL? Je suis sauver toutes les données extraites à partir de XML dans la base de données à l'aide de jeux de données, TableAdapters avec la commande insert.
EDIT: Maintenant pour l'utilisation de XmlReader veuillez donner un peu de code de XmlReader pour le document ci-dessus. pour l'instant, j'ai fait ce
void Load(string url)
{
_reader = XmlReader.Create(url);
while (_reader.Read())
{
}
}
Availible des Méthodes pour XmlReader sont source de confusion. Ce que j'ai besoin est d'obtenir le frappeur et le bowling stats complètement, le frappeur et le bowling stats sont différentes, et que l'odi,t2o,ipl, etc sont les mêmes à l'intérieur de bowling et au bâton.
Non, je n'ai pas, est-ce la meilleure approche?
Vous devrez peut-être deux questions distinctes (chargement de fichier, le noeud de l'extraction, de la base de données des interactions etc) pour clouer les goulets d'étranglement. Il existe plusieurs façons d'améliorer les performances de chaque composant.
Je suis étudiant, ce travail est une partie de mon projet. Pour l'instant, j'ai fait une classe qui analyse tous ces fichiers XML et de les enregistrer dans la base de données à partir de l'intérieur de cette classe. Oui ce serait mieux si je peux sperate composants mais je ne sais pas comment faire, pouvez-vous me donner un lien pour apprendre?
OriginalL'auteur SMUsamaShah | 2010-06-15
Vous devez vous connecter pour publier un commentaire.
La surcharge de lancer des exceptions probablement nains de la surcharge d'analyse XML. Vous avez besoin de réécrire le code pour qu'il ne jette pas des exceptions.
Une façon est de vérifier l'existence d'un élément avant de poser la question de sa valeur. Cela fonctionnera, mais c'est beaucoup de code. Une autre façon de faire serait d'utiliser une carte:
Ce code permet de gérer tous les éléments dont les noms vous vous souciez et d'ignorer ceux qui ne le sont pas. Si la valeur de la carte est nulle, cela signifie qu'un élément de ce nom n'existait pas (ou n'avait pas de texte).
En fait, si vous affichez les données dans un
DataTable
, et les noms de colonne dans laDataTable
sont les mêmes que les noms des éléments dans le document XML, vous n'avez même pas besoin de construire une carte, depuis leDataTable.Columns
propriété est toute la carte dont vous avez besoin. Aussi, depuis leDataColumn
sait quel type de données qu'il contient, vous n'avez pas à dupliquer cette connaissance dans votre code:Remarquez comment je ne suis pas déclarer toutes les variables pour stocker cette information, donc il n'y a aucune chance de me foutre en l'air et la déclaration d'une variable d'un type de données différent de la colonne, il est stocké dans, ou la création d'une colonne dans ma table et en oubliant de mettre en œuvre la logique qui le remplit.
Modifier
Bon, voilà quelque chose qui est un peu tricksy. C'est une question assez technique courante en Python, en C#, je pense que la plupart des gens pensent encore il y a quelque chose de bizarre à ce sujet.
Si vous regardez le deuxième exemple que j'ai donné, vous pouvez voir que c'est à l'aide de la meta-information dans le
DataColumn
de comprendre à quelle logique à utiliser pour la conversion d'une valeur de l'élément de texte à son type de base. Vous pouvez accomplir la même chose à la construction de votre propre carte, par exemple:et ensuite de faire à peu près la même chose que j'ai montré dans le deuxième exemple:
Vos résultats peuvent ne plus être un
Dictionary<string, string>
, car ils peuvent contenir des choses qui ne sont pas des chaînes; ils doivent être uneDictionary<string, object>
.Mais cette logique semble un peu maladroits; vous êtes à l'analyse de chaque élément plusieurs fois, il y a
continue
déclarations de sortir de celui - ci- il n'est pas terrible, mais il pourrait être plus concis. Comment? En utilisant une autre carte, celle que les cartes de types de fonctions de conversion:C'est un peu dur à lire, si vous n'êtes pas habitué à des expressions lambda. Le type
Func<string, object>
spécifie une fonction qui prend unstring
comme argument et retourne un objet. Et c'est ce que les valeurs de cette carte sont les suivants: ils sont les expressions lambda, c'est à dire des fonctions. Ils prennent un argument de type chaîne (x
), et ils retournent un objet. (Comment savons-nous quex
est une chaîne de caractères? LeFunc<string, object>
nous le dit.)Cela signifie que la conversion d'un élément peut prendre une ligne de code:
Aller de l'intérieur vers l'extérieur d'expression, ce qui regarde le type de l'élément dans
typeMap
, et se penche ensuite la fonction de conversion enconversionMap
, et les appels de fonction, en passant ilelm.Text
comme un argument.Cela peut ne pas être l'approche idéale dans votre cas. Je ne sais vraiment pas. Je montre ici parce qu'il y a un problème plus important à jouer. Comme Steve McConnell points dans Code Complet, il est plus facile de données de débogage que c'est le débogage de code. Cette technique permet de désactiver la logique du programme dans les données. Il y a des cas où l'utilisation de cette technique simplifie grandement la structure de votre programme. Il vaut la peine de comprendre.
Wow c'est génial, maintenant je sais que la première méthode. Il est beaucoup plus simple, mais je ne peux utiliser la première méthode que j'utilise tableAdapter pour stocker des données.
Depuis le point de l'ensemble d'un TableAdapter est de simplifier l'adaptation de tables de données SQL, ce commentaire ne semble pas avoir de sens pour moi.
Je suis actuellement en utilisant le
Dictionary<string, string>
mais il peut stocker qu'un seul type de données. Alors que XML a différents type de données, comme int, double, Datetime, de Temps etc.. Comment puis-je utiliser le dictionnaire pour qui?La réponse courte est que vous devez utiliser
Dictionary<string, object>
. Pour la réponse longue, voir mon edit.OriginalL'auteur Robert Rossney
Vous pouvez utiliser un XmlReader pour uniquement vers l'avant, la lecture rapide.
stats["average"].InnerText
, là où "moyenne" est un nom de nœudHmm ; si il y a beaucoup d'éléments manquants partie de vos problèmes de performances peuvent porter sur le nombre de l'exception levée. Les Exceptions sont chers. La vérification de la présence d'un nœud avant de référence, il est beaucoup moins cher.
ont une fonction comme getAttribute(string statname) qui utilise les stats[statname] à l'intérieur d'un bloc try/catch et renvoie la chaîne de caractères.Vide chaque fois qu'une exception est interceptée.
Si vous obtenez un nullreference ici, c'est que les stats["moyenne"] est null. Il suffit d'ajouter une (si stats["moyenne"] != null)) vérifier.
je l'ai déjà fait, GetInnerString() ne fait que de la tâche.
OriginalL'auteur Carra
Vous pouvez essayer de LINQ to XML. Ou vous pouvez utiliser cette à la figure ce qu'il faut utiliser.
OriginalL'auteur Chandam
Si les documents sont volumineux, puis un flux d'analyseur (qui est très bien pour vos besoins) sera plus rapide que d'utiliser XmlDocument, principalement en raison de la baisse des frais généraux. Consultez la documentation de XmlReader.
OriginalL'auteur Adrian
Je ne dirais pas que LINQ est la meilleure approche. J'ai cherché sur Google et j'ai vu des références à HTML Agility Pack .
Je pense que si vous allez avoir un goulot d'étranglement de vitesse, ce sera avec votre processus de téléchargement. En d'autres termes, il semble que vos problèmes de performances ne sont pas avec votre code XML. Je pense qu'il y a des façons d'améliorer votre vitesse de téléchargement peut-être ou que votre fichier i/o, mais je ne sais pas ce qu'ils voudraient être.
HTML Agility pack est utilisée pour analyser le html. Il est plus tolérant que l'analyse de xml. Encore, de vérifier si le goulot d'étranglement est dans le téléchargement des fichiers est une bonne idée.
OriginalL'auteur djangofan
Si vous savoir que le XML est conforme et bien formé, vous pouvez simplement éviter de faire de réel, d'analyse XML et juste de les traiter comme des fichiers de texte plats. C'est risqué, non portable, et cassants.
Mais ça va être le plus rapide à exécuter, pas de code) solution.
+1..pour être honnête et donner la solution la plus rapide
OriginalL'auteur Joshua Muskovitz
Un XmlReader est la solution à votre problème. Un XmlDocument contient beaucoup de méta-informations qui rendent le Xml facile d'accès, mais il devient trop lourd sur la mémoire. J'ai vu certains Xmls de taille de moins de 50 KO converti à quelques mo (10 ou quelque chose) de XmlDocument.
void Load(string url) { _reader = XmlReader.Create(url); while (_reader.Read()) { } }
Availible des Méthodes pour XmlReader sont source de confusion. Ce que j'ai besoin est d'obtenir le frappeur et le bowling stats complètement, le frappeur et le bowling stats sont différentes, et que l'odi,t2o,ipl, etc sont les mêmes à l'intérieur de bowling et au bâton.void Load(string url) { _reader = XmlReader.Créer des url (); while (_reader.Read()) { _reader.Nom; // Donne le nom _reader.Valeur; // Donne la Valeur comme une chaîne de caractères } } Veuillez vérifier MSDN pour plus de détails. Vous devrez vérifier HasValues, HasAttributes, etc.
XmlReader est difficile à mettre en œuvre, XmlDocument est facile, le problème n'était pas avec XmlDocument, il a été lente en raison de try catch consolidés. Merci pour l'aide.
OriginalL'auteur Sudesh Sawant
Si vous êtes déjà en train de convertir cette information dans un ensemble de données à insérer dans les tables, il suffit d'utiliser un jeu de données.ReadXML() - et de travailler avec les tables par défaut, il crée à partir des données.
Ce jouet app fait ça, et il fonctionne avec le format que vous avez défini ci-dessus.
Fichier de projet: http://www.dot-dash-dot.com/files/wtfxml.zip
Programme d'installation: http://www.dot-dash-dot.com/files/WTFXMLSetup_1_8_0.msi
Il vous permet de parcourir, éditer votre fichier XML à l'aide d'un arbre et format de grille - les tableaux figurant dans la grille sont ceux créés automatiquement par le jeu de données après ReadXML().
OriginalL'auteur Ron Savage