Condividi tramite


Procedura: Eseguire il binding a dati XML usando un XMLDataProvider e query XPath

Questo esempio mostra come associare i dati XML usando un XmlDataProvider.

Con un XmlDataProvider, i dati sottostanti a cui è possibile accedere tramite il data binding nell'applicazione possono essere qualsiasi albero di nodi XML. In altre parole, un XmlDataProvider offre un modo pratico per usare qualsiasi albero di nodi XML come origine di associazione.

Esempio

Nell'esempio seguente i dati vengono incorporati direttamente come un'isola di dati xml all'interno della sezione Resources. È necessario eseguire il wrapping di un'isola di dati XML in tag <x:XData> e avere sempre un singolo nodo radice, che è Inventario in questo esempio.

Nota

Il nodo radice dei dati XML ha un attributo xmlns che imposta lo spazio dei nomi XML su una stringa vuota. Si tratta di un requisito per l'applicazione di query XPath a un'isola di dati incorporata nella pagina XAML. In questo caso inline, XAML e di conseguenza l'isola dei dati ereditano lo spazio dei nomi System.Windows. Per questo motivo, è necessario impostare lo spazio dei nomi vuoto per evitare che le query XPath vengano erroneamente qualificate dallo spazio dei nomi System.Windows, cosa che potrebbe sviare le query.

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

Come illustrato in questo esempio, per creare la stessa dichiarazione di associazione nella sintassi dell'attributo, è necessario eseguire correttamente l'escape dei caratteri speciali. Per ulteriori informazioni, vedere le entità carattere XML e XAML.

Il ListBox mostrerà gli elementi seguenti quando viene eseguito questo esempio. Questi sono i Titledi tutti gli elementi in Books con un valore stock pari a "out" o un valore Number pari a 3 o maggiore o uguale a 8. Si noti che non vengono restituiti elementi di CD perché il valore XPath impostato su XmlDataProvider indica che devono essere esposti solo gli elementi Libri (essenzialmente impostando un filtro).

Screenshot dell'esempio XPath che mostra i titoli dei quattro libri.

In questo esempio i titoli dei libri vengono visualizzati perché il XPath dell'associazione TextBlock nel DataTemplate è impostato su "Titolo". Se si desidera visualizzare il valore di un attributo, ad esempio ISBN, è necessario impostare tale valore XPath su "@ISBN".

Le proprietà XPath in WPF vengono gestite dal metodo XmlNode.SelectNodes. È possibile modificare le query XPath per ottenere risultati diversi. Di seguito sono riportati alcuni esempi per la query XPath sul vincolo ListBox dall'esempio precedente.

  • XPath="Book[1]" restituirà il primo elemento libro ("XML in Action"). Si noti che gli indici XPath sono basati su 1, non su 0.

  • XPath="Book[@*]" restituirà tutti gli elementi del libro con qualsiasi attributo.

  • XPath="Book[last()-1]" restituirà il penultimo elemento del libro ("Introduzione a Microsoft .NET").

  • XPath="*[position()>3]" restituirà tutti gli elementi del libro ad eccezione dei primi 3.

Quando si esegue una query XPath, restituisce un XmlNode o un elenco di XmlNodes. XmlNode è un oggetto CLR (Common Language Runtime), il che significa che è possibile usare la proprietà Path per eseguire l'associazione alle proprietà CLR (Common Language Runtime). Si consideri di nuovo l'esempio precedente. Se il resto dell'esempio rimane invariato e si modifica il collegamento di TextBlock nel modo seguente, verranno visualizzati i nomi dei nodi XML restituiti in ListBox. In questo caso, il nome di tutti i nodi restituiti è "Book".

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

In alcune applicazioni, l'incorporamento del codice XML come isola di dati all'interno dell'origine della pagina XAML può risultare scomodo perché il contenuto esatto dei dati deve essere noto in fase di compilazione. Pertanto, è supportato anche ottenere i dati da un file XML esterno, come nell'esempio seguente:

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

Se i dati XML si trovano in un file XML remoto, è necessario definire l'accesso ai dati assegnando un URL appropriato all'attributo Source come indicato di seguito:

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

Vedere anche