Compartilhar via


Como associar a dados XML usando consultas XMLDataProvider e XPath

Este exemplo mostra como associar dados XML usando um XmlDataProvider.

Com um XmlDataProvider, os dados subjacentes que podem ser acessados por meio da associação de dados em seu aplicativo podem ser qualquer árvore de nós XML. Em outras palavras, um XmlDataProvider fornece uma maneira conveniente de usar qualquer árvore de nós XML como uma fonte de associação.

Exemplo

No exemplo a seguir, os dados são inseridos diretamente como uma ilha de dados XML na seção Resources. Uma ilha de dados XML deve ser encapsulada em tags <x:XData> e sempre ter um único nó raiz, que é o inventário neste exemplo.

Nota

O nó raiz dos dados XML tem um atributo xmlns que define o namespace XML como uma cadeia de caracteres vazia. Esse é um requisito para aplicar consultas XPath a uma ilha de dados embutida na página XAML. Nesse caso embutido, o XAML e, portanto, a ilha de dados, herda o namespace System.Windows. Por isso, você precisa definir o namespace em branco para impedir que as consultas XPath sejam qualificadas pelo namespace System.Windows, o que redirecionaria incorretamente as consultas.

<StackPanel
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Background="Cornsilk">

  <StackPanel.Resources>
    <XmlDataProvider x:Key="InventoryData" XPath="Inventory/Books">
      <x:XData>
        <Inventory xmlns="">
          <Books>
            <Book ISBN="0-7356-0562-9" Stock="in" Number="9">
              <Title>XML in Action</Title>
              <Summary>XML Web Technology</Summary>
            </Book>
            <Book ISBN="0-7356-1370-2" Stock="in" Number="8">
              <Title>Programming Microsoft Windows With C#</Title>
              <Summary>C# Programming using the .NET Framework</Summary>
            </Book>
            <Book ISBN="0-7356-1288-9" Stock="out" Number="7">
              <Title>Inside C#</Title>
              <Summary>C# Language Programming</Summary>
            </Book>
            <Book ISBN="0-7356-1377-X" Stock="in" Number="5">
              <Title>Introducing Microsoft .NET</Title>
              <Summary>Overview of .NET Technology</Summary>
            </Book>
            <Book ISBN="0-7356-1448-2" Stock="out" Number="4">
              <Title>Microsoft C# Language Specifications</Title>
              <Summary>The C# language definition</Summary>
            </Book>
          </Books>
          <CDs>
            <CD Stock="in" Number="3">
              <Title>Classical Collection</Title>
              <Summary>Classical Music</Summary>
            </CD>
            <CD Stock="out" Number="9">
              <Title>Jazz Collection</Title>
              <Summary>Jazz Music</Summary>
            </CD>
          </CDs>
        </Inventory>
      </x:XData>
    </XmlDataProvider>
  </StackPanel.Resources>

  <TextBlock FontSize="18" FontWeight="Bold" Margin="10"
    HorizontalAlignment="Center">XML Data Source Sample</TextBlock>
  <ListBox
    Width="400" Height="300" Background="Honeydew">
    <ListBox.ItemsSource>
      <Binding Source="{StaticResource InventoryData}"
               XPath="*[@Stock='out'] | *[@Number>=8 or @Number=3]"/>
    </ListBox.ItemsSource>

    <!--Alternatively, you can do the following. -->
    <!--<ListBox Width="400" Height="300" Background="Honeydew"
      ItemsSource="{Binding Source={StaticResource InventoryData},
      XPath=*[@Stock\=\'out\'] | *[@Number>\=8 or @Number\=3]}">-->

    <ListBox.ItemTemplate>
      <DataTemplate>
        <TextBlock FontSize="12" Foreground="Red">
          <TextBlock.Text>
            <Binding XPath="Title"/>
          </TextBlock.Text>
        </TextBlock>
      </DataTemplate>
    </ListBox.ItemTemplate>
  </ListBox>
</StackPanel>

Conforme mostrado neste exemplo, para criar a mesma declaração de associação na sintaxe de atributo, você deve escapar corretamente dos caracteres especiais. Para mais informações, consulte Entidades de Caractere XML e XAML.

O ListBox mostrará os itens a seguir quando este exemplo for executado. Estas são os títulosde todos os elementos em Livros com um valor de Estoque de "esgotado" ou um valor de Número igual a 3 ou maior ou igual a 8. Observe que nenhum item CD é retornado porque o valor XPath definido em XmlDataProvider indica que apenas os elementos Books devem ser expostos (essencialmente, criando um filtro).

Captura de tela do exemplo XPath mostrando o título de quatro livros.

Neste exemplo, os títulos do livro são exibidos porque o XPath da associação TextBlock no DataTemplate é definido como "Title". Se você quiser exibir o valor de um atributo, como o ISBN, definirá esse valor XPath como "@ISBN".

As propriedades XPath no WPF são tratadas pelo método XmlNode.SelectNodes. Você pode modificar as consultas XPath para obter resultados diferentes. Aqui estão alguns exemplos para a consulta XPath no vinculado ListBox do exemplo anterior:

  • XPath="Book[1]" retornará o primeiro elemento de livro ("XML in Action"). Observe que índices de XPath são baseados em 1, não em 0.

  • XPath="Book[@*]" retornará todos os elementos de livro com quaisquer atributos.

  • XPath="Book[last()-1]" retornará o penúltimo elemento do "livro" ("Apresentando o Microsoft .NET").

  • XPath="*[position()>3]" retornará todos os elementos do livro, exceto os três primeiros.

Quando você executa uma consulta XPath, ela retorna um XmlNode ou uma lista de XmlNodes. XmlNode é um objeto CLR (Common Language Runtime), o que significa que você pode usar a propriedade Path para associar às propriedades CLR (Common Language Runtime). Considere o exemplo anterior novamente. Se o restante do exemplo permanecer igual e você alterar o vínculo TextBlock para o seguinte, verá os nomes dos XmlNodes retornados em ListBox. Nesse caso, o nome de todos os nós retornados é "Book".

<TextBlock FontSize="12" Foreground="Red">
  <TextBlock.Text>
    <Binding Path="Name"/>
  </TextBlock.Text>
</TextBlock>

Em alguns aplicativos, a inserção do XML como uma ilha de dados na origem da página XAML pode ser inconveniente porque o conteúdo exato dos dados deve ser conhecido em tempo de compilação. Portanto, também há suporte para a obtenção dos dados de um arquivo XML externo, como no exemplo a seguir:

<XmlDataProvider x:Key="BookData" Source="data\bookdata.xml" XPath="Books"/>

Se os dados XML residirem em um arquivo XML remoto, você definirá o acesso aos dados atribuindo uma URL apropriada ao atributo Source da seguinte maneira:

<XmlDataProvider x:Key="BookData" Source="http://MyUrl" XPath="Books"/>  

Consulte também