Привязки XmlDataProvider и XPath не разрешают пространство имен по умолчанию для данных XML?

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

Там уродливый ответ, используя local-name <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 ответ

Решение

Я не осознавал, что мне не нужно добавлять префикс к 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>
Другие вопросы по тегам