Comment lire un grand fichier XML sans le charger en mémoire et en utilisant XElement
-
20-09-2019 - |
Question
Je veux lire un gros fichier xml (100 + M). En raison de sa taille, je ne veux pas le charger en mémoire à l'aide XElement. J'utilise les requêtes LINQ-xml pour analyser et lire.
Quelle est la meilleure façon de le faire? Tout exemple sur une combinaison de XPath ou XmlReader avec LINQ-xml / XElement?
S'il vous plaît aider. Merci.
La solution
Oui, vous pouvez combiner XmlReader avec le procédé XNode.ReadFrom , voir l'exemple de la documentation qui utilise C # pour traiter sélectivement les noeuds trouvés par le XmlReader comme un XElement.
Autres conseils
Le code exemple dans la documentation MSDN pour la méthode de XNode.ReadFrom
est la suivante:
class Program
{
static IEnumerable<XElement> StreamRootChildDoc(string uri)
{
using (XmlReader reader = XmlReader.Create(uri))
{
reader.MoveToContent();
// Parse the file and display each of the nodes.
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
if (reader.Name == "Child")
{
XElement el = XElement.ReadFrom(reader) as XElement;
if (el != null)
yield return el;
}
break;
}
}
}
}
static void Main(string[] args)
{
IEnumerable<string> grandChildData =
from el in StreamRootChildDoc("Source.xml")
where (int)el.Attribute("Key") > 1
select (string)el.Element("GrandChild");
foreach (string str in grandChildData)
Console.WriteLine(str);
}
}
Mais j'ai trouvé que la méthode StreamRootChildDoc
dans l'exemple doit être modifié comme suit:
static IEnumerable<XElement> StreamRootChildDoc(string uri)
{
using (XmlReader reader = XmlReader.Create(uri))
{
reader.MoveToContent();
// Parse the file and display each of the nodes.
while (!reader.EOF)
{
if (reader.NodeType == XmlNodeType.Element && reader.Name == "Child")
{
XElement el = XElement.ReadFrom(reader) as XElement;
if (el != null)
yield return el;
}
else
{
reader.Read();
}
}
}
}
Il suffit de garder à l'esprit que vous devrez lire le fichier de manière séquentielle et en se référant aux frères et soeurs ou descendants va être au pire lent, au mieux, et impossible. Dans le cas contraire @MartinHonnn a la clé.