Come leggere file di grandi dimensioni XML senza caricarla in memoria e utilizzando XElement
-
20-09-2019 - |
Domanda
Voglio leggere un file di grandi dimensioni XML (100 + M). Grazie alle sue dimensioni, non voglio caricare in memoria usando XElement. Sto usando query LINQ-XML per analizzare e leggerlo.
Qual è il modo migliore per farlo? Qualsiasi esempio a combinazione di XPath o XmlReader con LINQ-xml / XElement?
Si prega di aiuto. Grazie.
Soluzione
Sì, è possibile combinare XmlReader con la metodo XNode.ReadFrom , vedi esempio nella documentazione che utilizza C # per elaborare selettivamente i nodi trovati dai XmlReader come XElement.
Altri suggerimenti
Il codice di esempio nella documentazione MSDN per il metodo XNode.ReadFrom
è il seguente:
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);
}
}
Ma ho trovato che il metodo StreamRootChildDoc
nell'esempio deve essere modificato come segue:
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();
}
}
}
}
Basta tenere a mente che si dovrà leggere il file in modo sequenziale e facendo riferimento alle fratelli o discendenti sta per essere lento al meglio e nel peggiore dei casi impossibili. In caso contrario, @MartinHonnn ha la chiave.