ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

【C# XML】XmlDocument 类

2022-04-16 01:04:11  阅读:191  来源: 互联网

标签:XML xml Console string C# XmlDocument WriteLine XmlNode 节点


原文地址:https://zhuanlan.zhihu.com/p/337698648

XmlDocument 类的方法和属性

  1. XmlDocument 类的一些常用的属性
属性描述
XmlAttributeCollection Attributes { get; } 获取当前节点的所有属性引用对象集合
XmlNodeList ChildNodes { get; } 获取子级节点集合
XmlElement DocumentElement { get; } 获取文档的根节点
XmlDocumentType DocumentType { get; } 获取XML文档类型定义
XmlNodeType NodeType { get; } 获取当前节点的类型
XmlDocument OwnerDocument { get; } 获取当前节点所属的 XmlDocument 对象
XmlNode ParentNode { get; } 获取父节点(针对可以拥有父级的节点)
string BaseURI { get; } 获取文档的地址
string InnerText { get; set;} 获取或设置当前节点和子级的文本
string InnerXml { get; set; } 获取或设置子级节点的标签和文本
string LocalName { get; } 获取节点本地名称
string Name { get; } 获取节点限定名称
bool IsReadOnly { get; } 是否只读
bool PreserveWhitespace { get; set; } 获取或设置元素内容是否保留空白区域
XmlNameTable NameTable { get; } 获取关联的 XmlNameTable
IXmlSchemaInfo SchemaInfo { get; } 返回节点的后架构验证信息集 (PSVI)
XmlSchemaSet Schemas { get; set; } 获取或设置与此 XmlDocument 关联的XmlSchemaSet 对象
XmlNode NextSibling { get; } 获取下一个节点(XmlNode)
XmlNode PreviousSibling { get; } 获取上一个节点(XmlNode)
XmlNode PreviousText { get; } 获取该节点之前的文本节点(XmlNode)
XmlNode LastChild { get; } 获取该节点的最后一个子节点(XmlNode)
XmlNode FirstChild { get; } 获取节点的第一个子级(XmlNode)
XmlElement Item[string name] { get; } 获取具有指定Name的第一个子元素 (XmlNode)
string OuterXml { get; } 获取当前节点和子级的标签和文本(XmlNode)
string Prefix { get; set; } 获取或设置该节点的命名空间前缀(XmlNode)
string Value { get; set; } 获取或设置节点的值(XmlNode)
string NamespaceURI { get; } 获取该节点的命名空间 URI(XmlNode)
bool HasChildNodes { get; } 判断该节点下是否有子节点(XmlNode)

2. XmlDocument 类的一些常用的方法

方法描述
XmlElement CreateElement (string name); 创建一个新节点
XmlAttribute CreateAttribute (string name); 创建指定名称的属性
void SetAttribute(string attribute ,string value); 为指定节点的新建属性并赋值
mlNode AppendChild (XmlNode newChild); 为指定节点末尾添加子节点(XmlNode)
XmlAttribute SetAttributeNode(XmlAttribute newAttr); 指定节点添加指定的属性
XmlElement GetElementById (string elementId); 获取具有指定ID的XmlElement
XmlNodeList GetElementsByTagName (string name); 返回一个 XmlNodeList,它包含与指定Name匹配的所有节点的列表,特殊值“*”匹配所有标记
XmlNode ImportNode (XmlNode node, bool deep); 将节点从另一个文档导入到当前文档
XmlNode CreateNode (string nodeType, string name, string namespace); 创建一个节点
XmlNode InsertAfter (XmlNode newChild, XmlNode refChild); 将指定的节点紧接着插入指定的引用节点之后(XmlNode)
XmlNode InsertBefore (XmlNode newChild, XmlNode refChild); 将指定的节点紧接着插入指定的引用节点之前(XmlNode)
void Load (string filename); 从指定的地址加载 XML 文档
void LoadXml (string xml); 从指定的字符串加载 XML 文档
XmlNode PrependChild (XmlNode newChild); 指定的节点添加到该节点的子节点列表的开头(XmlNode)
XmlNode SelectSingleNode (string xpath); 选择一个节点
XmlNodeList SelectNodes (string xpath); 获取同名同级节点集合
void RemoveAll (); 移除当前节点的所有子节点和/或属性(XmlNode)
XmlNode RemoveChild (XmlNode oldChild); 移除指定的子节点(XmlNode)
XmlNode ReplaceChild (XmlNode newChild, XmlNode oldChild); 用新子节点替换旧子节点(XmlNode)
void Save (string filename); 保存XML文件,如果存在指定文件,则此方法会覆盖它

关于查询,可以简单了解一下XPath表达式:

表达式描述
nodename 选取此节点的所有子节点
/ 从根节点选取
// 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置
. 选取当前节点
.. 选取当前节点的父节点
@ 选取属性

代码演示

示例XML文档内容如下:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE note SYSTEM "Note.dtd"[]>
<note>
  <ID id1="111" id2="222"/>
  <name>张三</name>
  <jobs>
    <type>搬砖</type>
    <time>1h</time>
  </jobs>
  <jobs>
    <type>伐木</type>
    <time>1h</time>
  </jobs>
  <sex>
    <man>男</man>
    <woman>女</woman>
  </sex> 
</note>

 

using System;
using System.Xml;

namespace XML操作
{
    class Program
    {
        static void Main(string[] args)
        {
            XMLTest();
            XMLTest2();
            Console.ReadKey();
        }
        //先封装一个简单的输出方法方便验证结果
        /// <summary>
        /// 一个简单输出方法
        /// </summary>
        static void C(string str,object obj)
        {
            Console.WriteLine(" {0}: {1}" ,str, obj);
            Console.WriteLine(" ------------------------------");
        }

        //定义两个文档地址
        static string filePath = @"C:\Users\Administrator\Desktop\Temp\test.xml";   
        static string filePath2 = @"C:\Users\Administrator\Desktop\Temp\test2.xml";  
        //定义两个 XML 对象
        static XmlDocument xml; 
        static XmlDocument xml2;
        //定义两个常用的节点
        static XmlNode IDnote;
        static XmlNode jobsnote;

        /// <summary>
        /// XML属性测试
        /// </summary>
       static void XMLTest()
        {
            //构造函数
            xml = new XmlDocument();

            //如果 XML 文档中存在注释,读取时会报错
            //可以通过 XmlReaderSettings ,XmlReader 组合设置即可
            //文档读取完毕后,要关闭 XmlReader
            XmlReaderSettings settings = new XmlReaderSettings();

            //设置忽略注释
            settings.IgnoreComments = true;

            //通过 XmlReader 设置规则
            XmlReader reader = XmlReader.Create(filePath, settings);

            //读取 XmlReader 中缓存的 XML

            xml.Load(reader);

            //关闭 XmlReader
            reader.Close();

            //选择第一个按标签匹配到的节点,节点需要从根节点开始一层一层到当前节点标签
            IDnote = xml.SelectSingleNode("/note/ID");
            jobsnote = xml.SelectSingleNode("/note/jobs");

            Console.WriteLine("\n ------------------------------\n");

            Console.WriteLine(" 1.获取 当前 节点的所有属性引用对象集合");
            //不包含子级的属性
            XmlAttributeCollection attributes = IDnote.Attributes;
            //遍历出来的item必须指定类型(拆箱),否则默认为boject类型
            foreach (XmlNode i in attributes) C("Attributes", i.Value);

            Console.WriteLine(" 通过 item 的方式直接获取单个属性的引用对象");
            //需要通过 item[] 的方式定位到具体属性名
            C("Attributes[id1]", IDnote.Attributes["id1"].Value);
            
            Console.WriteLine(" 2.获取 文档的地址");
            string URI = xml.BaseURI;
            C("BaseURI", URI);

            Console.WriteLine(" 3.获取 当前 节点本地名称");
            string localName = jobsnote.LocalName;
            C("LocalName", localName);

            Console.WriteLine(" 4.获取 当前节点 限定名称");
            string name = jobsnote.Name;
            C("Name", name);
        }
    }
}
View Code

 

运行结果:

 

 

            Console.WriteLine(" 5.获取 当前和子级 的标签和文本(XmlNode)");
            string outerXml = jobsnote.OuterXml;
            C("OuterXml", outerXml);

            Console.WriteLine(" 6.获取或设置 当前和子级 的文本");
            string innerText = jobsnote.InnerText;
            C("InnerText", innerText);

            Console.WriteLine(" 7.获取或设置 子级 节点的标签和文本");
            //只能获取子节点,不包含当前节点
            string innerXml = jobsnote.InnerXml;
            C("InnerXml", innerXml);

            Console.WriteLine(" 8.获取 XML文档类型定义");
            XmlNode documentType = xml.DocumentType;
            C("DocumentType", documentType.OuterXml);

            Console.WriteLine(" 9.获取 子级 节点集合");
            //只能获取子节点,不包含当前节点
            XmlNodeList childNodes = jobsnote.ChildNodes;
            //可以通过 XmlNodeList.Item(index) 方法索引获得单个节点
            string childNodesItem = childNodes.Item(0).LocalName;
            //也可以遍历列表
            foreach (XmlNode i in childNodes) C(" ChildNodes", i.LocalName);

            Console.WriteLine(" 10.获取 文档的 根 节点");
            //根节点是唯一的
            XmlNode documentElement = xml.DocumentElement;
            C("DocumentElement", documentElement.LocalName);

            Console.WriteLine(" 11.获取 当前文档的 XmlImplementation 对象");
            XmlImplementation xmlImplementation = xml.Implementation;
            Console.WriteLine("\n ------------------------------\n");
View Code

 

运行结果:

 

 

            Console.WriteLine(" 12.判断 是否只读");
            bool isRead = xml.IsReadOnly;
            C("IIsReadOnly" , isRead);

            Console.WriteLine(" 13.获取或设置 元素内容是否保留空白区域");
            //经过试验,设置为 true 会将每一行开头和结尾的空白以及换行符给去掉
            //相反,false 会保留开头和结尾的处的空白和换行符
            //??为何呢??
            bool preserveWhitespace = xml.PreserveWhitespace;
            C("PreserveWhitespace", preserveWhitespace);

            Console.WriteLine(" 14.获取 当前节点 的类型");
            XmlNodeType nodeType = jobsnote.NodeType;
            XmlNodeType nodeType2 = xml.NodeType;
            C("1.NodeType", nodeType);
            C("2.NodeType", nodeType2);

            Console.WriteLine(" 15.获取 当前节点 所属的 XmlDocument 对象");
            XmlDocument ownerDocument = jobsnote.OwnerDocument;
            C("OwnerDocument" , ownerDocument);

            Console.WriteLine(" 16.获取 父 节点");
            //针对可以拥有父级的节点
            XmlNode parentNode = jobsnote.ParentNode;
            C("ParentNode" , parentNode.LocalName);

            Console.WriteLine(" 17.获取 下一个节点(XmlNode)");
            //注意:
            //1.下一个节点必须是当前节点的同级节点,否则会返回null
            //2.如果存在多个标志相同的节点,则默认为第一个
            //下面代码会报错,因为不存在和根节点同级的节点,版本声明不属于节点
            //XmlNode next = xml.DocumentElement.NextSibling; 
            XmlNode nextSibling = jobsnote.NextSibling;
            C("NextSibling" , nextSibling.LocalName);

            Console.WriteLine(" 18.获取 上一个节点(XmlNode)");
            //注意:内容同上
            XmlNode previousSibling = jobsnote.PreviousSibling;
            C("PreviousSibling" , previousSibling.LocalName);

 

运行结果:

 

 

    Console.WriteLine(" 19.获取 当前 节点之前的文本节点(XmlNode)");
            //??不知为何返回null??
            //请求高人指点
            XmlNode previousText = jobsnote.PreviousText;
            //C("PreviousText" , previousText.InnerXml); 
            Console.WriteLine("\n ------------------------------\n");

            Console.WriteLine(" 20.获取 当前 节点的 最后子级(XmlNode)");
            XmlNode lastChild = jobsnote.LastChild;
            C("LastChild" , lastChild.LocalName);

            Console.WriteLine(" 21.获取 当前 节点的 首位子级(XmlNode)");
            XmlNode firstChild = jobsnote.FirstChild;
            C("FirstChild" , firstChild.LocalName);

            Console.WriteLine(" 22.获取 具有指定 Name 的第一个子元素 (XmlNode)");
            XmlNode item = documentElement["jobs"];
            C("item" , item.LocalName);

            Console.WriteLine(" 23.获取或设置节点的值(XmlNode)");
            //注意:
            //这里想要获得Value的值,必须详细定位到哪个属性,需要调用Attributes["属性名"]
            string value = IDnote.Attributes["id2"].Value;
            C("Value", value);

            Console.WriteLine(" 24.获取该节点的命名空间 URI(XmlNode)");
            string namespaceURI = xml.NamespaceURI;
            C("NamespaceURI", namespaceURI);

            Console.WriteLine(" 25.判断该节点下是否有子节点(XmlNode)");
            bool hasChildNodes = xml.HasChildNodes;
            C("HasChildNodes", hasChildNodes);

 

运行结果:

 

 

    static void XMLTest2()
        {
            //构造函数
            xml = new XmlDocument();

            //如果 XML 文档中存在注释,读取时会报错
            //可以通过 XmlReaderSettings ,XmlReader 组合设置即可
            //文档读取完毕后,要关闭 XmlReader
            XmlReaderSettings settings = new XmlReaderSettings();

            //设置忽略注释
            settings.IgnoreComments = true;

            //通过 XmlReader 设置规则
            XmlReader reader = XmlReader.Create(filePath, settings);

            //读取 XmlReader 中缓存的 XML

            xml.Load(reader);

            //关闭 XmlReader
            reader.Close();

            //获取根节点
            XmlElement rootElement = xml.DocumentElement;

            Console.WriteLine(" \n查询类方法:\n");
            
            Console.WriteLine(" 1.获取与指定节点标签名称匹配的所有节点的列表");
            XmlNodeList getElementsByTagName = xml.GetElementsByTagName("jobs");
            foreach (XmlNode i in getElementsByTagName)
            {
                Console.Write("\n getElementsByTagName(jobs): {0}\n", i.LocalName);
            }
            Console.WriteLine("\n ------------------------------\n");

            Console.WriteLine(" 特殊值“*”匹配所有标签名称");
            XmlNodeList getElementsByTagName2 = xml.GetElementsByTagName("*");
            foreach (XmlNode i in getElementsByTagName2)
            {
                Console.Write("\n getElementsByTagName(*): {0}\n", i.LocalName);
            }
            Console.WriteLine("\n ------------------------------\n");

 

运行结果:

 

 

     Console.WriteLine(" 2.获取第一个按标签匹配到的节点集合");
            //节点标签需要从根节点开始一层一层到当前节点标签
            XmlNodeList selectNodes = xml.SelectNodes("/note/jobs");
            foreach (XmlNode item in selectNodes)
            {
                C("SelectNodes", item.LocalName);
            }

            Console.WriteLine(" 3.选择第一个按标签匹配到的节点");
            //1.节点标签需要从根节点开始一层一层到当前节点标签
            XmlNode selectSingleNode = xml.SelectSingleNode("/note/jobs");
            C("SelectSingleNode", selectSingleNode.LocalName);

            Console.WriteLine(" 4.获取具有指定 ID 的 XmlElement 节点");
            //1.这里的指定 ID,需要再 DTD 中定义属于 ID 类型的属性
            //2.比较麻烦,一般用不上,这里不做演示
            XmlElement getElementById = xml.GetElementById("");

 

运行结果:

 

 

   //新增和添加类方法

            //创建一个新节点
            XmlElement createElement = xml.CreateElement("1.createElement");

            //为指定节点新建属性并赋值
            createElement.SetAttribute("2.setAttribute", "100");

            //不推荐以下为节点添加属性的办法,性能内存不佳,而且麻烦
            //1.创建指定名称的属性
            XmlAttribute createAttribute = xml.CreateAttribute("3.createAttribute");
            //2.设置属性值
            createAttribute.Value = "200";
            //3.为指定节点添加指定的属性
            createElement.SetAttributeNode(createAttribute);

            //为指定节点添加子节点
            //如果存在相同节点,不会覆盖原节点
            rootElement.AppendChild(createElement);

            //创建一个节点
            //1.需要申明 XmlNodeType 和 Name,URI 可以不用申明
            //2.XmlNodeType.Element 类型的节点,就等于是创建一个 XmlElement
            //3.XmlNodeType 是一个枚举类,18种类型节点,所以这是创建节点和创建元素的最大区别
            XmlNode createNode = xml.CreateNode(XmlNodeType.Element, "4.CreateNode", "");
            rootElement.AppendChild(createNode);

            //在当前节点的指定子节点 *前* 插入新节点(XmlNode)
            //1.refChild必须为当前节点的子节点
            //2.newChild可以是xmlNode或者xmlElement
            XmlElement insertBefore = xml.CreateElement("5.InsertBefore");
            XmlNode refChild = xml.SelectSingleNode("/note/jobs");
            rootElement.InsertBefore(insertBefore, refChild);

            //在当前节点的指定子节点 *后* 插入新节点(XmlNode)
            //1.refChild必须为当前节点的子节点
            //2.newChild可以是xmlNode或者xmlElement
            XmlElement insertAfter = xml.CreateElement("6.InsertAfter");
            rootElement.InsertAfter(insertAfter, refChild);

            //将节点从另一个文档导入到当前文档
            //1.importNode节点需要添加进当前的XML节点中,否则不会被添加进去
            //2.不同文档之间无法直接添加对方节点,会报错,需要通过导入节点来添加
            xml2 = new XmlDocument();
            xml2.Load(filePath2);
            XmlNode xml2node = xml2.SelectSingleNode("/xml2/ImportNode");
            //rootElement.AppendChild(xml2node); //此处会报错,提示不同文档
            XmlNode importNode = xml.ImportNode(xml2node, true);
            rootElement.AppendChild(importNode);

 

运行结果:

 

 

   //删改类方法

            //将指定的节点添加到该节点的子节点列表的开头(XmlNode)
            //1.newChild可以是xmlNode或者xmlElement
            refChild.PrependChild(createNode);

            //用新子节点替换旧子节点(XmlNode)
            //1.必须是当前节点的子节点
            XmlElement replaceChild = xml.CreateElement("ReplaceChild");
            rootElement.ReplaceChild(replaceChild, createElement);

            //移除当前节点的子节点(XmlNode)
            //1.被移除的节点必须为当前节点的直接子级,不能是子级的子级
            XmlNode removeChild = xml.SelectSingleNode("/note/jobs");
            rootElement.RemoveChild(removeChild);

            //移除当前节点的所有子节点和属性(XmlNode)
            removeChild.RemoveAll();

            //保存XML文件,如果存在指定文件,则此方法会覆盖它
            xml.Save(filePath);
        }

 

运行结果:

 

标签:XML,xml,Console,string,C#,XmlDocument,WriteLine,XmlNode,节点
来源: https://www.cnblogs.com/cdaniu/p/16151672.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有