2010-01-11 4 views
2

Je travaille avec de très gros fichiers XML (100s de MBs). L'arbre est assez simpleQuel est le moyen le plus rapide de supprimer des noeuds d'un grand fichier XML en utilisant .net?

<items> 
    <item> 
    <column1>ABC</column1> 
    <column2>DEF</column2> 
    </item> 
    <item> 
    <column1>GHI</column1> 
    <column2>KLM</column2> 
    </item> 
</items> 

je dois analyser ce document et supprimer certains éléments <item>. Jusqu'à présent, la meilleure performance que j'ai obtenue est d'utiliser XmlReader, en mettant en cache chaque <item> en mémoire et de l'écrire en utilisant XmlWriter s'il répond aux critères, et en l'ignorant simplement si ce n'est pas le cas. Y at-il quelque chose que je peux faire pour le rendre plus rapide?

+0

Vous cherchez une solution .Net? – womp

+0

oui, je cherche. Net, désolé de ne pas clarifier cela – PBG

+0

Quel genre de performance voyez-vous maintenant et combien de temps avez-vous besoin qu'il soit? S'agit-il d'une migration ponctuelle (c'est-à-dire de parcourir tous les documents existants et de supprimer les «mauvaises» données) ou d'une opération en cours (nous recevons ces documents 100 Mo toutes les N minutes et les nettoyons avant de les utiliser)? –

Répondre

1

Vous pourriez être en mesure d'économiser une étape en mettant en place une sous-classe de XmlReader dont Read méthode saute sur les item éléments que vous n'êtes pas intéressé à ce moment, vous semblez avoir deux étapes: la lecture et le filtrage du document avec une XmlReader puis en utilisant XmlWriter pour l'écrire sur quelque chose dont vous l'avez probablement lu. Le sous-classement XmlReader élimine cette deuxième étape; vous utilisez le sous-classé XmlReader comme entrée pour votre transformation XSLT ou XmlDocument ou autre, et il ne construit jamais une représentation intermédiaire du document XML filtré.

+0

Cela peut fonctionner, mais une fois que j'ai lu en avant, si mon article est bon, je vais devoir déplacer mon "curseur" au début de l'article. Comment je fais ça? – PBG

+0

Eh bien, il y a (au moins) deux façons. Vous pouvez faire en sorte que votre XmlReader vérifie sa propriété CanSeek de Stream à la création et lance une exception si elle ne peut pas chercher; alors vous savez que vous pouvez enregistrer la position dans le flux lorsque vous commencez à analyser un élément, et si l'élément est bon, vous pouvez l'analyser à nouveau. Le meilleur moyen est de construire une sorte de représentation intermédiaire pour chaque nœud - le XmlNodeType, Name, Value, etc. - et de l'enregistrer dans une liste.Ensuite, lancez la liste d'une manière ou mettez à jour les propriétés de XmlReader à partir de l'élément suivant dans la liste lorsque Read est appelée. –

0

Vous pouvez utiliser les scripts perl ou shell pour remplacer les éléments requis si vous pouvez écrire une expression régulière rapide pour s'en débarrasser. Cela éviterait de charger le tout dans la mémoire et de l'écrire à nouveau. .

+0

En général, les expressions régulières ne peuvent pas être utilisées pour faire correspondre XML (ou HTML), car elles ne sont pas des langues régulières. –

0

voir si vous pouvez utiliser xpath querys pour déterminer ce que vous voulez et ne voulez pas lire avec cet objet xmldocument .... regardez dans les méthodes suivantes de cette classe SelectSingleNode() qui renvoie un objet XmlNode ... SelectNodes() qui renvoie un objet XmlNodeList .... voir si cela aide ....

Questions connexes