.NET(C#):使用XPath查询带有命名空间(有xmlns)的XML
原文http://www.cnblogs.com/mgen/archive/2011/05/24/2056025.html
众所周知,XmlDocument可以进行XPath查询,但实际上这里所说的XPath查询仅限于没有命名空间(没有xmlns属性)的XML,一旦遇到有命名空间的XML,对应XPath查询都会无结果。
比如下面这个XML
<a xmlns="mgen.cnblogs.com">
<b>ccc</b>
</a>
XPath查询/a/b会返回null,而如果没有xmlns的话,会返回节点b。
为什么会这样呢?MSDN的相应函数有解释(参考:http://msdn.microsoft.com/en-us/library/system.xml.xmlnode.selectsinglenode.aspx)
If the XPath expression does not include a prefix, it is assumed that the namespace URI is the empty namespace. If your XML includes a default namespace, you must still add a prefix and namespace URI to the XmlNamespaceManager; otherwise, you will not get any nodes selected.
意思就是如果XPath表达式没有加前缀(如a:b中前缀是a),那么所查询节点(注意属性也可以是节点)的命名空间URI就应该是空值(也是默认值),否则XPath不会返回结果。
上面的XML, 因为节点a和b都有命名空间值,自然XPath查询不会有结果。
(上面英文还提到如果节点有默认命名空间,那么还得手动向XmlNamespaceManager添加前缀和命名空间值,这个在后面会讲的)
在看解决方案前,首先需要能够辨识XML命名空间,当然辨识XML命名空间值还是很容易的,参考如下XML(这个XML在后面程序中也会用到)
<?xmlversion="1.0" encoding="utf-8"?>
<rootxmlns="dotnet" xmlns:w="wpf">
<a>data in a</a>
<w:b>data in b</w:b>
<cxmlns="silverlight">
<w:d>
<e>data in e</e>
</w:d>
</c>
</root>
它的所有XML节点的命名空间如下所示:
<?xmlversion="1.0" encoding="utf-8"?>
<rootxmlns="dotnet" xmlns:w="wpf">
<!-- xmlns: dotnet -->
<a>data in a</a>
<!-- xmlns: dotnet -->
<w:b>data in b</w:b>
<!-- xmlns: wpf -->
<cxmlns="silverlight">
<!-- xmlns: silverlight -->
<w:d>
<!-- xmlns: wpf -->
<e>data in e</e>
<!-- xmlns: silverlight -->
</w:d>
</c>
</root>
如果识别XML命名空间没有问题,那么后面的操作就相当简单了,你需要记住:在XmlDocument中用XPath查询某一节点时,只要它的命名空间值不是空值,那么你必须给它一个前缀, 用这个前缀代表这个节点的命名空间值!这些前缀是通过XmlNamespaceManager类添加的,使用时将XmlNamespaceManager 传入SelectNodes或SelectSingleNode中即可。这也是为什么上面说“如果节点有默认命名空间,那么还得手动向 XmlNamespaceManager添加前缀和命名空间值”的原因。
另外构造一个XmlNamespaceManager需要XmlNameTable对象,这个对象可以从XmlDocument.NameTable和XmlReader.NameTable属性中得到。
下面我们步入代码,比如说查询上面XML中的节点e,分析位置节点e位于:root->c->d->e,然后将所需命名空间值加入到XmlNamespaceManager中(前缀名称无所谓,只要在XPath一致即可),查询即可成功,如下代码:
/*
* 假设上面XML文件在C:\a.txt中
* 下面代码会查询目标节点e,并输出数据:data in e
* */
var xmlDoc =newXmlDocument();
xmlDoc.Load(@"C:\a.txt");
//加入命名空间和前缀
var xmlnsm =newXmlNamespaceManager(xmlDoc.NameTable);
xmlnsm.AddNamespace("d", "dotnet");
xmlnsm.AddNamespace("s", "silverlight");
xmlnsm.AddNamespace("w", "wpf");
var node = xmlDoc.SelectSingleNode("/d:root/s:c/w:d/s:e", xmlnsm);
Console.WriteLine(node.InnerText);
//输出:data in e
.NET(C#):使用XPath查询带有命名空间(有xmlns)的XML的更多相关文章
- 使用XPath查询带有命名空间(有xmlns)的XML(转)
使用XPath查询带有命名空间(有xmlns)的XML 标签: xmlsilverlightwebserviceencodingwpfinclude 2012-06-19 10:26 3235人阅读 ...
- C#使用Linq to XML进行XPath查询
最近在用到HtmlAgliltyPack进行结点查询时,发现这里选择结点使用的是XPath.所以这里总结一下在C#中使用XPath查询XML的方法.习惯了用Linq,这里也是用的Linq to xml ...
- php解析带有命名空间的xml
xml如果带有命名空间我们将如何解析,例如: <ns1:CreateBillResponse xmlns:ns1="http://neusoft.com" xmlns:xsd ...
- 带有命名空间的xml解析,C#
前一段时间做花旗的接口,返回的xml格式是带有命名空间的,可是难倒了我,找了好久才找到解决办法,给大家分享下,少走弯路. 1,直接进入正题,先看一段带有命名空间的xml,这段xml大概的意思是,前面是 ...
- Oracle查询一个命名空间下所有表和视图的表名、字段名、字段类型、字段大小,是否可为NULL,主键和注释信息
使用SQL查询Oracle一个命名空间下所有表和视图的表名.字段名.字段类型.字段大小,是否可为NULL,主键和注释信息. SQL如下,注意需要将'CDFLOOD'更换为您要查询的命名空间: sele ...
- MySQL 按照日期格式查询带有时间戳数据
按照日期格式查询带有时间戳数据一般在MSQL数据库中的时间都是以时间戳的格式来存储时间的,但是对于我们来说,时间戳格式具体表示的是什么时间,我们很难一眼看出来,所以当我们要具体查询某一个时间或时间段的 ...
- 2)thinkphp的带有命名空间的自动加载机制
(1)为啥thinkphp里面的文件要是写你的命名空间,要与你的路径一样,因为在thinkphp实现自动加载机制的原理,就是靠的你的命名空间对应这个路径,然后自动加载机制通过这个路径找到你的类文件,然 ...
- 读写XML文档时,去掉新增加节点的“空命名空间”(xmlns=””)
在做对ReprotViewer编程时,想做一个用户可以更改显示/打印列的功能,大致看了下,只需要通过对rdlc文件中改变其<Hidden>节点值为false/true,即可实现对应某列的显 ...
- 让你编写的控件库在 XAML 中有一个统一的漂亮的命名空间(xmlns)和命名空间前缀
原文 让你编写的控件库在 XAML 中有一个统一的漂亮的命名空间(xmlns)和命名空间前缀 在 WPF XAML 中使用自己定义的控件时,想必大家都能在 XAML 中编写出这个控件的命名空间了.然而 ...
随机推荐
- JavaSE复习日记 : 循环终止语句(break/break outerFor/continue)
最近没网,但攒了几天的博客,这次逮到机会发博客,直接三篇走起; /* * 循环终止语句: break/ break outerFor/ continue */ /* * break语句 * 1. 用于 ...
- 幻世(OurDream)2D图形引擎易语言汉化版更新提示
幻世引擎的易语言汉化专版到目前为止已经累积了多个BUG,其中多个BUG是影响引擎功能使用的问题,我将会在近期发布修复所有问题的更新版本(此更新版本同时也将会支持最新的对加入的粒子系统的支持),敬请各位 ...
- Storm基础理论
Storm流式计算基础 .note-content {font-family: "Helvetica Neue",Arial,"Hiragino Sans GB" ...
- Nodejs学习笔记——Assert(断言)
Assert - a:actual e:expected m:message o:operator v:value b:block assert.fail(a, e, m, o) assert(v, ...
- spring常量值注入
<context:property-placeholder location="classpath:resources/*.properties" /> @Value( ...
- Adobe Acrobat 9 Pro Extended 9.4简体中文完整免激活注册版
Acrobat9 Pro最近升级比较频繁,如今已经升级到了Acrobat 9 Pro Extended 9.4版.亿品元素上曾经分享过Acrobat Pro Extended简体中文版 9.3.3 优 ...
- [原]命令模式在MVC框架中的应用
其实在项目开发中,我们使用了大量的设计模式,只是这些设计模式都封装在框架中了,如果你想要不仅仅局限于简单的使用,就应该深入了解框架的设计思路. 在MVC框架中,模式之一就是命令模式,先来看看模式是如何 ...
- nautilus-open-terminal右键随处打开终端
Nautilus-Open-Terminal : 可随处打开终端的 Nautilus 插件 nautilus-open-terminal-0.17-4.el6.x86_64 是一个让你随处都可以打开终 ...
- C语言入门(3)——对Hello World程序的解释
上篇我们写了一个最简单的程序.这个简单的程序包含了很多重要的内容.本篇我们通过这个最简单的Hello World程序逐一讲解C语言程序的一些特点. 打开Visual Studio 2013 通过菜单- ...
- android服务Service(上)- IntentService
Android学习笔记(五一):服务Service(上)- IntentService 对于需要长期运行,例如播放音乐.长期和服务器的连接,即使已不是屏幕当前的activity仍需要运行的情况,采用服 ...