Привязки XmlDataProvider и XPath не разрешают пространство имен по умолчанию для данных XML? - PullRequest
1 голос
/ 10 мая 2010

Я пытаюсь понять, как использовать стандартные пространства имен с привязками XmlDataProvider и XPath.

Существует безобразный ответ с использованием локального имени <Binding XPath="*[local-name()='Name']" />, но он неприемлем для клиента, который хочет, чтобы этот XAML был в высокой степени поддерживаемым.

Откат заключается в том, чтобы заставить их использовать пространства имен, отличные от заданных по умолчанию, в XML-отчете, но это нежелательное решение.

Файл отчета XML выглядит следующим образом. Это будет работать только в том случае, если я удалю xmlns="http://www.acme.com/xml/schemas/report, поэтому пространство имен по умолчанию отсутствует.

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type='text/xsl' href='PreviewReportImages.xsl'?>
<Report xsl:schemaLocation="http://www.acme.com/xml/schemas/report BlahReport.xsd" xmlns:xsl="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.acme.com/xml/schemas/report">
  <Service>Muncher</Service>
  <Analysis>
    <Date>27 Apr 2010</Date>
    <Time>0:09</Time>
    <Authoriser>Service Centre Manager</Authoriser>

Что я представляю в окне с XAML:

<Window x:Class="AcmeTest.ReportPreview"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     Title="ReportPreview" Height="300" Width="300" >
    <Window.Resources>
        <XmlDataProvider x:Key="Data"/>
    </Window.Resources>
    <StackPanel Orientation="Vertical" DataContext="{Binding Source={StaticResource Data}, XPath=Report}">
        <TextBlock Text="{Binding XPath=Service}"/>
    </StackPanel>
</Window>

с выделенным кодом, используемым для загрузки XmlDocument в XmlDataProvider (кажется, единственный способ загрузки из файла или объекта во время выполнения).

public partial class ReportPreview : Window
{
    private void InitXmlProvider(XmlDocument doc)
    {
        XmlDataProvider xd = (XmlDataProvider)Resources["Data"];
        xd.Document = doc;
    }

    public ReportPreview(XmlDocument doc)
    {
        InitializeComponent();
        InitXmlProvider(doc);
    }

    public ReportPreview(String reportPath)
    {
        InitializeComponent();

        var doc = new XmlDocument();
        doc.Load(reportPath);
        InitXmlProvider(doc);
    }
}

1 Ответ

2 голосов
/ 11 мая 2010

Я не осознавал, что мне не нужно добавлять префикс к XML-данным клиента, просто используйте префикс в моих выражениях XPath, который отображается на тот же URI, что и пространство имен по умолчанию (очевидно, когда я спал на нем! ).

Итак, исправление было в том, чтобы добавить отображение пространства имен, как показано здесь, обратите внимание на использование префикса r: для элементов.

<Window x:Class="AcmeTest.ReportPreview"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     Title="ReportPreview" Height="300" Width="300" >
    <Window.Resources>
        <XmlDataProvider x:Key="Data">
            <XmlDataProvider.XmlNamespaceManager>
                <XmlNamespaceMappingCollection>
                    <XmlNamespaceMapping 
                       Uri="http://www.acme.com/xml/schemas/report" 
                       Prefix="r" />
                </XmlNamespaceMappingCollection>
            </XmlDataProvider.XmlNamespaceManager>
        </XmlDataProvider>
    </Window.Resources>
    <StackPanel Orientation="Vertical" DataContext="{Binding Source={StaticResource Data}, XPath=Report}">
        <TextBlock Text="{Binding XPath=r:Service}"/>
        <TextBlock Text=" "/>
        <TextBlock Text="{Binding XPath=r:Name/r:Last}"/>
    </StackPanel>
</Window>
...