【问题标题】:Query an XmlDocument without getting a 'Namespace prefix is not defined' problem查询 XmlDocument 时未获得“未定义命名空间前缀”问题
【发布时间】:2010-03-24 17:17:47
【问题描述】:

我有一个定义和引用一些命名空间的 XML 文档。我将它加载到一个 XmlDocument 对象中,据我所知,我创建了一个 XmlNamespaceManager 对象来查询 Xpath。问题是我收到了未定义命名空间“my”的 XPath 异常。如何让命名空间管理器看到我引用的命名空间已经定义。或者更确切地说,我如何将命名空间定义从文档中获取到命名空间管理器。

此外,让我感到奇怪的是,您必须首先为您从文档命名表创建的文档提供名称空间管理器。即使您需要对手动命名空间进行硬编码,为什么不能将它们直接添加到文档中。为什么每次查询都必须传递这个命名空间管理器? XmlDocument 不能只知道什么?

代码:

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(programFiles + @"Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES\HfscBookingWorkflow\template.xml");
XmlNamespaceManager ns = new XmlNamespaceManager(xmlDoc.NameTable);

XmlNode referenceNode = xmlDoc.SelectSingleNode("/my:myFields/my:ReferenceNumber", ns);
referenceNode.InnerXml = this.bookingData.ReferenceNumber;

XmlNode titleNode = xmlDoc.SelectSingleNode("/my:myFields/my:Title", ns);
titleNode.InnerXml = this.bookingData.FamilyName;

XML:

  <?xml version="1.0" encoding="UTF-8" ?> 
  <?mso-infoPathSolution name="urn:schemas-microsoft-com:office:infopath:Inspection:-myXSD-2010-01-15T18-21-55" solutionVersion="1.0.0.104" productVersion="12.0.0" PIVersion="1.0.0.0" ?> 
  <?mso-application progid="InfoPath.Document" versionProgid="InfoPath.Document.2"?> 
  <my:myFields xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2010-01-15T18:21:55" xmlns:xd="http://schemas.microsoft.com/office/infopath/2003">
  <my:DateRequested xsi:nil="true" /> 
  <my:DateVisited xsi:nil="true" /> 
  <my:ReferenceNumber /> 
  <my:FireCall>false</my:FireCall> 

更新:

ns.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
ns.AddNamespace("xhtml", "http://www.w3.org/1999/xhtml");
ns.AddNamespace("xd", "http://schemas.microsoft.com/office/infopath/2003");
ns.AddNamespace("my", "http://schemas.microsoft.com/office/infopath/2003/myXSD/2010-01-15T18:21:55");

这可以完成工作,但这意味着我必须对这个特定的 xml 架构进行硬编码。此架构表示一个信息路径表单模板。特别是我的命名空间 url 对于每个表单模板都是不同的,所以我真的不想硬编码这个。如果能找到一种干净的方式来从 xml 中获取这个命名空间而不使用 RegEx,那就太好了。

我希望 XmlNamespaceManager 能够从 NameTable 中提取命名空间定义。我的意思是它们在 Xml 中,但我仍然必须定义它们。

【问题讨论】:

    标签: c# .net xml


    【解决方案1】:
    ns.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
    ns.AddNamespace("xhtml", "http://www.w3.org/1999/xhtml");
    ns.AddNamespace("xd", "http://schemas.microsoft.com/office/infopath/2003");
    ns.AddNamespace("my", "http://schemas.microsoft.com/office/infopath/2003/myXSD/2010-01-15T18:21:55");
    

    这可以完成这项工作,但这意味着我必须对这个特定的 xml 模式进行硬编码。此架构表示一个信息路径表单模板。特别是我的命名空间 url 对于每个表单模板都是不同的,所以我真的不想硬编码这个。如果能找到一种干净的方式从 xml 中获取这个命名空间而不使用 Regex,那就太好了。

    我希望 XmlNamespaceManager 能够从 NameTable 中提取命名空间定义。我的意思是它们在 Xml 中,但我仍然必须定义它们。

    【讨论】:

      【解决方案2】:

      这里是“XmlDocument 不能知道什么?”的答案。问题。

      NameTable 只是对存储名称的优化。它实际上与命名空间无关。

      即使 XmlNamespaceManager 可以从 XML 文档中推断出所有命名空间和前缀,但由于 XML 命名空间的性质,这在一般情况下也无济于事,例如在这种情况下,XmlNamespaceManager 会映射“我的”前缀:

      <root>
          <foo xmlns:my="blah"/>
          <foo xmlns:my="balh-blah-blah"/>
      </root>
      

      【讨论】:

        【解决方案3】:

        您是否在命名空间管理器中定义了“我的”?

        ns.AddNamespace("my", "http://schemas.microsoft.com/office/infopath/2003/myXSD/2010-01-15T18:21:55");
        

        或者更好 - 选择不太可能发生冲突的东西。不过,它没有从名称表中获取它似乎很奇怪。

        【讨论】:

        • NameTable 只是对存储名称的优化。它实际上与命名空间无关。即使 XmlNamespaceManager 可以从 XML 文档中推断出所有命名空间和前缀,但由于 XML 命名空间的性质,这在一般情况下也无济于事,例如在这种情况下,XmlNamespaceManager 会映射“my”前缀:
        • @Oleg - 我认为你应该保留你的答案(而不是删除它) - 这是对“为什么?”的一个很好的答案。
        • 我没有手动添加它,因为命名空间的 url 可能会改变。我尝试使用 XPath 访问的字段不会。
        【解决方案4】:

        对于使用 InfoPath 2007 的我来说,这解决了问题

        static public XmlNamespaceManager GetNameSpaceManager(this XmlDocument document)
        {
            XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(document.NameTable);
        
            xmlNamespaceManager.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
            xmlNamespaceManager.AddNamespace("dfs", "http://schemas.microsoft.com/office/infopath/2003/dataFormSolution");
            xmlNamespaceManager.AddNamespace("d", "http://schemas.microsoft.com/office/infopath/2003/ado/dataFields");
            xmlNamespaceManager.AddNamespace("my", "http://schemas.microsoft.com/office/infopath/2003/myXSD/2012-03-29T06:28:28");
            xmlNamespaceManager.AddNamespace("xd", "http://schemas.microsoft.com/office/infopath/2003");
        
            return xmlNamespaceManager;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-07-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-06-09
          • 2017-09-28
          • 1970-01-01
          相关资源
          最近更新 更多