So lesen Sie eine große XML -Datei, ohne sie in den Speicher zu laden und Xelement zu verwenden
-
20-09-2019 - |
Frage
Ich möchte eine große XML -Datei (100+m) lesen. Aufgrund seiner Größe möchte ich es nicht mit Xelement im Speicher laden. Ich verwende Linq-XML-Abfragen, um es zu analysieren und zu lesen.
Was ist der beste Weg, es zu tun? Ein Beispiel zur Kombination von XPath oder XMLReader mit linq-xml/xelement?
Bitte helfen Sie. Vielen Dank.
Lösung
Ja, Sie können XMLreader mit dem kombinieren Methode xnode.readfrom, Siehe das Beispiel in der Dokumentation, in der C# zum selektiven Verarbeiten von Knoten des XMLReaders als Xelement verarbeitet wird.
Andere Tipps
Der Beispielcode in der MSDN -Dokumentation für die XNode.ReadFrom
Methode ist wie folgt:
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);
}
}
Aber ich habe festgestellt, dass die StreamRootChildDoc
Die Methode im Beispiel muss wie folgt geändert werden:
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();
}
}
}
}
Denken Sie nur daran, dass Sie die Datei nacheinander lesen müssen und sich auf Geschwister oder Nachkommen beziehen müssen, wird im schlimmsten Fall im besten Fall langsam und unmöglich sein. Andernfalls hat @MartinHonnn den Schlüssel.