Cómo: Enlazar a datos XML mediante XMLDataProvider y consultas XPath

En este ejemplo se muestra cómo enlazar a datos XML utilizando XmlDataProvider.

Con XmlDataProvider, los datos subyacentes a los que se puede tener acceso mediante el enlace de datos en la aplicación pueden ser cualquier árbol de nodos XML. En otras palabras, XmlDataProvider proporciona una manera cómoda de utilizar cualquier árbol de nodos XML como origen de enlace.

Ejemplo

En el ejemplo siguiente, los datos se incrustan directamente como una isla de datos de XML en la sección Resources. Una isla de datos de XML se debe incluir en etiquetas <x:XData> y tener siempre un nodo raíz único, que es Inventory en este ejemplo.

NotaNota

El nodo raíz de los datos XML tiene un atributo xmlns que establece el espacio de nombres de XML en una cadena vacía.Se trata de un requisito para aplicar las consultas XPath a una isla de datos insertada dentro de la página de XAML.En este caso de inserción, el marcado XAML y, en consecuencia, la isla de datos, hereda el espacio de nombres System.Windows.Por ello, es preciso establecer el espacio de nombres en blanco, a fin de evitar que el espacio de nombres System.Windows certifique las consultas Xpath, lo que las dirigiría incorrectamente.

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

  <StackPanel.Resources>
    <XmlDataProvider x:Key="InventoryData" XPath="Inventory/Books">
      <x:XData>
        <Inventory >
          <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>

Como se muestra en este ejemplo, para crear la misma declaración de enlace en la sintaxis de atributo es preciso crear caracteres de escape correctos para los caracteres especiales. Para obtener más información, vea Entidades de caracteres XML y XAML.

ListBox mostrará los elementos siguientes cuando se ejecute este ejemplo. Se trata de los elementos Title de todos los elementos que se encuentran bajo Books cuyo valor de Stock sea "out" o cuyo valor de Number sea 3 o mayor o igual que 8. Observe que no se devuelve ningún elemento CD porque el valor de XPath establecido en XmlDataProvider indica que únicamente se deben exponer los elementos Books (básicamente, estableciendo un filtro).

Ejemplo de XPath

En este ejemplo, se muestran los títulos de los libros porque la propiedad XPath del enlace del objeto TextBlock en DataTemplate se establece en "Title". Si desea mostrar el valor de un atributo, como el ISBN, deberá establecer ese valor de XPath en "@ISBN".

El método XmlNode.SelectNodes administra las propiedades XPath en WPF. Puede modificar las consultas del XPath para obtener resultados diferentes. A continuación se muestran algunos ejemplos para la consulta XPath en el control ListBox enlazado del ejemplo anterior:

  • XPath="Book[1]" devolverá el primer elemento de libro ("XML in Action"). Observe que los índices de XPath se basan en 1, no en 0.

  • XPath="Book[@*]" devolverá todos los elementos de libro con cualquier atributo.

  • XPath="Book[last()-1]" devolverá los elementos de libro del segundo a último libro ("Introducing Microsoft .NET").

  • XPath="*[position()>3]" devolverá todos los elementos de libro salvo los 3 primeros.

Al ejecutar una consulta XPath, devuelve un objeto XmlNode o una lista de XmlNodes. XmlNode es un objeto common language runtime (CLR), lo que significa que puede utilizar la propiedad Path para enlazar a las propiedades de common language runtime (CLR). Estudie de nuevo el ejemplo anterior. Si el resto del ejemplo permanece igual y cambia el enlace de TextBlock por lo siguiente, verá los nombres de los objetos XmlNodes devueltos en el control ListBox. En este caso, el nombre de todos los nodos devueltos es "Book".

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

En algunas aplicaciones, puede que no sea oportuno incrustar XML como una isla de datos dentro del código fuente de la página XAML, ya que es imprescindible conocer el contenido exacto de los datos en tiempo de compilación. Por consiguiente, también se admite la obtención de los datos de un archivo XML externo, como en el ejemplo siguiente:

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

Si los datos XML residen en un archivo XML remoto, el acceso a ellos se define asignando una URL adecuada al atributo Source, como sigue:

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

Vea también

Tareas

Cómo: Enlazar a los resultados de una consulta LINQ for XML, XDocument o XElement

Cómo: Usar el patrón principal-detalle con datos XML jerárquicos

Referencia

ObjectDataProvider

Conceptos

Información general sobre orígenes de enlaces

Información general sobre el enlace de datos

Otros recursos

Temas "Cómo..." sobre enlace de datos