代码之家  ›  专栏  ›  技术社区  ›  Andy Dent

xmldataprovider和xpath绑定不允许xml数据的默认命名空间?

  •  1
  • Andy Dent  · 技术社区  · 14 年前

    我正在努力研究如何使用 违约 具有xmldataprovider和xpath绑定的命名空间。

    有一个 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 回复  |  直到 14 年前
        1
  •  2
  •   Andy Dent    14 年前

    我没有意识到,我不需要向客户机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>