Alteração de memória de árvore XML na compilação funcional (LINQ to XML)

Modificar uma árvore XML no local é uma abordagem tradicional para alterar a forma de um documento XML. Um aplicativo típico carrega um documento para um armazenamento de dados como DOM ou LINQ to XML; usa uma interface de programação para inserir nós, excluir nós ou modificar o conteúdo dos nós; então ele salva o XML em um arquivo ou fluxo em uma rede.

O LINQ to XML permite outra abordagem que é útil em muitos cenários: construção funcional. Deleites funcionais de compilação que modificam dados como um problema de transformação, em vez de como tratamento detalhada de um armazenamento de dados. Se você pode ter uma representação dos dados e a transformação com eficiência de um formulário para outro, o resultado é o mesmo como se você recebe um armazenamento de dados e o manipulou de alguma maneira para executar outra forma. Uma chave para a abordagem de construção funcional é passar os resultados de consultas para os construtores XDocument e XElement.

Em muitos casos você pode escrever código transformacional em uma fração do tempo levaria para manipular o armazenamento de dados, e a manutenção desse código resultante é mais fácil e robusta. Nesses casos, embora a abordagem transformacional possa usar mais poder de processamento, é um modo mais eficiente de modificar dados. Se um desenvolvedor estiver familiarizado com a abordagem funcional, o código resultante em muitos casos será mais fácil de entender, e será fácil encontrar o código que modifica cada parte da árvore.

A abordagem em que você altera uma árvore XML no local é mais familiar para muitos desenvolvedores DOM, enquanto o código escrito usando a abordagem funcional pode parecer estranha a um desenvolvedor que ainda não entende essa abordagem. Se você precisa apenas fazer uma alteração pequena a uma grande árvore XML, a abordagem onde você altera uma árvore no lugar em muitos casos terá menos processador central - tempo.

Este artigo dá exemplos de ambas as abordagens. Suponha que você queira modificar o seguinte documento XML simples de modo que os atributos se transformem em elementos:

<?xml version="1.0" encoding="utf-8" ?>
<Root Data1="123" Data2="456">
  <Child1>Content</Child1>
</Root>

O primeiro dos exemplos a seguir adota a abordagem tradicional de modificação in-loco; o segundo, usa a abordagem de construção funcional.

Exemplo: transformar atributos em elementos com a abordagem in-loco tradicional

Você pode escrever qualquer código procedural para criar elementos de atributos, e exclui os atributos, como segue:

XElement root = XElement.Load("Data.xml");
foreach (XAttribute att in root.Attributes()) {
    root.Add(new XElement(att.Name, (string)att));
}
root.Attributes().Remove();
Console.WriteLine(root);
Dim root As XElement = XElement.Load("Data.xml")
For Each att As XAttribute In root.Attributes()
    root.Add(New XElement(att.Name, att.Value))
Next
root.Attributes().Remove()
Console.WriteLine(root)

Esse exemplo gera a saída a seguir:

<Root>
  <Child1>Content</Child1>
  <Data1>123</Data1>
  <Data2>456</Data2>
</Root>

Exemplo: transformar atributos em elementos com a abordagem de construção funcional

Por outro lado, uma abordagem funcional consiste no código para formar uma nova árvore, selecionar e escolher elementos e atributos de árvore de origem e transformá-los como adequado conforme eles são adicionados à nova árvore.

XElement root = XElement.Load("Data.xml");
XElement newTree = new XElement("Root",
    root.Element("Child1"),
    from att in root.Attributes()
    select new XElement(att.Name, (string)att)
);
Console.WriteLine(newTree);
Dim root As XElement = XElement.Load("Data.xml")
Dim newTree As XElement = _
    <Root>
        <%= root.<Child1> %>
        <%= From att In root.Attributes() _
            Select New XElement(att.Name, att.Value) %>
    </Root>
Console.WriteLine(newTree)

Saída deste exemplo mesmo XML que o primeiro exemplo. No entanto, observe que você pode realmente consulte a estrutura XML resultante de novo na abordagem funcional. Você pode ver a criação do elemento de Root , o código que recebe o elemento de Child1 de árvore de origem, e o código que transforma os atributos de árvore de origem aos elementos na árvore novo.

O exemplo funcional nesse caso não é menor nem mais simples que o primeiro exemplo. Porém, se você tiver muitas alterações para fazer a uma árvore XML, a abordagem processual será bastante complexa e um tanto obtusa. Por outro lado, ao usar a abordagem funcional, você ainda forma apenas XML desejado, inserindo consultas e expressões apropriadas, para receber dentro do conteúdo desejado. Os passa funcionais de abordagem código que é mais fácil de manter.

Observe que neste caso a abordagem funcional provavelmente não deseja executar muito bem como a abordagem de manipulação de árvore. A principal problema é que a abordagem funcional cria um objetos mais breves. No entanto, as troca são eficiente usar a abordagem funcional permite maior produtividade do programador.

Este é um exemplo muito simples, mas serve para mostrar a diferença na filosofia entre as duas abordagens. A abordagem mais funcional fornece ganhos de produtividade para transformar documentos XML maiores.