查询XmlDocument而不会得到“未定义名称空间前缀”问题

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

此外,让我感到奇怪的是,您必须首先为文档名称表创建的文档提供命名空间管理器。 即使您需要对手动命名空间进行硬编码,为什么不能将它们直接添加到文档中。 为什么总是必须在每个查询中传递此命名空间管理器? 什么不能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:

         false 

更新:

 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架构。 此架构表示infopath表单模板。 特别是我的命名空间url对于每个表单模板都是不同的,所以我真的不想硬编码。 很高兴找到一种从xml获取此命名空间的简洁方法,而无需使用RegEx。

我希望XmlNamespaceManager只是从NameTable中获取命名空间定义。 我的意思是他们在Xml中,但我仍然需要定义它们。

 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架构。 此架构表示infopath表单模板。 特别是我的命名空间url对于每个表单模板都是不同的,所以我真的不想硬编码。 很高兴找到一种干净的方法从xml获取这个命名空间而不诉诸Regex。

我希望XmlNamespaceManager只是从NameTable中获取命名空间定义。 我的意思是他们在Xml中,但我仍然需要定义它们。

以下是“什么不能XmlDocument只知道?”的答案。 题。

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

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

     

你在名称空间管理器中定义了“我的”吗?

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

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

对于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; }