Criar árvores XML em C# (LINQ to XML)
Este artigo fornece informações sobre a criação de árvores XML em C#.
Para obter informações sobre como usar os resultados de consultas LINQ como o conteúdo de um XElement, confira Construção funcional.
Construir elementos
As assinaturas dos construtores XElement e XAttribute permitem que você passe o conteúdo do elemento ou atributo como argumentos para o construtor. Como um dos construtores recebe um número variável de argumentos, você pode passar qualquer número de elementos filhos. Naturalmente, cada um desses elementos filhos pode conter seus próprios elementos filhos. Para qualquer elemento, você pode adicionar a quantidade desejada de atributos.
Ao adicionar objetos XNode (inclusive XElement) ou XAttribute, se o novo conteúdo não tiver um pai, os objetos serão simplesmente anexados à árvore XML. Se o novo conteúdo já tiver um pai e fizer parte de outra árvore XML, o novo conteúdo será clonado, e o conteúdo recém-clonado será anexado à árvore XML. O último exemplo deste artigo demonstra isso.
Para criar uma contacts
XElement, você poderia usar o seguinte código:
XElement contacts =
new XElement("Contacts",
new XElement("Contact",
new XElement("Name", "Patrick Hines"),
new XElement("Phone", "206-555-0144"),
new XElement("Address",
new XElement("Street1", "123 Main St"),
new XElement("City", "Mercer Island"),
new XElement("State", "WA"),
new XElement("Postal", "68042")
)
)
);
Se recuado corretamente, o código para criar objetos XElement é muito parecido com a estrutura do XML subjacente.
Construtores de XElement
A classe XElement usa os seguintes construtores na construção funcional. Observe que há outros construtores para XElement, mas como eles não são usados na construção funcional, eles não são listados aqui.
Construtor | Descrição |
---|---|
XElement(XName name, object content) |
Cria um XElement. O parâmetro name especifica o nome do elemento; content especifica o conteúdo do elemento. |
XElement(XName name) |
Cria um XElement com seu XName inicializado para o nome especificado. |
XElement(XName name, params object[] content) |
Cria um XElement com seu XName inicializado para o nome especificado. Os atributos e/ou elementos filhos são criados a partir do conteúdo da lista de parâmetros. |
O parâmetro content
é muito flexível. Ele dá suporte a qualquer tipo de objeto que seja um filho válido de um XElement. As seguintes regras se aplicam aos diferentes tipos de objetos passados neste parâmetro:
- Uma cadeia de caracteres é adicionada como conteúdo de texto.
- Um XElement é adicionado como um elemento filho.
- Um XAttribute é adicionado como um atributo.
- Um XProcessingInstruction, XComment ou XText é adicionado como conteúdo filho.
- Um IEnumerable é enumerado, e essas regras são aplicadas recursivamente aos resultados.
- Para qualquer outro tipo, seu método
ToString
é chamado e o resultado é adicionado como conteúdo de texto.
Exemplo: criar um XElement com conteúdo
Você pode criar um XElement contendo o conteúdo simples com uma única chamada de método. Para fazer isso, especifique o conteúdo como o segundo parâmetro, como segue:
XElement n = new XElement("Customer", "Adventure Works");
Console.WriteLine(n);
Esse exemplo gera a saída a seguir:
<Customer>Adventure Works</Customer>
Você pode passar qualquer tipo de objeto como o conteúdo. Por exemplo, o seguinte código cria um elemento que contém um número de ponto flutuante como conteúdo:
XElement n = new XElement("Cost", 324.50);
Console.WriteLine(n);
Esse exemplo gera a saída a seguir:
<Cost>324.5</Cost>
O número de ponto flutuante foi convertido e passado para o construtor. O número é convertido em uma cadeia de caracteres e usado como o conteúdo do elemento.
Exemplo: criar um XElement com um elemento filho
Se você passar uma instância da classe XElement para o argumento de conteúdo, o construtor criará um elemento com um elemento filho:
XElement shippingUnit = new XElement("ShippingUnit",
new XElement("Cost", 324.50)
);
Console.WriteLine(shippingUnit);
Esse exemplo gera a saída a seguir:
<ShippingUnit>
<Cost>324.5</Cost>
</ShippingUnit>
Exemplo: Criar um XElement com vários elementos filho
Você pode passar um número de objetos XElement para o conteúdo. Cada um dos objetos XElement é incluído como um elemento filho.
XElement address = new XElement("Address",
new XElement("Street1", "123 Main St"),
new XElement("City", "Mercer Island"),
new XElement("State", "WA"),
new XElement("Postal", "68042")
);
Console.WriteLine(address);
Esse exemplo gera a saída a seguir:
<Address>
<Street1>123 Main St</Street1>
<City>Mercer Island</City>
<State>WA</State>
<Postal>68042</Postal>
</Address>
Por extensão ao exemplo anterior, você pode criar uma árvore XML inteira, desta forma:
XElement contacts =
new XElement("Contacts",
new XElement("Contact",
new XElement("Name", "Patrick Hines"),
new XElement("Phone", "206-555-0144"),
new XElement("Address",
new XElement("Street1", "123 Main St"),
new XElement("City", "Mercer Island"),
new XElement("State", "WA"),
new XElement("Postal", "68042")
)
)
);
Console.WriteLine(contacts);
Esse exemplo gera a saída a seguir:
<Contacts>
<Contact>
<Name>Patrick Hines</Name>
<Phone>206-555-0144</Phone>
<Address>
<Street1>123 Main St</Street1>
<City>Mercer Island</City>
<State>WA</State>
<Postal>68042</Postal>
</Address>
</Contact>
</Contacts>
Exemplo: criar um XElement com um XAttribute
Se você passar uma instância da classe XAttribute para o argumento de conteúdo, o construtor criará um elemento com um atributo:
XElement phone = new XElement("Phone",
new XAttribute("Type", "Home"),
"555-555-5555");
Console.WriteLine(phone);
Esse exemplo gera a saída a seguir:
<Phone Type="Home">555-555-5555</Phone>
Exemplo: criar um elemento vazio
Para criar um XElement vazio, não passe conteúdo para o construtor. O seguinte exemplo cria um elemento vazio:
XElement n = new XElement("Customer");
Console.WriteLine(n);
Esse exemplo gera a saída a seguir:
<Customer />
Exemplo: anexar vs. clonar
Conforme citado anteriormente, ao adicionar objetos XNode (inclusive XElement) ou XAttribute, se o novo conteúdo não tiver um pai, os objetos serão simplesmente anexados à árvore XML. Se o novo conteúdo já tiver um pai e fizer parte de outra árvore XML, o novo conteúdo será clonado, e o conteúdo recém-clonado será anexado à árvore XML.
O seguinte exemplo demonstra o comportamento quando você adiciona um elemento com uma relação de pai a uma árvore, e quando você adiciona um elemento sem relação de pai a uma árvore:
// Create a tree with a child element.
XElement xmlTree1 = new XElement("Root",
new XElement("Child1", 1)
);
// Create an element that's not parented.
XElement child2 = new XElement("Child2", 2);
// Create a tree and add Child1 and Child2 to it.
XElement xmlTree2 = new XElement("Root",
xmlTree1.Element("Child1"),
child2
);
// Compare Child1 identity.
Console.WriteLine("Child1 was {0}",
xmlTree1.Element("Child1") == xmlTree2.Element("Child1") ?
"attached" : "cloned");
// Compare Child2 identity.
Console.WriteLine("Child2 was {0}",
child2 == xmlTree2.Element("Child2") ?
"attached" : "cloned");
// This example produces the following output:
// Child1 was cloned
// Child2 was attached