Como: Transformar a forma de uma árvore XML
A forma de um documento XML se refere a seus nomes de elemento, nomes de atributo, e as características da sua hierarquia.
Às vezes você precisará alterar a forma de um documento XML. Por exemplo, você pode ter que enviar um documento XML existente para outro sistema que requer nomes diferentes de elementos e atributos. Você pode examinar o documento, excluir e renomeando elementos conforme necessário, mas usando funcionais resultados de compilação em um código mais legível e mais sustentável. Para obter mais informações sobre a compilação funcional, consulte Construção funcional (LINQ to XML).
O primeiro exemplo altera a organização de documento XML. Mover elementos complexos de um local na árvore para outro.
O segundo exemplo neste tópico cria um documento XML com uma forma diferente do documento de origem. Altera a caixa de nomes de elemento, renomear alguns elementos, e permitir que alguns elementos da árvore de origem fora da árvore transformada.
Exemplo
As seguintes alterações de código a forma de um arquivo XML usando expressões inseridas de consulta.
O documento XML de origem neste exemplo contém um elemento de Customers no elemento de Root que contém todos os clientes. Também contém um elemento de Orders no elemento de Root que contém todos os pedidos. Este exemplo cria uma nova árvore XML em que os pedidos para cada cliente estão contidos em um elemento de Orders dentro do elemento de Customer . O documento original também contém um elemento de CustomerID no elemento de Order ; este elemento será removido do documento reformulado.
Este exemplo usa o seguinte documento XML: Arquivo XML de exemplo: clientes e pedidos (LINQ to XML).
XElement co = XElement.Load("CustomersOrders.xml");
XElement newCustOrd =
new XElement("Root",
from cust in co.Element("Customers").Elements("Customer")
select new XElement("Customer",
cust.Attributes(),
cust.Elements(),
new XElement("Orders",
from ord in co.Element("Orders").Elements("Order")
where (string)ord.Element("CustomerID") == (string)cust.Attribute("CustomerID")
select new XElement("Order",
ord.Attributes(),
ord.Element("EmployeeID"),
ord.Element("OrderDate"),
ord.Element("RequiredDate"),
ord.Element("ShipInfo")
)
)
)
);
Console.WriteLine(newCustOrd);
Dim co As XElement = XElement.Load("CustomersOrders.xml")
Dim newCustOrd = _
<Root>
<%= From cust In co.<Customers>.<Customer> _
Select _
<Customer>
<%= cust.Attributes() %>
<%= cust.Elements() %>
<Orders>
<%= From ord In co.<Orders>.<Order> _
Where ord.<CustomerID>.Value = cust.@CustomerID _
Select _
<Order>
<%= ord.Attributes() %>
<%= ord.<EmployeeID> %>
<%= ord.<OrderDate> %>
<%= ord.<RequiredDate> %>
<%= ord.<ShipInfo> %>
</Order> _
%>
</Orders>
</Customer> _
%>
</Root>
Console.WriteLine(newCustOrd)
Esse código gera a seguinte saída:
<Root>
<Customer CustomerID="GREAL">
<CompanyName>Great Lakes Food Market</CompanyName>
<ContactName>Howard Snyder</ContactName>
<ContactTitle>Marketing Manager</ContactTitle>
<Phone>(503) 555-7555</Phone>
<FullAddress>
<Address>2732 Baker Blvd.</Address>
<City>Eugene</City>
<Region>OR</Region>
<PostalCode>97403</PostalCode>
<Country>USA</Country>
</FullAddress>
<Orders />
</Customer>
<Customer CustomerID="HUNGC">
<CompanyName>Hungry Coyote Import Store</CompanyName>
<ContactName>Yoshi Latimer</ContactName>
<ContactTitle>Sales Representative</ContactTitle>
<Phone>(503) 555-6874</Phone>
<Fax>(503) 555-2376</Fax>
<FullAddress>
<Address>City Center Plaza 516 Main St.</Address>
<City>Elgin</City>
<Region>OR</Region>
<PostalCode>97827</PostalCode>
<Country>USA</Country>
</FullAddress>
<Orders />
</Customer>
. . .
Este exemplo renomeia alguns elementos e converte alguns atributos para elementos.
O código chama ConvertAddress, que retorna uma lista de objetos XElement . O argumento para o método é uma consulta que determina o elemento complexo de Address onde o atributo de Type tem um valor de "Shipping".
Este exemplo usa o seguinte documento XML: Arquivo XML de exemplo: ordem de compra típica (LINQ to XML).
static IEnumerable<XElement> ConvertAddress(XElement add)
{
List<XElement> fragment = new List<XElement>() {
new XElement("NAME", (string)add.Element("Name")),
new XElement("STREET", (string)add.Element("Street")),
new XElement("CITY", (string)add.Element("City")),
new XElement("ST", (string)add.Element("State")),
new XElement("POSTALCODE", (string)add.Element("Zip")),
new XElement("COUNTRY", (string)add.Element("Country"))
};
return fragment;
}
static void Main(string[] args)
{
XElement po = XElement.Load("PurchaseOrder.xml");
XElement newPo = new XElement("PO",
new XElement("ID", (string)po.Attribute("PurchaseOrderNumber")),
new XElement("DATE", (DateTime)po.Attribute("OrderDate")),
ConvertAddress(
(from el in po.Elements("Address")
where (string)el.Attribute("Type") == "Shipping"
select el)
.First()
)
);
Console.WriteLine(newPo);
}
Function ConvertAddress(ByVal add As XElement) As IEnumerable(Of XElement)
Dim fragment = New List(Of XElement)
fragment.Add(<NAME><%= add.<Name>.Value %></NAME>)
fragment.Add(<STREET><%= add.<Street>.Value %></STREET>)
fragment.Add(<CITY><%= add.<City>.Value %></CITY>)
fragment.Add(<ST><%= add.<State>.Value %></ST>)
fragment.Add(<POSTALCODE><%= add.<Zip>.Value %></POSTALCODE>)
fragment.Add(<COUNTRY><%= add.<Country>.Value %></COUNTRY>)
Return fragment
End Function
Sub Main()
Dim po As XElement = XElement.Load("PurchaseOrder.xml")
Dim newPo As XElement = _
<PO>
<ID><%= po.@PurchaseOrderNumber %></ID>
<DATE><%= CDate(po.@OrderDate) %></DATE>
<%= _
ConvertAddress( _
(From el In po.<Address> _
Where el.@Type = "Shipping" _
Select el) _
.First() _
) _
%>
</PO>
Console.WriteLine(newPo)
End Sub
Esse código gera a seguinte saída:
<PO>
<ID>99503</ID>
<DATE>1999-10-20T00:00:00</DATE>
<NAME>Ellen Adams</NAME>
<STREET>123 Maple Street</STREET>
<CITY>Mill Valley</CITY>
<ST>CA</ST>
<POSTALCODE>10999</POSTALCODE>
<COUNTRY>USA</COUNTRY>
</PO>