在.Net Framework中处理Xml名称空间(Namespace)

在.Net Framework中,在System.Xml类库中,查找一个Xml节点的最简单方法是通过XmlNode.SelectSingleNode和XmlNode.SelectNodes方法,解析XPath字符串。不过如果Xml文本中包含名称空间(Namespace),事情就有一点点复杂了。

注意,Xml名称空间属于亦正亦邪的技术,参见Xml名称空间(Namespace)的简介和优劣分析

含有名称空间(Namespace)前缀的Xml

比如以下的例子,xdoc.SelectSingleNode什么也找不到,只能得到Nothing。

Dim xml As String = "<test:store xmlns:test='testnamespace'><test:book/></test:store>"
Dim xdoc As XmlDocument = New XmlDocument
xdoc.LoadXml(xml)
Dim xnd As XmlNode = xdoc.SelectSingleNode("//book")

正确的代码如下。

Dim xml As String = "<test:store xmlns:test='testnamespace'><test:book/></test:store>"
Dim xdoc As XmlDocument = New XmlDocument
xdoc.LoadXml(xml)
Dim nsmgr As XmlNamespaceManager = New XmlNamespaceManager(xdoc.NameTable)
nsmgr.AddNamespace("test", "testnamespace")
Dim xnd As XmlNode = xdoc.SelectSingleNode("//test:book", nsmgr)

对于含有前缀的XPath,必须使用XmlNamespaceManager参数,否则SelectSingleNode会出现一个Exception。

含有缺省名称空间(Namespace)的Xml

如果Xml名称空间是缺省的,也一样要使用XmlNamespaceManager。微软目前不支持XPath的缺省名称空间,并号称这是Xml名称空间的规范所规定的。不过其他很多Xml分析器例如XmlSpy都支持顶层节点的缺省名称空间。

比如下面的例子,xdoc.SelectSingleNode也是什么也找不到,只能得到Nothing。

Dim xml As String = "<store xmlns='testnamespace'><book/></store>"
Dim xdoc As XmlDocument = New XmlDocument
xdoc.LoadXml(xml)
Dim xnd As XmlNode = xdoc.SelectSingleNode("//book")

如果要找到这个book节点,需要用下面的代码。

Dim xml As String = "<store xmlns='testnamespace'><book/></store>"
Dim xdoc As XmlDocument = New XmlDocument
xdoc.LoadXml(xml)
Dim nsmgr As XmlNamespaceManager = New XmlNamespaceManager(xdoc.NameTable)
nsmgr.AddNamespace("test", "testnamespace")
Dim xnd As XmlNode = xdoc.SelectSingleNode("//test:book", nsmgr)

这样的代码挺奇怪的,明明XPath中可以不需要前缀,现在却非要加上前缀,但是这个就是微软嘛,有什么办法,人家在.Net Framework类库参考手册 - XmlNode.SelectSingleNode Method中,专门说明,非要这么写代码才行。

忽略Xml名称空间(Namespace)的代码

也可以让XmlDocument在载入的时候忽略Xml名称空间(Namespace)。示例代码如下。

Dim xml As String = "<store xmlns='testnamespace'><book/></store>"
Dim srd As StringReader = New StringReader(xml)
Dim xrd As XmlTextReader = New XmlTextReader(srd)
xrd.Namespaces = False
Dim xdoc As XmlDocument = New XmlDocument
xdoc.Load(xrd)
Dim xnd As XmlNode = xdoc.SelectSingleNode("//book")

这个示例的主要原理是,在XmlTextReader中有一个Namespaces属性,设置为False以后,就不会将xmlns当作名称空间(Namespace)处理,而把它当作一个一般的属性。这种方法对于只有一个缺省名称空间的Xml文本,可以起到简化XPath的作用,不过,如果Xml文本是多个名称空间混用,则会出现Tag名称冲突和属性名称冲突的可能。

另外,采用这种方法是,如果要获取InnerXml,或者将XmlDocument输出或者保存,会出现Exception,需要用XmlTextWriter来做才可以,XmlTextWriter也有一个Namespaces属性,可以设置为False,这样也不会在输出和保存的时候,将xmlns当作一般的属性处理。

作者: 杰棍 [Jegwon]

波波坡原创文章 链接:http://www.bobopo.com/article/code/dotnet_xml_namespace.htm

标签: dotNetIT

关键词: .Net Framework, DotNet, Xml, 名称空间, Namespace, SelectSingleNode, 缺省名称空间, Xmlns

创建日期: 2008-01-22

 
原文地址:https://www.cnblogs.com/zhangchenliang/p/2438418.html