方法: XMLDataProvider と XPath クエリを使用して XML データにバインドする

この例では、XmlDataProvider を使用して XML データにバインドする方法を示します。

XmlDataProvider では、アプリケーションでデータ バインディングを介してアクセスできる基になるデータは、XML ノードの任意のツリーです。 つまり、XmlDataProvider では、XML ノードの任意のツリーをバインディング ソースとして使用するための便利な手段が提供されます。

次の例では、データは XML の "データ アイランド" として Resources セクション内に直接埋め込まれます。 XML データ アイランドは、<x:XData> タグ内にラップされていることと、常にルート ノードを 1 つだけ (この例では Inventory) 持つことが必要です。

注意

XML データのルート ノードには、XML 名前空間を空の文字列に設定する xmlns 属性があります。 これは、XAML ページ内にインラインで配置されるデータ アイランドに XPath クエリを適用する場合に必須です。 このインラインの場合は、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 Character Entities and XAML」(XML 文字エンティティと XAML) をご覧ください。

この例を実行すると、次の項目が ListBox に表示されます。 これらは、Books の下のすべての要素のうち、Stock の値が "out" か、Number の値が 3 に等しいか 8 以上のものの Title です。 CD の項目が 1 つも返されないのは、XmlDataProvider に設定された XPath の値が、Books 要素のみを公開するように指定されている (本質的にはフィルターが設定されている) からであることに注意してください。

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

この例で書籍のタイトルが表示されるのは、DataTemplate 内の TextBlock バインディングの XPath が "Title" に設定されているためです。 属性 (ISBN など) の値を表示するには、XPath の値を "@ISBN" に設定します。

WPF 内の XPath プロパティは、XmlNode.SelectNodes メソッドによって処理されます。 別の結果を得るために、XPath クエリを変更できます。 前の例での、バインドされた ListBox に対する XPath クエリの例を次に示します。

  • XPath="Book[1]" は、最初の書籍要素 ("XML in Action") を返します。 XPath のインデックスが 0 ではなく 1 から開始することにご注意ください。

  • XPath="Book[@*]" は、任意の属性を持つすべての書籍要素を返します。

  • XPath="Book[last()-1]" は、最後から 2 番目の書籍要素 ("Introducing Microsoft .NET") を返します。

  • XPath="*[position()>3]" は、最初の 3 つを除くすべての書籍要素を返します。

XPath クエリを実行すると、1 つの XmlNode または XmlNode のリストが返されます。 XmlNode は共通言語ランタイム (CLR) オブジェクトです。つまり、Path プロパティを使用して共通言語ランタイム (CLR) のプロパティにバインドできます。 前の例をもう一度考えてみます。 例の残りの部分はそのままで TextBlock バインディングを次のように変更すると、返された XmlNode の名前が ListBox に表示されます。 この場合、返されたノードの名前はすべて "Book" です。

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

XAML ページのソースに XML をデータ アイランドとして埋め込む方法では、コンパイル時に正確なデータ コンテンツが必要となるので、アプリケーションによっては不都合が生じます。 したがって、次の例のように、外部 XML ファイルからのデータの取得もサポートされています。

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

XML データがリモートの XML ファイル内に存在する場合は、次のように、適切な URL を Source 属性に割り当てることによってデータへのアクセスを定義します。

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

関連項目