2010-05-10 55 views
1

我正在努力研究如何使用默认命名空间与XmlDataProvider和XPath绑定。XmlDataProvider和XPath绑定不允许XML数据的默认名称空间?

有一个ugly answer使用本地名称<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

没有测试,您应该能够使用XmlNamespaceManager作为绑定的一部分;那么你将不得不使用一个前缀,但它应该工作。 – p00ya 2010-05-10 04:25:50

+0

是的,强制前缀是我的后备,但这意味着很多XSLT外部脚本需要更改,而且默认名称空间很满意。 – 2010-05-10 05:29:21

+0

doh - 看到我的答案在下面! – 2010-05-10 23:02:09

回答

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>