今天使用C#中XMLDocument来读取配置文件中的XML节点,写的时候发现xml文件出现有的文件能够读到节点,有的文件却读取不到节点,纠结了很久,后来发现原来是xml文件中的命名空间惹得祸。
xml文件,大家都知道,为了避免xml中元素命名的冲突,所以xml中可以自定义命名空间,但是在用SelectNodes查询元素时候就会发现,坑爹的问题出现了,这时候就无法找到对应的元素了。如下面
<?xml version="1.0" encoding="UTF-8"?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" >
<session-factory name="Server">
<property name="connection.driver_class">NHibernate.Driver.MySqlDataDriver</property>
<property name="dialect">NHibernate.Dialect.MySQLDialect</property>
<property name="connection.connection_string">server=192.168.30.46;port=8306;Database=***;uid=***;pwd=*</property>
.......
<mapping assembly="StealSecret.Model"/>
</session-factory>
</hibernate-configuration>
这里在hibernate-configuration这个标签后有xmlns,这个就是定义的命名空间,xmlnamespace。这个时候,如果要读取xml文件就需要在XmlDocument对象中加上命名空间。
XmlDocument doc = new XmlDocument();
doc.Load(path + "Config/hibernate.cfg.xml");
XmlNamespaceManager m = new XmlNamespaceManager ( doc.NameTable );
m.AddNamespace("nhb", "urn:nhibernate-configuration-2.2");
XmlNodeList xmlNodes = doc.SelectNodes("//nhb:session-factory/nhb:property[@name='connection.connection_string']", m);
注意这里AddNamespace方法的前面一个参数用于标记这个命名空间,在下面SelectNodes方法中加上对应的标记。给出的这一段是为了查找数据库连接字符串的节点。顺便附带扯下SelectNodes中XPath的语法:
SelectNodes("node") 从当前子节点中查找节点
SelectNodes("/node") 从根节点的子节点中查找节点
SelectNodes("//node") 从任意位置上查找名为node的节点
SelectNodes(".") 选择当前节点
SelectNodes("..") 选择当前节点父节点
SelectNodes("//node[1]") 选择名为node的第一个节点,注意这里是从1开始,不是从0开始
SelectNodes("/@name") 选择有name属性的节点
SelectNodes("/node[position() < 3]") 选择名为node的前两个节点
SelectNodes("//node[@name]") 选择node节点,并且该节点有name属性
SelectNodes("//node[@name='limit']") 选择node节点,并且该节点有name属性,而且name属性值为limit
SelectNodes("//node[contains(item)]") 选择node节点,该节点存在名字item的子节点,注意,如果有命名空间,这里要加命名空间,XX:item
SelectNodes("//node[contains(item,‘Hello World’)]") 选择node节点,该节点存在名字item的子节点,并且item节点内容为Hello World