Gewusst wie: Binden an XML-Daten mithilfe von XMLDataProvider und XPath-Abfragen

In diesem Beispiel wird die Bindung an XML-Daten veranschaulicht, indem einem XmlDataProvider verwendet wird.

Mit einem XmlDataProvider können die untergeordneten Daten, die durch Datenbindung in Ihrer App abgerufen werden können, irgendeine Knotenstruktur im XML sein. Mit anderen Worten, ein XmlDataProvider bietet eine komfortable Möglichkeit, jede beliebige Knotenstruktur im XML als Bindungsquelle zu verwenden.

Beispiel

Im folgenden Beispiel werden die Daten direkt als XML-Dateninsel in den Resources-Abschnitt eingebettet. Eine XML-Dateninsel muss mit <x:XData>-Tags umschlossen sein und immer über einen einzelnen Stammknoten verfügen, der in diesem Beispiel Inventar ist.

Hinweis

Der Stammknoten der XML-Daten verfügt über ein xmlns-Attribut, das den XML-Namespace auf eine leere Zeichenfolge festlegt. Dies ist eine Anforderung für die Anwendung von XPath-Abfragen auf eine Dateninsel, die sich inline innerhalb der XAML-Seite befindet. In diesem Inlinefall erbt das XAML und damit die Dateninsel den System.Windows-Namespace. Aus diesem Grund müssen Sie den Namespace auf eine leere Zeichenfolge festlegen und verhindern so, dass XPath-Abfragen vom System.Windows-Namespace bestimmt werden, was zu fehlgeleiteten Abfragen führen würde.

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

Wie in diesem Beispiel veranschaulicht, müssen Sie zur Erstellung derselben Bindungsdeklaration in Attributsyntax die Sonderzeichen ordnungsgemäß mit einem Escapezeichen versehen. Weitere Informationen hierzu finden Sie unter XML-Zeichenentitäten und XAML.

Der ListBox zeigt das folgende Element, wenn dieses Beispiel Ausführen ist. Das sind die Title-Angaben aller Elemente unter Books, deren Stock-Wert entweder out (vergriffen) lautet oder einen Number-Wert von 3 bzw. größer gleich 8 aufweist. Beachten Sie, dass keine CD-Elemente zurückgegeben werden, da der auf XmlDataProvider eingestellte XPath-Wert anzeigt, dass nur die Bücher-Elemente freigelegt werden sollten (im Wesentlichen Einstellung eines Filters).

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

In diesem Beispiel werden die Buchtitel angezeigt, weil die XPath der TextBlock-Bindung im DataTemplate auf „Titel“ eingestellt ist. Um den Wert eines Attributs anzuzeigen, so wie ISBN, legen Sie den XPath- Wert auf „@ISBN“ fest.

Die XPath-Eigenschaften in WPF werden von der XmlNode.SelectNodes-Methode behandelt. Sie können die XPath-Abfragen ändern, um andere Ergebnisse abzurufen. Hier sind einige Beispiele für die XPath-Abfrage in der Abgrenzung ListBox vom vorherigen Beispiel:

  • XPath="Book[1]" gibt das erste Buchelement ("XML in Action") zurück. Beachten Sie, dass XPath-Indizes auf 1 und nicht auf 0 basieren.

  • XPath="Book[@*]" gibt alle Buchelemente mit beliebigen Attributen zurück.

  • XPath="Book[last()-1]" gibt das vorletzte Buchelement („Introducing Microsoft .NET“) zurück.

  • XPath="*[position()>3]" gibt außer den ersten 3 Buchelementen alle Buchelemente zurück.

Wenn Sie eine XPath-Abfrage ausführen, gibt sie ein XmlNode oder eine Liste von XmlNodes zurück. XmlNode ist ein Common Language Runtime-Objekt (CLR), das bedeutet, dass Sie die Path-Eigenschaft verwenden können, um an die Common Language Runtime-Eigenschaften (CLR) anzubinden. Betrachten Sie erneut das vorherige Beispiel. Wenn Sie den Rest des Beispiels unverändert lassen und die TextBlock-Bindung wie folgt ändern, werden die Namen der zurückgegebenen XmlNodes im ListBox angezeigt. In diesem Fall lautet der Name aller zurückgegebenen Knoten Book.

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

In bestimmten Anwendungen ist das Einbetten von XML als Dateninsel in die Quelle der XAML-Seite nicht geeignet, da zur Kompilierzeit der genaue Inhalt der Daten bekannt sein muss. Aus diesem Grund wird das Abrufen von Daten aus einer externen XML-Datei ebenso unterstützt, was im folgenden Beispiel veranschaulicht wird:

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

ML-Daten in einer XML-Remotedatei gespeichert sind, definieren Sie den Zugriff auf die Daten durch das Zuweisen einer geeigneten URL zum Source-Attribut, so wie folgt:

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

Siehe auch