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.

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top