Привязки 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>