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 ...
随机推荐
- BF、kmp算法
第七周 字符串匹配 BF算法,kmp算法 BF:时间复杂度为 O(m*n) int Index_BF(SString S, SString T, int pos) { ; while (i <= ...
- leecode刷题(8)-- 两数之和
leecode刷题(8)-- 两数之和 两数之和 描述: 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输 ...
- [Swift实际操作]八、实用进阶-(5)通过间接代理进行对象间的消息传递
本文将为你演示,如何通过简介代理的方式,进行对象间的消息传递在左侧的项目导航区,打开自定义视图的代码文件(CustomView.swift). import UIKit class CustomVie ...
- svn命令行的使用
只是说一下,svn平时工作时常用的命令 1.svn delete 目录 删除svn版本里的相关目录 2.svn add 目录 将本地的目录添加到svn版本信息里 3.svn commit 目录 提交s ...
- weex 编译vue成js
cd 项目 1.开发 npm run web 开发过程中可以直接使用浏览器运行 npm run ios 2.打包 npm run build 会在 dist 文件夹 中生成js文件, 即可拖入ios ...
- php post get 繁体、日文、韩文时 自动添加 反斜杠 问题
做些二次开发项目,数据库.文件编码没法大规模的修改,比如二次开发一个日文系统,编码是JA16SJIS,$_POST或$_GET的信息中如果“申請”,得到的信息就会变成“申\請”,多出一个反斜杠! 先贴 ...
- Hangfire项目
什么是Hangfire Hangfire 是一个开源的.NET任务调度框架,目前1.6+版本已支持.NET Core.个人认为它最大特点在于内置提供集成化的控制台,方便后台查看及监控: 另外,Hang ...
- 解决视图状态消息验证代码 (MAC) 错误
https://blog.csdn.net/bingtingabc/article/details/49148745 2015年10月15日 10:05:56 bingtingabc 阅读数:3397 ...
- 《Paxos Made Simple》翻译(转)
1 Introduction 可能是因为之前的描述对大多数读者来说太过Greek了,Paxos作为一种实现容错的分布式系统的算法被认为是难以理解的.但事实上,它可能是最简单,最显而易见的分布式算法了. ...
- c# 线程,同步,锁
最近在阅读<c#高级编程> 这本书.记录一下关于锁的使用 大致分为三种方法: 方法1:使用 lock 方法2:使用 Interlocked 方法3:使用 Monitor using Sys ...