C# XML的节点遍历、定位、编辑和删除(三)

news2024/11/28 19:37:14

文章目录

      • XML样例
      • 获取整个文档根开始
      • 获取根节点
      • 获取最后一个子节点
      • 在同级之间向前导航
      • 在同级之间向后导航
      • 查找节点
      • 获取多个节点
      • 编辑节点
      • 添加节点
      • 删除节点
      • 小结
      • 附录参考

在项目的实际应用中,有很多数据都会保存为XML配置文件。使用率比较高的操作有加载文档,
读取文档,读取XML的某个节点或属性值,增加或插入一个节点,遍历节点信息等。

XML样例

后面的例子以该xml文档为基础进行演示,在这里我将它放在D:\temp.xml路径下。请注意这个XML文档样例中包含了XmlComment 注释XmlElement 元素,和XmlCDataSection 字符数字段,这些类型同属于节点

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Citys>
  <!--这是一份关于城市省份的文件-->
  <Province level="发达">广东
  <City level="省会">广州</City>
  <City level="一线">深圳</City>
</Province>
  <Province level="发展">广西
    <![CDATA[All Jane Austen novels 25% off starting 3/23!]]>
    <City level="三线">桂林</City>
  </Province>
</Citys>

以下示例演示如何获取根节点,跳转到根节点的第一个子节点、访问其任何子节点、返回到父结点,然后跨同级节点导航。

获取整个文档根开始

演示加载文档,然后使用该对象将文档的内容打印输出到控制台。

            //创建XML文档对象
            XmlDocument document = new XmlDocument();
            //加载整个文档
            document.Load(@"D:\temp.xml");

            //使用document节点将文档内容输出到控制台
            Console.WriteLine(document.DocumentElement.OuterXml);

控制台输出结果:
在这里插入图片描述

获取根节点

演示了如何跳转到根节点的第一个子节点,然后循环访问该节点的子节点。(如果该节点有子节点的话)。

            //创建XML文档对象
            XmlDocument document = new XmlDocument();
            //加载整个文档
            document.Load(@"D:\temp.xml");

            //第一个子节点
            XmlElement root = document.DocumentElement;
          
            if(root.HasChildNodes)
            {//如果有子节点

                 for(int i=0; i<root.ChildNodes.Count; i++)
                {  //展示子节点的内容
                    Console.WriteLine(root.ChildNodes[i].InnerText);
                }
            

示例中root 的值是Citys, 可以从结果中看到该节点下的子节点都会被遍历出来,无论节点类型是XmlElement元素,还是XmlComment注释,或是XmlCDataSection字符数字段。

运行结果:

这是一份关于城市省份的文件
广东广州深圳
广西All Jane Austen novels 25% off starting 3/23!桂林

在这里插入图片描述

获取最后一个子节点

<Province level="发展">广西</Province>是最后一个子节点。

            //创建XML文档对象
            XmlDocument document = new XmlDocument();
            //加载整个文档
            document.Load(@"D:\temp.xml");

            //第一个子节点
            XmlElement root = document.DocumentElement;
          
            if(root.HasChildNodes)
            {//如果有子节点

                XmlNode lastChild = root.LastChild;

                Console.WriteLine("显示最后一个节点元素:");
                Console.WriteLine(lastChild.OuterXml);
            }

运行结果

显示最后一个节点元素:
<Province level="发展">广西<![CDATA[All Jane Austen novels 25% off starting 3/23!]]><City level="三线">桂林</City></Province>

在同级之间向前导航

在xml样例中可以看到注释结点和城市节点City是属于同级节点的。很多情况下我们的xml文件没有添加注释或其它字符数值段,就很容易将它们忽略掉,实际上这些类型也是属于节点。FirstChild使用NextSibling向前导航。

            //创建XML文档对象
            XmlDocument document = new XmlDocument();
            //加载整个文档
            document.Load(@"D:\temp.xml");

            //根节点
            XmlElement root = document.DocumentElement;
          
           //第一个节点
            XmlNode currNode = root.FirstChild;

           Console.WriteLine("显示第一个节点元素:");
           Console.WriteLine(currNode.OuterXml);

            //相邻节点
            XmlNode nextNode = currNode.NextSibling;
            Console.WriteLine("\r\n显示相邻节点元素:");
            Console.WriteLine(nextNode.OuterXml);

运行结果

显示第一个节点元素:
<!--这是一份关于城市省份的文件-->

显示相邻节点元素:
<Province level="发达">广东<City level="省会">广州</City><City level="一线">深圳</City></Province>

在同级之间向后导航

LastChild使用PreviousSibling向后导航。

 //创建XML文档对象
            XmlDocument document = new XmlDocument();
            //加载整个文档
            document.Load(@"D:\temp.xml");

            //根节点
            XmlElement root = document.DocumentElement;
          
           
            XmlNode currNode = root.LastChild;

           Console.WriteLine("显示最后一个节点元素:");
           Console.WriteLine(currNode.OuterXml);


            XmlNode nextNode = currNode.PreviousSibling;
            Console.WriteLine("\r\n显示相邻节点元素:");
            Console.WriteLine(nextNode.OuterXml);

运行结果:

显示最后一个节点元素:
<Province level="发展">广西<![CDATA[All Jane Austen novels 25% off starting 3/23!]]><City level="三线">桂林</City></Province>

显示相邻节点元素:
<Province level="发达">广东<City level="省会">广州</City><City level="一线">深圳</City></Province>

查找节点

可以根据XPath查询字符串来查找一个或多个数据节点。
附录:XPath的表达式MSDN介绍 https://learn.microsoft.com/zh-cn/previous-versions/dotnet/netframework-4.0/ms256086(v=vs.100)?redirectedfrom=MSDN
获取单个节点
演示使用知道节点路径以及是第几个节点来找到省份。

            //创建XML文档对象
            XmlDocument document = new XmlDocument();
            //加载整个文档
            document.Load(@"D:\temp.xml");

            //找Citys元素下的第2个Province元素
            string xPath = "Citys/Province[2]";

            XmlNode currNode = document.SelectSingleNode(xPath);

            if(currNode != null)
            {
                Console.WriteLine("寻找到的元素:");
                Console.WriteLine(currNode.OuterXml);
            }

运行结果

寻找到的元素:
<Province level="发展">广西<![CDATA[All Jane Austen novels 25% off starting 3/23!]]><City level="三线">桂林</City></Province>

还可以使用GetElementById来搜索节点。如果使用这个方法,必须在XML文件的文档类型定义声明中定义ID。
将示例中的XML文档修改如下,此时将Province 节点下的level 声明为ID了。

附录:关于GetElementById的MSDN示例

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!DOCTYPE Citys [  
 
  <!ELEMENT Province ANY>   

  <!ATTLIST Province level ID #REQUIRED>  ]> 

<Citys>
  <!--这是一份关于城市省份的文件-->
  <Province level="发达">广东
  <City level="省会">广州</City>
  <City level="一线">深圳</City>
</Province>
  <Province level="发展">广西
    <![CDATA[All Jane Austen novels 25% off starting 3/23!]]>
    <City level="三线">桂林</City>
  </Province>
</Citys>

使用GetElementById来搜索ID值是发达的节点

            //创建XML文档对象
            XmlDocument document = new XmlDocument();
            //加载整个文档
            document.Load(@"D:\temp.xml");

            //根据(level)ID来搜索节点
            XmlElement findEle = document.GetElementById("发达");
            
            if(findEle != null)
            {                 
                Console.WriteLine("寻找到的元素:");
                Console.WriteLine(findEle.OuterXml);
            }

运行结果:

寻找到的元素:
<Province level="发达">广东
<City level="省会">广州</City><City level="一线">深圳</City></Province>

获取多个节点

在这里使用SelectNodes选择所有Province的节点。

            //创建XML文档对象
            XmlDocument document = new XmlDocument();
            //加载整个文档
            document.Load(@"D:\temp.xml");

            XmlNodeList nodeList;
            //获取根节点
            XmlElement root = document.DocumentElement;

            nodeList = root.SelectNodes("Province");
            foreach(XmlNode node in nodeList)
            {
                //打印节点及其所有子节点的串联值
                Console.WriteLine(node.InnerText);
            }

运行结果:

广东
  广州深圳
广西
    All Jane Austen novels 25% off starting 3/23!桂林

还可以使用GetElementsByTagName通过节点的名称获取节点的集合。

           //创建XML文档对象
            XmlDocument document = new XmlDocument();
            //加载整个文档
            document.Load(@"D:\temp.xml");

            XmlNodeList nodeList;
            //获取根节点
            XmlElement root = document.DocumentElement;

            nodeList = root.GetElementsByTagName("Province");
            foreach(XmlNode node in nodeList)
            {
                //打印节点及其所有子节点的串联值
                Console.WriteLine(node.InnerText);
            }

运行结果同上。

编辑节点

获取某一个(广州)节点,并增加其属性,以及更改原有属性的值。

            //创建XML文档对象
            XmlDocument document = new XmlDocument();
            //加载整个文档
            document.Load(@"D:\temp.xml");

            XmlNodeList nodeList;
            //根节点
            XmlElement root = document.DocumentElement;

            nodeList = root.GetElementsByTagName("City");
            if(nodeList.Count > 0)
            {
                // 获取广州节点
                XmlElement element = (XmlElement) nodeList[0];
                //添加新的属性
                element.SetAttribute("newAttr1", "One");
                element.SetAttribute("newAttr2", "Two");
                element.SetAttribute("newAttr3", "Three");

                //已存在属性的值
                element.Attributes["level"].InnerText = "南方";
              
             }
            document.Save(@"D:\temp.xml");

运行结果:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!DOCTYPE Citys[  
 
  <!ELEMENT Province ANY>   

  <!ATTLIST Province level ID #REQUIRED>  ]>
<Citys>
  <!--这是一份关于城市省份的文件-->
  <Province level="发达">广东
  <City level="南方" newAttr1="One" newAttr2="Two" newAttr3="Three">广州</City>
  <City level="一线">深圳</City></Province>
  <Province level="发展">广西
    <![CDATA[All Jane Austen novels 25% off starting 3/23!]]><City level="省会">桂林</City></Province>
</Citys>

添加节点

可以使用CreateElement方法或CreateNode方法添加节点。
对于任何其他数据类型的节点(比如注释、空格节点或CDATA节点),请使用CreateNode方法。

演示了创建一个省份节点,以及一个城市节点,向这两个节点添加属性,并将节点添加到文档。

             //创建XML文档对象
            XmlDocument document = new XmlDocument();
            //加载整个文档
            document.Load(@"D:\temp.xml");

            //根节点
            XmlElement root = document.DocumentElement;

            //创建省份节点
            XmlElement proEle = document.CreateElement("Province");
            //设置元素值
            proEle.InnerText = "甘肃";
            //设置属性
            proEle.SetAttribute("level", "西北");
            proEle.SetAttribute("Attr5", "测试");

            //创建城市节点
            XmlElement cityEle = document.CreateElement( "City");
            cityEle.InnerText = "兰州";
            cityEle.SetAttribute("level", "拉面");
            //将城市节点添加到省份中
            proEle.AppendChild(cityEle);

            //将省份节点添加到根节点末尾
            root.AppendChild(proEle);

            document.Save(@"D:\temp.xml");

运行结果:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!DOCTYPE Citys[  
 
  <!ELEMENT Province ANY>   

  <!ATTLIST Province level ID #REQUIRED>  ]>
<Citys>
  <!--这是一份关于城市省份的文件-->
  <Province level="发达">广东
  <City level="海南" newAttr1="One" newAttr2="Two" newAttr3="Three">广州</City>
  <City level="一线">深圳</City>
 </Province>

  <Province level="发展">广西
    <![CDATA[All Jane Austen novels 25% off starting 3/23!]]>
    <City level="省会">桂林</City>
  </Province>

  <Province level="西北" Attr5="测试">甘肃
    <City level="拉面">兰州</City>
</Province>
</Citys>

删除节点

使用RemoveChild方法删除节点。

        /// <summary>
        /// 删除一个省份,以及该节点前面出现的空格
        /// </summary>
        /// <param name="province"></param>
        public void DeleteProvince(XmlNode province)
        {
            //前一个节点
            XmlNode preNode = province.PreviousSibling;

            //删除省份节点
            province.OwnerDocument.DocumentElement.RemoveChild(province);

            if(preNode.NodeType == XmlNodeType.Whitespace ||
                preNode.NodeType == XmlNodeType.SignificantWhitespace)
            {//删除空格
                preNode.OwnerDocument.DocumentElement.RemoveChild(preNode);
            }
        }

小结

函数名或类名描述
XmlDocumentXML文档对象
XmlDocument.DocumentElement文档树的根
CreateElement (CreateNode)创建结点
PreviousSibling (NextSibling)同级节点之间的前(后)相邻节点
SelectSingleNode(与XPath配合使用)查找单个节点
GetElementById (与ID配合使用)查找单个节点
SelectNodes(与XPath配合使用)查找多个节点
GetElementsByTagName(与节点名称配合使用)查找多个节点
element.InnerText = "甘肃"; element.SetAttribute("Attr5", "测试")编辑节点
InsertAfter (InsertBefore)定位节点
RemoveChild删除节点

附录参考

1 XPath的使用 XPath的表达式MSDN介绍 https://learn.microsoft.com/zh-cn/previous-versions/dotnet/netframework-4.0/ms256086(v=vs.100)?redirectedfrom=MSDN

2 XML文件的文档类型定义声明中定义ID 关于GetElementById的MSDN示例

3 XmlDocument 类 的介绍 https://learn.microsoft.com/zh-cn/dotnet/api/system.xml.xmldocument?view=net-7.0

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/528507.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023-数仓常见问题以及解决方案

01 数据仓库现状 小 A 公司创建时间比较短&#xff0c;才刚过完两周岁生日没多久&#xff1b;业务增长速度快&#xff0c;数据迅速增加&#xff0c;同时取数需求激增与数据应用场景对数据质量、响应速度、数据时效性与稳定要求越来越高&#xff1b;但技术能力滞后业务增长&…

ESXI8中修改虚拟机磁盘格式

厚置备改精简置备 改后 所以&#xff0c;先开启SSH、Shell服务 流程如下&#xff1a; 使用root登录SSH [rootlocalhost:~] [rootlocalhost:~] cd "/vmfs/volumes/HDD1/SOESC" [rootlocalhost:/vmfs/volumes/64398ef2-3cb0bdb4-2552-e8611f32b3ac/SOESC] ls -lh …

R.I.P,又一位程序员巨佬——左耳朵耗子陨落

震惊&#xff01;谣言吧&#xff01;求辟谣&#xff01;默哀&#xff01; 左耳朵耗子&#xff0c;在程序员这个群体里应该属于 GOAT 的存在了&#xff0c;虽然每个人心目中都有自己的 GOAT&#xff0c;但耗子叔的影响力可以说是有目共睹。 我也是在技术群刷到这张图片的&#…

由浅入深理解java集合(二)——集合 Set

一、HashSet类 HashSet简介 HashSet是Set接口的典型实现&#xff0c;实现了Set接口中的所有方法&#xff0c;并没有添加额外的方法&#xff0c;大多数时候使用Set集合时就是使用这个实现类。HashSet按Hash算法来存储集合中的元素。因此具有很好的存取和查找性能。 HashSet特点…

Docker Swarm集群管理

秋风阁(https://focus-wind.com/) 文章目录 基本概念Swarm节点任务与服务 集群管理端口配置创建集群加入集群查看集群退出集群 节点设置节点标签设置节点信息查询 服务管理部署服务查看服务服务日志查看服务重启 Docker Swarm官方文档 Docker Swarm是Docker引擎原生内置的容器…

FE_函数(Function)的基本理解

1 函数&#xff08;Function&#xff09;的基本理解 函数就是在程序设计中&#xff0c;将一段代码封装起来&#xff0c;完成一个特定的功能&#xff0c;并给这段代码起一个名称&#xff0c;程序通过名称就可以执行这段代码。函数也是一个对象&#xff0c;也具有普通对象的功能…

华为测开面试记,三面被吊打,所幸最后Offer已到手

在互联网做了几年之后&#xff0c;去大厂“镀镀金”是大部分人的首选。大厂不仅待遇高、福利好&#xff0c;更重要的是&#xff0c;它是对你专业能力的背书&#xff0c;大厂工作背景多少会给你的简历增加几分竞争力。 但说实话&#xff0c;想进大厂还真没那么容易。最近面试华…

企业级信息系统开发讲课笔记4.3 Spring Boot两种全局配置和两种注解

文章目录 零、学习目标一、全局配置文件概述二、Application.properties配置文件&#xff08;一&#xff09;创建Spring Boot的Web项目PropertiesDemo&#xff08;二&#xff09;在application.properties里添加相关配置1、配置tomcat端口号和web虚拟路径2、对象类型的配置与使…

C++继承(一文学懂继承)——对象赋值转换、菱形虚拟继承

hello&#xff0c;这里是bangbang&#xff0c;今天来讲下继承。 面向对象三大特性&#xff1a;封装、继承、多态。 目录 1. 继承的概念及定义 1.1 继承的概念 1.2 继承定义 1.2.1 定义格式 1.2.2 继承关系和访问限定符 1.2.3 继承基类成员访问方式的变化 2. 基类和派生类对…

波士顿房价数据集怎么不见了?

波士顿数据下载 消失的波士顿 OoO 做线性回归的同学大概率会用到一个数据集&#xff0c;即波士顿房价数据集&#xff0c;然而当你从sklearn下载该数据集时&#xff0c;你会惊讶地发现居然下载不了了&#xff01;&#xff01;&#xff01;起初我以为是是什么别的原因导致数据集可…

云计算之OpenStack基础

云计算之OpenStack基础 一、OpenStack基础知识二、虚拟化2.1 虚拟化类型2.1.1 Ⅰ型虚拟化2.1.2 Ⅱ型虚拟化2.1.3 比较 2.2 KVM&#xff08;Ⅱ型虚拟化&#xff09;2.2.1 基本概念2.2.2 Libvirt2.2.3 CPU虚拟化2.2.4 内存虚拟化2.2.5 存储虚拟化2.2.5.1 目录类型的 Storage Pool…

【教程】配置NFS共享直接访问目标服务器的存储目录

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] 目录 前景提要 NFS安装教程 旧服务器上 新服务器上 验证安装 优缺点 扩展 前景提要 我们新服务器的硬盘容量很小&#xff0c;但旧服务器的硬盘容量很大。如何在不拔硬盘的情况下&#xff0c;直接已本地目录…

分区计量管理项目应用

为充分发挥分区计量管理项目在漏损控制的效用&#xff0c;应构建科学完备的应用体系&#xff0c;如下图 分区计量应用体系 1. 基于水量平衡分析的漏损现状评估方法 分区计量管理项目通过监控分析DMA 分区内流量、压力、水质、大用户用水等情况&#xff0c;结合营业抄收系统的营…

【内网渗透】春秋云镜 Tsclient WP

前言 mssql连接和攻击、windows提权、令牌窃取、镜像劫持 flag1 上来就扫给的地址 nmap: 结合题目的mssql知识点&#xff0c;估计是从这里入手了&#xff0c;尝试爆破用户名和密码&#xff0c;这里先用fscan来爆&#xff0c;可以直接爆出来&#xff08;别的工具也可&#x…

0.96寸oled显示坏苹果(badapple)

前言 俗话说&#xff1a;有屏幕的地方就会有badapple。 下面带来使用0.96寸OLED屏幕显示badapple的教程。 1、获取视频 首先从网上下载badapple的视频&#xff0c;下载地址&#xff1a;badapple 2、抓取视频图片 使用OLED播放视频的思想就是将视频分成一张一张的图片然后进行…

叉乘在图形学中的几何意义 ---- 判断一个点是否在三角形内

1 叉乘是什么 先简单介绍一下叉乘(cross product)&#xff1a; a → b → \overrightarrow{a} \times \overrightarrow{b} a b &#xff0c;其结果&#xff0c;还是一个向量。 其方向&#xff0c;符合右手螺旋定则&#xff08;右手手指头从a转向b&#xff0c;看大拇指指向哪…

声音合成——Foley Sound——DECASE项目——多模态智能感知与应用——VariantAutoencoder(VAE)代码实现(7)

文章目录 概述VAE代码实现关闭eager execution修改bottlenectk组件修改loss损失函数 Preprocessline模块实现Loader模块Padder模块LogSpectrogramExtractor模块MinMaxNormaliser模块Saver模块PreprocessPipeLine模块知识补充property修饰词 train训练模块load_fsdd模块train模块…

针对基于智能卡进行认证的活动目录攻击

最近&#xff0c;我参与了一项攻击基于智能卡的活动目录的工作。实际上&#xff0c;你根本不需要使用物理智能卡来验证登录这个活动目录。证书的属性决定了它是否可以用于基于智能卡进行登录。因此&#xff0c;如果你能获得相应的私钥&#xff0c;那么就可以绕过智能卡的验证实…

ubuntu 22.04 安装 Docker Desktop 及docker介绍

目录 一、Docker Desktop 安装 1、我们先去官网下载安装包 2、Install Docker Desktop on Ubuntu 3、Launch Docker Desktop 二、Docker 介绍 什么是docker 如何使用docker docker是如何工作的 docker build docker run docker pull 一、Docker Desktop 安装 1、我们先…

网络应用技术师技能考试试题+讲解

作者简介:一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭:低头赶路,敬事如仪 个人主页:网络豆的主页​​​​​​ 前言 本章将会讲解网络应用技术师技能考试试题 一.正文 一、单选题(每题1分,满分50分) 1. 设信号的波特率为800Baud,采用幅度…