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 ...
随机推荐
- 线程概要 Java
线程 进程和线程的区别 串行:初期的计算机只能串行执行任务,大量时间等待用户输入 批处理:预先将用户的指令集中成清单,批量串行处理用户指令,仍然无法并发执行 进程:进程独占内存空间,保存各自运行状态, ...
- Public Bike Management (30)(DFS,VRCTOR,模拟)(PAT甲级)
#include<bits/stdc++.h>using namespace std;const int inf = 1e9;int sum,n,tar,m;int num[507];in ...
- WEB新手之do u know caidao?
继续写题. 进入该网站,可以看到显然题目给出了一个假的flag.再看第二句话,说题目里存在shell.于是用御剑扫描一下后台. 如上图所示,扫出了一个叫shell的包.于是常识性地在URL加上shel ...
- 解决winform datagridview的ClearSelection无效问题
因为把方法放在了界面的构造方法里,此时datagridview还没绘制出来,所以ClearSelection方法无效,放在control或form的load方法里就没问题了 参考:https://ww ...
- 关于word转化成xml,图片的转换
当word另存为xml的时候,其中的图片会以Base64编码形式展示在xml文件的特定位置, java中操作图片转换成64位编码的方式: 可将返回的64直接放在前面的未知即可:
- PyQt5(2)——调整布局(布局管理器)第一个程序
我们拖拽一个UI文件,转为PY文件后生成一个类Ui_MainWindow 此时,我们新建一个文件,用来控制业务逻辑(继承界面中的类),跟界面分开,这样我们就完成了界面和逻辑相分离(这段代码使用率基本1 ...
- fastcgi main
main函数里 当kill -TERM pid 时, http://redfoxli.github.io/php-fpm-signals.html 这篇文章 说是 1)master主进程接收到sig ...
- MySQL压缩版Windows环境进行安装配置
MySQL下载地址:https://dev.mysql.com/downloads/mysql/ 选择对应的系统和相应的版本后点击Download进入下载页面,不需要登录,点击下面的“No thank ...
- Kamailio
http://www.kamailio.org/wiki/cookbooks/4.1.x/core IMS 支持接口 MSC接口,信令:ISUP over IP和SIP, 用户面: rtp协议 PCR ...
- Linux串口驱动程序设计
1. 在Linux系统中,终端是一类字符型设备,它包括多种类型,通常使用tty来简称各种类型的终端设备. (1)串口终端(/dev/ttyS*):串口终端是使用计算机串口连接的终端设备.Linux把每 ...