【C#】创建、解析 xml 文件(XmlDocument 方式)

【C#】创建、解析 xml 文件(XmlDocument 方式)前言本文使用System.Xml中的XmlDocument解析xml格式的文件。另外,由于我是粗略的看了下官方文档和一些博客,可能会有许多错误的地方,望指出。官方文档:https://docs.microsoft.com/zh-cn/dotnet/api/system.xml.xmldocument?view=netframework-4.8文章时间:写于2019-7-17…

大家好,又见面了,我是你们的朋友全栈君。

前言

本文使用 System.Xml 中的 XmlDocument 解析 xml 格式的文件。另外,由于我是粗略的看了下官方文档和一些博客,可能会有许多错误的地方,望指出。

官方文档:https://docs.microsoft.com/zh-cn/dotnet/api/system.xml.xmldocument?view=netframework-4.8

文章时间:

  • 写于 2019-7-17

1 创建 Xml

XmlDocument tDoc = new XmlDocument();

// 一些声明信息
XmlDeclaration xmlDecl = tDoc.CreateXmlDeclaration("1.0", "utf-8", null);
tDoc.AppendChild(xmlDecl);

// 新建根节点
XmlElement root = tDoc.CreateElement("root");
tDoc.AppendChild(root);

// root 下的子节点
XmlElement toTalTick = tDoc.CreateElement("TotalTick");
toTalTick.InnerText = "10";
root.AppendChild(toTalTick); //注意这里是 root.AppendChild

// root 下的子节点
XmlElement demension = tDoc.CreateElement("Demension");
demension.InnerText = "2";
root.AppendChild(demension);

// root 下的子节点
XmlElement tickLine = tDoc.CreateElement("TickLine");
root.AppendChild(tickLine);

for(int i = 0; i < 10; i++)
{
    // TickLine 下的子节点 Tick
    XmlElement tick = tDoc.CreateElement("Tick");

    // 给 Tick 增加属性值
    XmlAttribute attr = tDoc.CreateAttribute("Value");
    attr.Value = i.ToString();
    tick.Attributes.Append(attr);
    tickLine.AppendChild(tick);
}

// 保存
tDoc.Save("data.xml");

上面的程序将生成一个这样一个 xml 格式的文件

<?xml version="1.0" encoding="utf-8"?>
<root>
  <TotalTick>10</TotalTick>
  <Demension>2</Demension>
  <TickLine>
    <Tick Value="0" />
    <Tick Value="1" />
    <Tick Value="2" />
    <Tick Value="3" />
    <Tick Value="4" />
    <Tick Value="5" />
    <Tick Value="6" />
    <Tick Value="7" />
    <Tick Value="8" />
    <Tick Value="9" />
  </TickLine>
</root>

输出格式好像不是很舒服,我习惯是 4 个空格缩进,可以通过以下方式保存,控制格式

//同上...

XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = System.Text.Encoding.UTF8; //默认其实就是 UTF-8 这里记下怎么写
settings.Indent = true; //需要缩进元素
settings.IndentChars = "    "; //使用 四个空格 缩进

XmlWriter writer = XmlWriter.Create("data.xml", settings);
tDoc.Save(writer);

更多有关信息,可看 XmlWriterSettings 这样就可以得到我习惯的格式了,另外 Save 会覆盖原来的文件

<?xml version="1.0" encoding="utf-8"?>
<root>
    <TotalTick>10</TotalTick>
    <Demension>2</Demension>
    <TickLine>
        <Tick Value="0" />
        <Tick Value="1" />
        <Tick Value="2" />
        <Tick Value="3" />
        <Tick Value="4" />
        <Tick Value="5" />
        <Tick Value="6" />
        <Tick Value="7" />
        <Tick Value="8" />
        <Tick Value="9" />
    </TickLine>
</root>

2 解析 Xml

若已知一个这样的 xml 文档(省略了一些不重要的部分)

<?xml version="1.0" encoding="utf-8"?>
<root>
    <TotalTick>10</TotalTick>
    <Demension>2</Demension>
    <TickLine>
        <Tick Value="0">
            <Person id="0" x="0" y="0" z="0" />
            <Person id="1" x="0" y="0" z="1" />
            <Person id="2" x="0" y="0" z="2" />
            <Person id="3" x="0" y="0" z="3" />
            <Person id="4" x="0" y="0" z="4" />
        </Tick>
        <Tick Value="1">
            ...
            ...
        </Tick>
        ...
        ...
    </TickLine>
</root>

2.1 定位单个节点

已经知道节点的名字,如何获取值呢,如果同名节点很多怎么办?

2.1.1 方式一

通过 XmlNodeSelectSingleNode 方法定位到指定节点

// XmlDocument x = new XmlDocument();
// ...
XmlNode root = x.DocumentElement;
XmlNode e = root.SelectSingleNode("TotalTick");
Console.WriteLine(e.InnerText);

需要注意的是,这个方法传入的是 XPath,建议看一下 XPath示例,这里就不再展开讲,通过 XPath,查找元素不担心!

举个例子:

XmlNode e = root.SelectSingleNode("TickLine/Tick[@Value = '1']");

这样就定位到了 root 的子节点 TickLine 的其属性 Value 值为 1 的 Tick 子节点

2.1.2 方式二(操作符[]定位)

没有仔细研究过,看下面的示例

// XmlDocument x = new XmlDocument();
// ...
XmlNode root = x.DocumentElement;
XmlNode e = root["TotalTick"];
Console.WriteLine(e.InnerText);

2.2 获取节点列表

和 2.1 的方式一类似,使用 XmlNodeSelectNodes 方法

// XmlDocument x = new XmlDocument();
// ...
XmlNode root = x.DocumentElement;
XmlNodeList tickList = root.SelectNodes("TickLine/Tick");
foreach(XmlNode tick in tickList)
{
    foreach(XmlNode person in tick)
    {
        Console.WriteLine(person.OuterXml);
    }
}

2.3 获取节点属性值

我想获取 Tick 的属性 Value = 1 的节点,并输出其中所有 Person 的属性

2.3.1 方式一

使用 XmlNamedNodeMapGetNameItem 方法

// XmlDocument x = new XmlDocument();
// ...
int n = 1;
XmlNode root = x.DocumentElement;
XmlNode tick = root.SelectSingleNode($"TickLine/Tick[@Value = '{n}']");
foreach(XmlNode person in tick)
{
    XmlAttribute attr1 = (XmlAttribute)person.Attributes.GetNamedItem("id");
    XmlAttribute attr2 = (XmlAttribute)person.Attributes.GetNamedItem("x");
    XmlAttribute attr3 = (XmlAttribute)person.Attributes.GetNamedItem("z");
    Console.WriteLine($"{attr1.Value}, {attr2.Value}, {attr3.Value}");
}

注解:XmlNode.Attributes 返回一个 XmlAttributeCollection,然后再使用 GetNameItem(返回 XmlNode

另注继承关系:

  • Object -> XmlNamedNodeMap -> XmlAttributeCollection
  • Object -> XmlNode -> XmlAttribute

2.3.2 方式二

使用 XmlElementGetAttribute 方法

// XmlDocument x = new XmlDocument();
// ...
int n = 1;
XmlNode root = x.DocumentElement;
XmlNode tick = root.SelectSingleNode($"TickLine/Tick[@Value = '{n}']");
foreach(XmlNode person in tick)
{
    XmlElement tmp = (XmlElement)person;
    Console.WriteLine($"{tmp.GetAttribute("id")}, {tmp.GetAttribute("x")}, {tmp.GetAttribute("z")}"));
}

注意,GetAttribute 返回的是字符串 string,如果要获取 XmlAttribute,可使用 GetAttributeNode

另注继承关系:Object -> XmlNode -> XmlLinkedNode -> XmlElement


小结

暂时写这么多吧,常用的写在这里,以后如果有需要再补充

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/150746.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • SpringBoot集成Eurake、Gateway和Redis+Token验证拦截器实现

    SpringBoot集成Eurake、Gateway和Redis+Token验证拦截器实现SpringBoot聚合项目配置Eurake和Gateway一、版本信息:SpringBoot <version>2.2.6.RELEASE</version>SpringCloud <spring-cloud.version>Hoxton.SR1</spring-cloud.version>二、开始配置一个聚合项目1.先建一个父级工程:最终pom.xml配置如下:<?xmlversion=”1.0″encodin

    2022年5月29日
    34
  • Python判断文件、文件夹是否存在,不存在则创建

    Python判断文件、文件夹是否存在,不存在则创建本文仅供学习交流使用,如侵立删!联系方式及demo下载见文末判断文件是否存在,不存在则创建#判断文件是否存在不存在则创建一个ifnotos.path.isfile(filename):fd=open(filename,mode=”w”,encoding=”utf-8″)fd.close()判断文件夹是否存在,不存在则创建#判断文件夹是否存在,不存在则创建一个ifnotos.path.exists(path):os.mkdir(p

    2022年6月25日
    50
  • intellij idea破解2019(2019年科目二考试全过程视频)

    本来看网上已经有写的不错的教程,结果用起来的时候发现有一些问题,首先是版本号的问题,另外是文件路径问题,还有就是碰到的修改hosts没有权限问题,还是想着记录一下,方便需要的童鞋使用。如果发现什么问题,请及时联系我。本文参考自:https://www.jianshu.com/p/3c87487e7121https://blog.csdn.net/qq_17213067/article/de…

    2022年4月16日
    41
  • 获取Google音乐的具体信息(方便对Google音乐批量下载)

    获取Google音乐的具体信息(方便对Google音乐批量下载)

    2021年12月14日
    58
  • PL/SQL Developer下载安装及使用[通俗易懂]

    PL/SQL Developer下载安装及使用[通俗易懂]PL/SQLDeveloper下载安装及使用前言PL/SQLDeveloper是什么PL/SQLDeveloper下载PL/SQLDeveloper安装PL/SQLDeveloper使用PL/SQLDeveloper汉化PL/SQLDeveloper修改字体PL/SQLDeveloper编写SQL代码PL/SQLDeveloper连接远程服务器前言古语说的好,工欲善其事必先利其器。在开发中我们乜需要熟悉各种开发工具、数据库集成开发工具、等其他工具的使用。因为笔者在公司所使用的是or

    2022年10月12日
    0
  • 关于Java向上取整和向下取整(天花板函数)的说明

    关于Java向上取整和向下取整(天花板函数)的说明背景项目应用后期纪要!问题1.小数参数如何向上取整?2.小数参数如何向下取整?说明向上或向下取整的问题只针对小数类型的数据,在Java中主要用来处理double类型或float类型的数据。纪要函数是Math类下的基础函数,操作较为简单,比较容易上手。下面是随笔的Demo,以供参考:packagecom.company.num;/***天花板函数*用例主要说明两个函数*…

    2022年6月21日
    37

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号