Como encadear chamadas de método do eixo (LINQ to XML)

Um padrão comum que você usar em seu código é chamar um método do eixo, então chama um dos eixos do método de extensão.

Há dois eixos com o nome de Elements que retornam uma coleção de elementos: o método de XContainer.Elements e o método de Extensions.Elements . Você pode combinar esses dois eixos para localizar todos os elementos de um nome especificado em uma determinada profundidade na árvore.

Exemplo: recuperar todos os elementos de nome

Este exemplo usa XContainer.Elements e Extensions.Elements para recuperar todos os elementos Name em todos os elementos Address em todos os elementos PurchaseOrder.

O exemplo usa o documento XML Arquivo XML de exemplo: várias ordens de compra.

XElement purchaseOrders = XElement.Load("PurchaseOrders.xml");
IEnumerable<XElement> names =
    from el in purchaseOrders
        .Elements("PurchaseOrder")
        .Elements("Address")
        .Elements("Name")
    select el;
foreach (XElement e in names)
    Console.WriteLine(e);
Dim purchaseOrders As XElement = XElement.Load("PurchaseOrders.xml")
Dim names As IEnumerable(Of XElement) = _
    From el In purchaseOrders.<PurchaseOrder>.<Address>.<Name> _
    Select el
For Each e As XElement In names
    Console.WriteLine(e)
Next

Esse exemplo gera a saída a seguir:

<Name>Ellen Adams</Name>
<Name>Tai Yee</Name>
<Name>Cristian Osorio</Name>
<Name>Cristian Osorio</Name>
<Name>Jessica Arnold</Name>
<Name>Jessica Arnold</Name>

Isto funciona porque uma das implementações do eixo de Elements é como um método de extensão em IEnumerable<T> de XContainer. XElement deriva de XContainer, então você pode chamar o método de Extensions.Elements nos resultados de uma chamada para o método de XContainer.Elements .

Exemplo: Recuperar todos os elementos em uma determinada profundidade

Às vezes, você deseja recuperar todos os elementos em uma profundidade de elemento específica quando pode não haver ancestrais intermediários. Por exemplo, no documento a seguir, você pode querer recuperar todos os elementos ConfigParameter que são filhos do elemento Customer, mas não o ConfigParameter que é filho do elemento Root.

<Root>
  <ConfigParameter>RootConfigParameter</ConfigParameter>
  <Customer>
    <Name>Frank</Name>
    <Config>
      <ConfigParameter>FirstConfigParameter</ConfigParameter>
    </Config>
  </Customer>
  <Customer>
    <Name>Bob</Name>
    <!--This customer doesn't have a Config element-->
  </Customer>
  <Customer>
    <Name>Bill</Name>
    <Config>
      <ConfigParameter>SecondConfigParameter</ConfigParameter>
    </Config>
  </Customer>
</Root>

Para fazer isso, você pode usar o eixo de Extensions.Elements , como segue:

XElement root = XElement.Load("Irregular.xml");
IEnumerable<XElement> configParameters =
    root.Elements("Customer").Elements("Config").
    Elements("ConfigParameter");
foreach (XElement cp in configParameters)
    Console.WriteLine(cp);
Dim root As XElement = XElement.Load("Irregular.xml")
Dim configParameters As IEnumerable(Of XElement) = _
    root.<Customer>.<Config>.<ConfigParameter>
For Each cp As XElement In configParameters
    Console.WriteLine(cp)
Next

Esse exemplo gera a saída a seguir:

<ConfigParameter>FirstConfigParameter</ConfigParameter>
<ConfigParameter>SecondConfigParameter</ConfigParameter>

Exemplo: recuperar elementos para XML que estão em um namespace

O exemplo a seguir mostra a mesma técnica para XML que está em um namespace. Para obter mais informações, consulte Visão geral de namespaces.

Este exemplo usa o documento XML: Arquivo XML de exemplo: várias ordens de compra em um namespace.

XNamespace aw = "http://www.adventure-works.com";
XElement purchaseOrders = XElement.Load("PurchaseOrdersInNamespace.xml");
IEnumerable<XElement> names =
    from el in purchaseOrders
        .Elements(aw + "PurchaseOrder")
        .Elements(aw + "Address")
        .Elements(aw + "Name")
    select el;
foreach (XElement e in names)
    Console.WriteLine(e);
Imports <xmlns:aw="http://www.adventure-works.com">

Module Module1
    Sub Main()
        Dim purchaseOrders As XElement = XElement.Load("PurchaseOrdersInNamespace.xml")
        Dim names As IEnumerable(Of XElement) = _
            From el In purchaseOrders.<aw:PurchaseOrder>.<aw:Address>.<aw:Name> _
            Select el
        For Each e As XElement In names
            Console.WriteLine(e)
        Next
    End Sub
End Module

Esse exemplo gera a saída a seguir:

<aw:Name xmlns:aw="http://www.adventure-works.com">Ellen Adams</aw:Name>
<aw:Name xmlns:aw="http://www.adventure-works.com">Tai Yee</aw:Name>
<aw:Name xmlns:aw="http://www.adventure-works.com">Cristian Osorio</aw:Name>
<aw:Name xmlns:aw="http://www.adventure-works.com">Cristian Osorio</aw:Name>
<aw:Name xmlns:aw="http://www.adventure-works.com">Jessica Arnold</aw:Name>
<aw:Name xmlns:aw="http://www.adventure-works.com">Jessica Arnold</aw:Name>

Confira também