Pergunta

Eu quero ler um arquivo XML grande (100+m). Devido ao seu tamanho, não quero carregá -lo na memória usando o Xelement. Estou usando consultas Linq-xml para analisar e ler.

Qual é a melhor maneira de fazer isso? Algum exemplo sobre combinação de XPath ou XMLReader com Linq-xml/Xelement?

Por favor ajude. Obrigado.

Foi útil?

Solução

Sim, você pode combinar o XMLReader com o método xnode.readfrom, consulte o exemplo na documentação que usa C# para processar os nós seletivamente encontrados pelo XMLReader como um Xelement.

Outras dicas

O código de exemplo na documentação do MSDN para o XNode.ReadFrom O método é o seguinte:

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);
    }
}

Mas eu descobri que o StreamRootChildDoc O método no exemplo precisa ser modificado da seguinte forma:

    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();
                }
            }
        }
    }

Lembre -se de que você terá que ler o arquivo sequencialmente e se referir a irmãos ou descendentes será lento, na melhor das hipóteses, na pior das hipóteses. Caso contrário, @martinhonnn tem a chave.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top