如何:使用 XMLDataProvider 和 XPath 查询绑定到 XML 数据

此示例演示如何使用XmlDataProvider绑定到XML数据。

使用XmlDataProvider,在应用程序中通过数据绑定访问的底层数据可以是任意的 XML 节点树。 换句话说,XmlDataProvider 提供了一种将任何 XML 节点树用作绑定源的便捷方法。

示例:

在以下示例中,数据作为 XML 数据岛 直接嵌入在 Resources 节内。 XML 数据岛必须用 <x:XData> 标签包裹,并且总是只有一个根节点,在本示例中为 Inventory

注释

XML 数据的根节点具有 xmlns 属性,该属性将 XML 命名空间设置为空字符串。 这是将 XPath 查询应用到 XAML 页面中内联的数据岛的要求。 在此内联情况下,XAML 及其相关的数据岛继承了 System.Windows 命名空间。 因此,需要将命名空间设置为空白,以使 XPath 查询不受命名空间限定 System.Windows ,这会误导查询。

<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>

如本示例所示,若要在属性语法中创建相同的绑定声明,必须正确转义特殊字符。 有关详细信息,请参阅 XML 字符实体和 XAML

运行此示例时,将显示 ListBox 以下项。 这些是书籍下所有元素的标题,其库存值为“out”或编号值为3或大于等于8。 请注意,没有返回 CD 项,因为 XPath 设置的值 XmlDataProvider 指示只应公开 Books 元素(实质上设置筛选器)。

XPath 示例的屏幕截图,其中显示了四本书的标题。

在此示例中,书籍标题之所以会显示,是因为DataTemplate中的TextBlock绑定的XPath设置为“Title”。 如果要显示属性的值(如 ISBN),请将该值XPath设置为“”。@ISBN

WPF 中的 XPath 属性由 XmlNode.SelectNodes 方法处理。 可以修改 XPath 查询以获取不同的结果。 下面是关于上一示例中绑定XPath的查询的一些ListBox示例:

  • XPath="Book[1]" 将返回第一个图书元素(“XML in Action”)。 请注意, XPath 索引基于 1 而不是 0。

  • XPath="Book[@*]" 将返回具有任何属性的所有图书元素。

  • XPath="Book[last()-1]" 将返回第二个到最后一个 book 元素(“Microsoft .NET 简介”)。

  • XPath="*[position()>3]" 将返回除了前三个之外的所有书籍元素。

运行 XPath 查询时,它将返回 XmlNode XmlNodes 或列表。 XmlNode 是公共语言运行时 (CLR) 对象,这意味着可以使用该 Path 属性绑定到公共语言运行时 (CLR) 属性。 再次考虑前面的示例。 如果示例的其余部分保持不变,而您将TextBlock的绑定更改为以下内容,那么您将在ListBox中看到返回的 XmlNodes 的名称。 在这种情况下,所有返回的节点的名称为“Book”。

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

在某些应用程序中,将 XML 嵌入为 XAML 页面源中的数据岛可能不方便,因为必须在编译时知道数据的确切内容。 因此,还支持从外部 XML 文件获取数据,如以下示例所示:

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

如果 XML 数据驻留在远程 XML 文件中,则通过向属性分配适当的 URL Source 来定义对数据的访问,如下所示:

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

另请参阅