XDocument ou XmlDocument


502

Agora estou aprendendo, XmlDocumentmas acabei de encontrar XDocumente, quando tento pesquisar a diferença ou os benefícios deles, não consigo encontrar algo útil, você poderia me dizer por que usaria um sobre o outro?


13
Estou me perguntando por que a equipe de documentação da Microsoft não colocou nenhuma observação ou observação no MSDN para esclarecer suas diferenças ou quando usar o quê.
Kamran Bigdely

1
Algumas informações sobre o msdn : msdn.microsoft.com/en-us/library/… . E uma pergunta de desempenho: stackoverflow.com/questions/4383919/… . Pessoalmente, achei mais fácil trabalhar com LINQ to XML.
Nawfal 19/08

Respostas:


500

Se você estiver usando .NET versão 3.0 ou inferior, você tem de usar XmlDocumenttambém conhecido como o DOM API clássico. Da mesma forma, você encontrará outras APIs que esperam isso.

Se você escolher, no entanto, recomendo o uso do XDocumentLINQ to XML. É muito mais simples criar documentos e processá-los. Por exemplo, é a diferença entre:

XmlDocument doc = new XmlDocument();
XmlElement root = doc.CreateElement("root");
root.SetAttribute("name", "value");
XmlElement child = doc.CreateElement("child");
child.InnerText = "text node";
root.AppendChild(child);
doc.AppendChild(root);

e

XDocument doc = new XDocument(
    new XElement("root",
                 new XAttribute("name", "value"),
                 new XElement("child", "text node")));

É fácil trabalhar com namespaces no LINQ to XML, diferente de qualquer outra API XML que eu já vi:

XNamespace ns = "http://somewhere.com";
XElement element = new XElement(ns + "elementName");
// etc

O LINQ to XML também funciona muito bem com o LINQ - seu modelo de construção permite criar elementos com sequências de subelementos com muita facilidade:

// Customers is a List<Customer>
XElement customersElement = new XElement("customers",
    customers.Select(c => new XElement("customer",
        new XAttribute("name", c.Name),
        new XAttribute("lastSeen", c.LastOrder)
        new XElement("address",
            new XAttribute("town", c.Town),
            new XAttribute("firstline", c.Address1),
            // etc
    ));

É tudo muito mais declarativo, que se encaixa no estilo geral do LINQ.

Agora, como Brannon mencionou, essas são APIs na memória, em vez de streaming (embora XStreamingElementsuporte a saída lenta). XmlReadere XmlWritersão as formas normais de transmitir XML em .NET, mas você pode misturar todas as APIs até certo ponto. Por exemplo, você pode transmitir um documento grande, mas usar o LINQ to XML, posicionando um XmlReaderno início de um elemento, lendo um XElemente processando-o e depois passando para o próximo elemento etc. Há várias postagens de blog sobre essa técnica, aqui está um que encontrei com uma pesquisa rápida .


Você poderia me dizer por que eles são diferentes? Quero dizer, sim, o XDocument parece bastante elegante, mas quanto à diferença de nível do DOM, eles não são xml, existe algum esquema que mostre o Microsoft X-DOM e o DOM compatível com o W3C? Obrigado.
Tarik

3
O que você quer dizer com "esquema" e o que você quer dizer com "shows"? Sim, ambos lidam com XML padrão, mas o LINQ to XML é apenas uma API melhor para a maioria das coisas. Muita da tecnologia por trás do LINQ to XML simplesmente não estava disponível antes do .NET 3.5.
9139 Jon Skeet

Quero dizer, se os modelos de objetos de documentos são diferentes?
Tarik

6
Bem, ambas são APIs para o próprio XML, portanto, nesse sentido, não são diferentes, não. Eu suspeito que ambos têm algumas limitações (e há um LINQ to XML que eu conheço, mas não consigo me lembrar), mas na maioria dos casos você pode apenas tratá-los como sendo o mesmo modelo com representações ligeiramente diferentes.
Jon Skeet

1
@SensorSmith: Mas isso não cobre todos os outros bônus, como achatamento automático de seqüências, manipulação de DateTime etc. Você também pode adicionar métodos de extensões para tudo isso, mas por que reinventar o LINQ to XML quando você pode usá-lo?
21815 Jon Skeet

57

Surpreende-me que nenhuma das respostas até agora mencione o fato de XmlDocumentnão fornecer informações de linha , enquanto XDocumentfornece (através da IXmlLineInfointerface).

Isso pode ser um recurso crítico em alguns casos (por exemplo, se você deseja relatar erros em um XML ou acompanhar onde os elementos são definidos em geral) e é melhor estar ciente disso antes de começar a implementar usando XmlDocument, para posteriormente descubra que você precisa mudar tudo.


1
E estou surpreso que ninguém tenha notado que sua afirmação é inversamente verdadeira. O XmlDocument fornece as informações da linha, enquanto o XDocument não.
VVS

4
@VVS: você me preocupou por um momento que eu cometi um erro de digitação terrível, mas, após uma verificação dupla, confirmo que XDocumentisso fornece informações de linha. Consulte XDocument.Load with LoadOptions.SetLineInfocomo um segundo argumento. Se você conhece uma maneira de obter informações de linha, XmlDocumentestou curioso; Quando escrevi esta resposta, não encontrei nenhuma. Esta outra resposta parece confirmar: stackoverflow.com/a/33622102/253883 #
Julien Guertault

1
"e é melhor você estar ciente disso antes de começar a implementar o XmlDocument, para descobrir mais tarde que precisa mudar tudo." Adivinha o que eu fiz :)
Paul

36

XmlDocumenté ótimo para desenvolvedores familiarizados com o modelo de objeto XML DOM. Já existe há algum tempo e corresponde mais ou menos a um padrão W3C. Ele suporta navegação manual e XPathseleção de nós.

XDocumenthabilita o recurso LINQ to XML no .NET 3.5. Faz uso pesado IEnumerable<>e pode ser mais fácil trabalhar com C # direto.

Os dois modelos de documento exigem que você carregue o documento inteiro na memória (diferente de, XmlReaderpor exemplo).


3
Eu acho que você quis dizer "e pode ser mais fácil trabalhar com o VB.net direto". Como o VB oferece suporte à criação direta de elementos onde o C # ainda requer código.
precisa saber é o seguinte

24

XDocumenté da API LINQ to XML e XmlDocumenté a API padrão do estilo DOM para XML. Se você conhece bem o DOM e não quer aprender LINQ to XML, vá com XmlDocument. Se você é novato em ambos, confira esta página que compara os dois e escolha qual deles você mais gosta.

Acabei de começar a usar o LINQ to XML e adoro a maneira como você cria um documento XML usando construção funcional. É muito legal. DOM é desajeitado em comparação.


23

Como mencionado em outro lugar, sem dúvida, o Linq to Xml facilita muito a criação e a alteração de documentos xml XmlDocument, e a XNamespace ns + "elementName"sintaxe proporciona uma leitura agradável ao lidar com espaços para nome.

Uma coisa que vale a pena mencionar xsle xpathressaltar é que ainda é possível executar xpath 1.0expressões arbitrárias no Linq 2 Xml XNodes, incluindo:

using System.Xml.XPath;

e então podemos navegar e projetar dados usando xpathesses métodos de extensão:

Por exemplo, dado o documento Xml:

<xml>
    <foo>
        <baz id="1">10</baz>
        <bar id="2" special="1">baa baa</bar>
        <baz id="3">20</baz>
        <bar id="4" />
        <bar id="5" />
    </foo>
    <foo id="123">Text 1<moo />Text 2
    </foo>
</xml>

Podemos avaliar:

var node = xele.XPathSelectElement("/xml/foo[@id='123']");
var nodes = xele.XPathSelectElements(
"//moo/ancestor::xml/descendant::baz[@id='1']/following-sibling::bar[not(@special='1')]");
var sum = xele.XPathEvaluate("sum(//foo[not(moo)]/baz)");

14

Além disso, observe que XDocumenthá suporte para Xbox 360 e Windows Phone OS 7.0. Se você os segmentar, desenvolva XDocumentou migre para XmlDocument.


-8

Acredito que isso XDocumentfaça muito mais chamadas de criação de objetos. Eu suspeito que, quando você estiver lidando com muitos documentos XML, XMLDocumentserá mais rápido.

Um lugar em que isso acontece é no gerenciamento de dados de digitalização. Muitas ferramentas de varredura exibem seus dados em XML (por razões óbvias). Se você precisar processar muitos desses arquivos de digitalização, acho que terá melhor desempenho XMLDocument.


11
Acho que você deve apoiar seu comentário com números da próxima vez, pois acredito que você pode estar errado. Veja blogs.msdn.com/b/codejunkie/archive/2008/10/08/…
mike
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.