zoukankan      html  css  js  c++  java
  • C#中用SelectSingleNode方法解析带有多个命名空间的XML文件

      今晚在博问看到一个问题:查找xml文件中特定属性值的节点,给它增加一个新属性,本以为很简单,随手写了一个程序,却遇到了问题,主要是多个命名空间的原因,查找了一些资料最终解决了,现把解决的办法分享出来,大家如果有更好的方案欢迎留言讨论。

      XML文件如下:

    <?xml version="1.0" encoding="utf-8" ?>
    <Enginuity:ViewControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x
    ="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d
    ="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc
    ="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:Enginuity
    ="clr-namespace:Enginuity.Core;assembly=Enginuity.Core">
    <Viewbox Stretch="Fill">
    <TextBox Name="Text_10" Value="abc"/>
    <TextBox Name="Text_11" Value="bcd"/>
    </Viewbox>
    </Enginuity:ViewControl>

      这里小小提示一下,Enginuity:ViewControl 这种写法表示ViewControl的命名空间为Enginuity。

      现在要得到的是Name为Text_10的TextBox结点的Value属性值:abc。

      关于SelectSingleNode方法大家可以参考:http://msdn.microsoft.com/en-us/library/h0hw012b.aspx

      这个方法有两个参数,第一个是string xpath,这个是必须的,第二个是XmlNamespaceManager nsmgr,这个可选。重要的一点就是xpath的写法,主要就是命名空间:节点/命名空间:节点/...,官方给的示例中只有一个命名空间,xml结构相对比较简单。

      从上面的XML文件中很容易看出ViewControl的命名空间是Enginuity,但ViewBox的命名空间是什么呢?查找了XML文件命名空间的定义后,发现有这么一句”如果Xml文档里没有明确指出当前节点的命名空间,那么当前节点的命名空间继承其父节点的命名空间“,ViewBox的父节点是ViewControl,ViewControl的命名空间是Enginuity,同时注意到Enginuity还不是最终的命名空间,Enginuity的命名空间是xmlns,那么是哪一个呢?

      动手试呗,于是写出下面的程序:

                XmlDocument dom = new XmlDocument();
    dom.Load(
    @"E:\NET\test.xml");
    XmlNamespaceManager xnm
    =new XmlNamespaceManager(dom.NameTable);
    xnm.AddNamespace(
    "e", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
    xnm.AddNamespace(
    "x", "http://schemas.microsoft.com/winfx/2006/xaml");
    xnm.AddNamespace(
    "d", "http://schemas.microsoft.com/expression/blend/2008");
    xnm.AddNamespace(
    "mc", "http://schemas.openxmlformats.org/markup-compatibility/2006");
    xnm.AddNamespace(
    "Enginuity", "clr-namespace:Enginuity.Core;assembly=Enginuity.Core");
    XmlNodeList xNodes
    = dom.SelectSingleNode("Enginuity:ViewControl", xnm).ChildNodes;
    Console.WriteLine(xNodes[
    0].NamespaceURI);

      结果如下:

      可以看到,ViewControl的命名空间为最顶及的xmlns,于是写出下面的程序:

                XmlDocument dom = new XmlDocument();
    dom.Load(
    @"E:\NET\test.xml");
    XmlNamespaceManager xnm
    =new XmlNamespaceManager(dom.NameTable);
    xnm.AddNamespace(
    "e", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
    xnm.AddNamespace(
    "x", "http://schemas.microsoft.com/winfx/2006/xaml");
    xnm.AddNamespace(
    "d", "http://schemas.microsoft.com/expression/blend/2008");
    xnm.AddNamespace(
    "mc", "http://schemas.openxmlformats.org/markup-compatibility/2006");
    xnm.AddNamespace(
    "Enginuity", "clr-namespace:Enginuity.Core;assembly=Enginuity.Core");
    XmlNode xNode
    = dom.SelectSingleNode("Enginuity:ViewControl/e:Viewbox/e:TextBox[@Name='Text_10']", xnm);
    Console.WriteLine(xNode.Attributes[
    "Value"].Value);

      运行后效果如下:

      期待中的”abc“终于出现了。

      因此,得出一个结论,在用SelectSingleNode方法解析含有多个命名空间的XML文件时,没有明确标出命名空间的节点,其命名空间为根节点的命名空间。如果还不确定可以从根节点开始,逐层输出该级节点的命名空间。

      keyword:SelectSingleNode,C#解析XML文件,SelectSingleNode多命名空间,

    版权
    作者:天行健,自强不息

    出处:http://www.cnblogs.com/durongjian

    本文首发博客园,版权归作者跟博客园共有。

    转载必须保留本段声明,并在页面显著位置给出本文链接,否则保留追究法律责任的权利。

  • 相关阅读:
    Windows server 2016 解决“无法完成域加入,原因是试图加入的域的SID与本计算机的SID相同。”
    Windows Server 2016 辅助域控制器搭建
    Windows Server 2016 主域控制器搭建
    Net Framework 4.7.2 覆盖 Net Framework 4.5 解决办法
    SQL SERVER 2012更改默认的端口号为1772
    Windows下彻底卸载删除SQL Serever2012
    在Windows Server2016中安装SQL Server2016
    SQL Server 创建索引
    C#控制台或应用程序中两个多个Main()方法的设置
    Icon cache rebuilding with Delphi(Delphi 清除Windows 图标缓存源代码)
  • 原文地址:https://www.cnblogs.com/artwl/p/2111073.html
Copyright © 2011-2022 走看看