1

我正在努力研究如何将默认命名空间与 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);
    }
}
4

1 回答 1

2

我没有意识到我不需要为客户端 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>
于 2010-05-10T22:57:56.730 回答