C# 处理XML的基本操作
文章部分代码引用参考文章, 文末参考文章已标注 ,本篇文章建立在两篇参考文章基础上,可以先阅读参考文章
XML 相关类
- XDocument
- XmlDocument
- XmlReader XmlWriter
- XNamespace
- XPath
XDocument 和 XmlDocument 这两个类都可以代表 XML 操作对象,可以对XML 内的节点进行操作进行.既然两个都是操作对象,有什么区别呢?
在.NET version 3.0 或是更低 你不得不使用XmlDocument , 而 XDocument 可以结合 LINK TO XML 使用 ,并且在创建XML 时, XD显得更加便捷,看起来更加明朗.见下文创建XML
// 创建一个xml文档 XDocument所属命名空间:using System.Xml.Linq;
XDocument xDoc = new XDocument();
// 添加根节点
XElement xRoot = new XElement("Root");
// 添加节点使用Add
xDoc.Add(xRoot); // 创建一个学生加到root中
// 1、创建学生节点
XElement xStudent = new XElement("Student"); // 2、创建学生姓名、年龄、性别
XElement xName = new XElement("Name");
XElement xAge = new XElement("Age");
XElement xGender = new XElement("Gender"); //给每个元素赋值
xName.Value = "张三";
xAge.Value = "";
xGender.Value = "男"; // 3、添加节点(没有顺序之分)
xStudent.Add(xName, xAge, xGender); //把学生姓名,年龄,性别元素添加到学生节点下
xRoot.Add(xStudent); //把学生节点添加到根节点下 // 为Student添加属性
XAttribute xId = new XAttribute("id", ".Net01");
xStudent.Add(xId); // 保存该文档
xDoc.Save("myxml.xml");
生成的XML
<?xml version="1.0" encoding="utf-8"?>
<Root>
<Student id=".Net01">
<Name>张三</Name>
<Age>19</Age>
<Gender>男</Gender>
</Student>
</Root>
而看一下XDocument 的情况
static void saveXml2()
{
//如果你喜欢这样写的话,那就一级一级阶梯状排列好。很有层次感,看起来特明了
XDocument xDoc = new XDocument(
new XElement("Root",
new XElement("FlyInfo",
new XElement("Sum",
new XElement("AirLine", "航空"),
new XElement("Seat", "经济舱"),
new XElement("Rating", "A"),
new XElement("Gai", "可以改"),
new XElement("Tui", "可以退"),
new XElement("Qian", "可以签"),
new XElement("com",
new XElement("comm", "暂无")
)
)
), new XElement("FlyInfo",
new XElement("Sum",
new XElement("AirLine", "航空"),
new XElement("Seat", "头等舱"),
new XElement("Rating", "R"),
new XElement("Gai", "不可以改"),
new XElement("Tui", "不可以退"),
new XElement("Qian", "不可以签")
)
)
)
); xDoc.Save("Test.xml");
}
生成的XML

增加节点
//XDocument提供了Load()静态方法
XDocument xDoc = XDocument.Load("tableDemo.xml"); //加载xml文档。这里是相对路径
//当你生了个儿子。想上户口簿时,就给其父亲加个儿子节点
XElement xfa = xDoc.Root.Element("FlyInfo"); //找到父亲(FlyInfo是父节点,所属他下面的都是子节点)
XNode xson = xfa.LastNode; //找到最后一个儿子节点 //这里给父亲添加个儿子(在末尾添加的)
xson.AddAfterSelf(
new XElement("son","还没生子") //这里son没有儿子。也就是son节点没有子节点
);
xDoc.Save("tableDemo.xml"); //保存数据 其实总的来说是把全部数据读到内存中然后在内存中追加数据后再全部保存tableDemo.xml
看结果
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Root>
<FlyInfo>
<AirLine>航空</AirLine>
<Seat>经济舱</Seat>
<Rating>A</Rating>
<Gai>可以改</Gai>
<Tui>可以退</Tui>
<Qian>可以签</Qian>
<son>还没生子</son>
</FlyInfo>
</Root>
关于XDocument 对 XML 格式的数据进行操作具体可以点开参考文章进行学习(第一篇文章讲的很详细),下面纪录我在使用XML中遇到的问题。
几种使用场景
Xml 格式数据转化为byte
当Xml需要在网络中传输的时候就需要转化为byte
public static byte[] XMLtoBytes(string cmd,string ver,string id,string ret)
{
XDocument xDoc = new XDocument(
new XElement("msg",
new XElement("header",
new XElement("ack", cmd),
new XElement("ver", ver),
new XElement("id", id)),
new XElement("data",
new XElement("ret", ret),
new XElement("error","must use english"))
) );
byte[] byteArray = System.Text.Encoding.Default.GetBytes(xDoc.ToString());
return byteArray;
}
可以看到只需要调用 XDocument.ToString( ) 就可以转化为string 再转化为 byte[ ] ,当时坑死我了~~~, 当我需要转化回XML数据的时候,只需要
//创建一个内存缓冲区 其大小为1024*1024字节 即1M
byte[] arrServerRecMsg = new byte[ * ];
//将接收到的信息存入到内存缓冲区,并返回其字节数组的长度
int length = SocketCmd.Receive(arrServerRecMsg);
//将机器接受到的字节数组转换为人可以读懂的字符串
string strSRecMsg = Encoding.UTF8.GetString(arrServerRecMsg, , length);
//将发送的字符串信息附加到文本框txtMsg上
Msgtextbox.AppendText("接受到的信息为 :" + "\r\n" + strSRecMsg + "\r\n"); //现在把它解释成xml
XDocument xDocument = XDocument.Parse(strSRecMsg);
这里我是使用Socket接收数据,arrServerRecMsg 即为 xml数据的byte[ ] 数据。当然 XDocument 转为为 string 的方式还有很多种,详见:
Xml 带有XmlDeclaration
例如我需要的数据如下:开头需要
<?xml version="1.0"?>
<?xml version="1.0"?>
<msg>
<header>
<cmd>CON</cmd>
<ver>1.1</ver>
<id>4417</id>
</header>
<data />
</msg>
使用XmlDeclaration
private static XDocument BuildmdXMLTemp(string cmd, string ver, string id)
{ XDocument xDoc = new XDocument(new XDeclaration("1.0", null, null),
new XElement("msg",
new XElement("header",
new XElement("cmd", cmd),
new XElement("ver", ver),
new XElement("id", id)),
new XElement("data",
null)
) );
return xDoc;
}
但是这里有个坑,当我传递XML数据转化为byte[ ]进行传递的时候接收的数据我的XmlDeclaration不见了, 查了“爆栈”(stackoverflow)才知道直接时候XmlDocument.Tostring( )方法是不行的,可以有两种方案:
- XmlDeclaration大坑解决方法
- 使用XmlDocument.Save ( ) ,得到 TextWriter,再将数据转为byte[ ] ,需要注意的是这个方法当我的 XmlDeclaration 中包含 utf-8 有可能会变成 utf-16
<?xml version="1.0" encoding="UTF-8"?>
解决方法:
using (var mem = new MemoryStream())
using (var writer = new XmlTextWriter(mem, System.Text.Encoding.UTF8))
{
writer.Formatting = Formatting.Indented;
doc.WriteTo(writer);
writer.Flush();
mem.Flush();
mem.Seek(0, SeekOrigin.Begin);
using (var reader = new StreamReader(mem))
{
var xml = reader.ReadToEnd();
Console.WriteLine(xml);
}
}
- 另外一种就是
string strXML = string.Concat(xDoc.Declaration.ToString(), "\r\n",
xDoc.ToString());
byte[] bytes = Encoding.Default.GetBytes(strXML);
return bytes;
查找Xml数据中是否有某一节点
假如我不知道msg/header 和 msg/data 根节点中是否有 error 和 errorNum 节点,(如果你有更好的方法可以评论一下,互相学习一下)
IEnumerable<XElement> xmlElements = xDocument.XPathSelectElements("msg/header/error");
IEnumerable<XElement> xmlElementss = xDocument.XPathSelectElements("msg/data/errorNum");
clientTextBox.AppendText(xmlElements.Count().ToString());
if (xmlElements.Any())
{
foreach (XElement element in xmlElements)
{
if (element.Name.ToString().Equals("error"))
{
clientTextBox.AppendText("请求: " + ack + " " + "出现错误: " + element.Value + "\r\n");
}
clientTextBox.AppendText(element.Value.ToString() + "\r\n");
}
}
开始的时候,写成这样会报错,得不到引用
string ret = xDocument.XPathSelectElement("msg/data/errorNum").Value.ToString()
序列化
序列化可看第二篇参考文章,需要指出的是,第二篇文章,XML 使用的使用将XML 数据序列化成对象,这种方法需要一个前提的条件就是当我的数据结构是不变的情况下,例如本文中上一个使用场景,我不知道某个根节点中是否存在某一个节点,那么就无法构建对象了,因为我不知传过来的数据是否会有这个节点,有可能有,也有可能没有,要是这种情况的话,先把Xml数据序列化转为 byte[ ] ,利用XDocument.parse( string data ) 方法,然后再进行判断是否有这个节点.
参考文章 :
C# 处理XML的基本操作的更多相关文章
- xml之基本操作
XML:Extensible Markup Language(可扩展标记语言)的缩写,是用来定义其它语言的一种元语言,其前身是SGML(Standard Generalized Markup Lang ...
- XML的基本操作
所有 XML 文档中的文本均会被解析器解析.只有 CDATA 区段(CDATA section)中的文本会被解析器忽略.CDATA 部分中的所有内容都会被解析器忽略.CDATA 部分由 "& ...
- mybatis配置mapper.xml 的基本操作
XML 映射文件 本文参考mybatis中文官网进行学习总结:http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html MyBatis 的真正强大在于它的 ...
- mybatis(三)配置mapper.xml 的基本操作
参考:https://www.cnblogs.com/wuzhenzhao/p/11101555.html XML 映射文件 本文参考mybatis中文官网进行学习总结:http://www.myba ...
- php xml 的基本操作类
class xmlMessage{ protected $doc; protected $rootKey; public function __construct() { $this->doc ...
- xml基本操作和保存配置文件应用实例
引言:在实际项目中遇到一些关于xml操作的问题,被逼到无路可退的时候终于决定好好研究xml一番.本文首先介绍了xml的基本操作,后面写了一个经常用到的xml保存配置文件的实例. xml常用方法: 定义 ...
- # java对xml文件的基本操作
下面是简单的总结三种常用的java对xml文件的操作 1. dom方式对xml进行操作,这种操作原理是将整个xml文档读入内存总,在内存中进行操作,当xml文档非常庞大的时候就会出现内存溢出的异常,这 ...
- xml基本操作
在实际项目中遇到一些关于xml操作的问题,被逼到无路可退的时候终于决定好好研究xml一番.xml是一种可扩展标记语言,可跨平台进行传输,因此xml被广泛的使用在很多地方. 本文由浅入深,首先就xml的 ...
- LINQ for XML简单示例
LINQ,语言集成查询(Language Integrated Query)是一组用于c#和Visual Basic语言的扩展.它允许开发人员以与查询数据库相同的方式操作内存数据.从技术角度而言,LI ...
随机推荐
- react-dnd使用介绍
核心API 想要灵活使用,就先知道几个核心API DragSource 用于包装你需要拖动的组件,使组件能够被拖拽(make it draggable) DropTarget 用于包装接收拖拽元素的组 ...
- 四、Centos linux系统优化
1. 无论是哪个版本的linux,都会提供32位和64位的两个版本的镜像. i386为32位 x86_64为64位 两者的区别: 1)目标:需要大量的内存需求的行业为64位,普通用户的需求为3 ...
- “全栈2019”Java第十六章:下划线在数字中的意义
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- 《OD大数据实战》环境整理
一.关机后服务重新启动 1. 启动hadoop服务 sbin/hadoop-daemon.sh start namenode sbin/hadoop-daemon.sh start datanode ...
- 洛谷P5050 【模板】多项式多点求值
传送门 人傻常数大.jpg 因为求逆的时候没清零结果调了几个小时-- 前置芝士 多项式除法,多项式求逆 什么?你不会?左转你谷模板区,包教包会 题解 首先我们要知道一个结论\[f(x_0)\equiv ...
- BZOJ3531-[Sdoi2014]旅行(树剖+线段树动态开点)
传送门 完了今天才知道原来线段树的动态开点和主席树是不一样的啊 我们先考虑没有宗教信仰的限制,那么就是一个很明显的树剖+线段树,路径查询最大值以及路径和 然后有了宗教信仰的限制该怎么做呢? 先考虑暴力 ...
- [Objective-C语言教程]数据类型(5)
在Objective-C编程语言中,数据类型是指用于声明不同类型的变量或函数的扩展系统. 变量的类型决定了它在存储中占用的空间大小以及如何解释存储的位模式. Objective-C中的类型可分为以下几 ...
- 二叉树的遍历python 代码
__author__ = "WSX" class Node: def __init__(self, val = None, left = None, right = None): ...
- P4098 [HEOI2013]ALO 可持久化01Trie
$ \color{#0066ff}{ 题目描述 }$ Welcome to ALO ( Arithmetic and Logistic Online).这是一个 VR MMORPG, 如名字所见,到处 ...
- 51nod1847 奇怪的数学题 (Min_25筛+第二类斯特林数)
link \(\sum_{i=1}^n\sum_{j=1}^n\mathrm{sgcd}(i,j)^k=\sum_{p=1}^ns(p)^k\sum_{i=1}^n\sum_{j=1}^n[\gcd( ...