Como associar dados XML usando um XMLDataProvider e consultas XPath

Este exemplo mostra como vincular a dados XML usando um XmlDataProviderarquivo .

Com um XmlDataProvider, os dados subjacentes que podem ser acessados por meio da vinculaçã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 vinculação.

Exemplo

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

Observação

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 System.Windows namespace. Devido a isso, você precisa definir o namespace em branco para evitar que as consultas XPath sejam qualificadas pelo namespace, o System.Windows que direcionaria 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 do atributo, você precisa fazer o escape de caracteres especiais corretamente. Para obter mais informações, consulte Entidades de caractere XML e XAML.

O ListBox mostrará os seguintes itens quando este exemplo for executado. Esses são os Títulos de todos os elementos em Livros com um valor de Estoque de "sem" ou um valor de Número de 3 ou maior ou igual a 8. Observe que nenhum item de CD é retornado porque o XPathXmlDataProvider valor definido no indica que somente os elementos Books devem ser expostos (essencialmente definindo um filtro).

Screenshot of the XPath example showing the title of four books.

Neste exemplo, os títulos dos livros são exibidos porque o XPath da TextBlock vinculação no DataTemplate está definido como "Título". Se você quiser exibir o valor de um atributo, como o ISBN, defina esse XPath valor como "@ISBN".

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

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

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

  • O XPath="Book[last()-1]" retornará do segundo ao último elemento de livro ("Introducing Microsoft .NET").

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

Quando você executa uma consulta XPath, ele retorna uma ou uma XmlNode lista de XmlNodes. XmlNode é um objeto CLR (Common Language Runtime), o que significa que você pode usar a Path propriedade para vincular às propriedades CLR (Common Language Runtime). Considere o exemplo anterior novamente. Se o restante do exemplo permanecer o mesmo e você alterar a TextBlock associação para o seguinte, você verá os nomes dos XmlNodes retornados no ListBox. Nesse caso, o nome de todos os nós retornados é "Livro".

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

Em alguns aplicativos, incorporar o 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, a obtenção dos dados de um arquivo XML externo também é suportada, 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 Source atributo da seguinte maneira:

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

Confira também