文章部分代码引用参考文章, 文末参考文章已标注 ,本篇文章建立在两篇参考文章基础上,可以先阅读参考文章

XML 相关类

  • XDocument
  • XmlDocument
  • XmlReader  XmlWriter
  • XNamespace
  • XPath

  XDocument 和 XmlDocument 这两个类都可以代表 XML 操作对象,可以对XML 内的节点进行操作进行.既然两个都是操作对象,有什么区别呢?

  XmlDocument 和 XDocument的区别

  在.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 的方式还有很多种,详见:

    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 ) 方法,然后再进行判断是否有这个节点.

 

参考文章 :

XDocument 简单入门

XML序列化

C# 处理XML的基本操作的更多相关文章

  1. xml之基本操作

    XML:Extensible Markup Language(可扩展标记语言)的缩写,是用来定义其它语言的一种元语言,其前身是SGML(Standard Generalized Markup Lang ...

  2. XML的基本操作

    所有 XML 文档中的文本均会被解析器解析.只有 CDATA 区段(CDATA section)中的文本会被解析器忽略.CDATA 部分中的所有内容都会被解析器忽略.CDATA 部分由 "& ...

  3. mybatis配置mapper.xml 的基本操作

    XML 映射文件 本文参考mybatis中文官网进行学习总结:http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html MyBatis 的真正强大在于它的 ...

  4. mybatis(三)配置mapper.xml 的基本操作

    参考:https://www.cnblogs.com/wuzhenzhao/p/11101555.html XML 映射文件 本文参考mybatis中文官网进行学习总结:http://www.myba ...

  5. php xml 的基本操作类

    class xmlMessage{ protected $doc; protected $rootKey; public function __construct() { $this->doc ...

  6. xml基本操作和保存配置文件应用实例

    引言:在实际项目中遇到一些关于xml操作的问题,被逼到无路可退的时候终于决定好好研究xml一番.本文首先介绍了xml的基本操作,后面写了一个经常用到的xml保存配置文件的实例. xml常用方法: 定义 ...

  7. # java对xml文件的基本操作

    下面是简单的总结三种常用的java对xml文件的操作 1. dom方式对xml进行操作,这种操作原理是将整个xml文档读入内存总,在内存中进行操作,当xml文档非常庞大的时候就会出现内存溢出的异常,这 ...

  8. xml基本操作

    在实际项目中遇到一些关于xml操作的问题,被逼到无路可退的时候终于决定好好研究xml一番.xml是一种可扩展标记语言,可跨平台进行传输,因此xml被广泛的使用在很多地方. 本文由浅入深,首先就xml的 ...

  9. LINQ for XML简单示例

    LINQ,语言集成查询(Language Integrated Query)是一组用于c#和Visual Basic语言的扩展.它允许开发人员以与查询数据库相同的方式操作内存数据.从技术角度而言,LI ...

随机推荐

  1. leetcode 19. 删除链表的倒数第N个节点 JAVA

    题目: 给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点. 示例: 给定一个链表: 1->2->3->4->5, 和 n = 2. 当删除了倒数第二个节点后,链 ...

  2. 2.iptables 匹配条件(基础)

    基本匹配条件 -s 用于匹配报文的源地址,可以同时指定多个源地址,每个IP地址用逗号分开,也可以指定网段 iptables -t filter -I INPUT -s 192.168.1.111,19 ...

  3. JQuery的基本用法总结

    1.jquery概念 是js的一个类库    (对js中某些功能的封装) 用jq实现的功能一定能用js实现 反过来 不一定  ,js实现的功能jq不一定能实现 2.jquery好处 1.代码简洁 2. ...

  4. jquery源码解析:jQuery延迟对象Deferred(工具方法)详解1

    请先看上一课的回调对象.Deferred是通过extend添加到jQuery中的工具方法.如下所示: jQuery.extend({ Deferred: function( func ) { }, w ...

  5. Android app ADB命令

    * 查看设备 adb devices ps这个命令是查看当前连接的设备, 连接到计算机的android设备或者模拟器将会列出显示 若有多台安卓设备,可以通过在adb后面加上 -s <设备id&g ...

  6. windows系统作为客户端时,linux中本地yum源挂载时,如何同时挂载DVD1和DVD2?

    这里以CentOS6.5为例.他的镜像有两个DVD1和DVD2.DVD1中是系统和主要的安装包,DVD2中是剩下的安装包 当挂载时如果要同时挂载DVD1和DVD2.需要这样做: 1)在虚拟机的设置中选 ...

  7. ReactNative之坑:停在gradle一直出点

    问题: 初次安装好React Native 环境后,运行项目,会停留在下载 gradle 的界面一直出点 原因: 下载gradle一直不成功 解决方案: 可以根据提示的版本信息,手动下载,放在目录中, ...

  8. WeakHashMap源码分析

    WeakHashMap是一种弱引用map,内部的key会存储为弱引用, 当jvm gc的时候,如果这些key没有强引用存在的话,会被gc回收掉, 下一次当我们操作map的时候会把对应的Entry整个删 ...

  9. Q767 重构字符串

    给定一个字符串S,检查是否能重新排布其中的字母,使得两相邻的字符不同. 若可行,输出任意可行的结果.若不可行,返回空字符串. 示例 1: 输入: S = "aab" 输出: &qu ...

  10. thinkphp5.1的安装

    首先,下载composer.建议选择全屏安装.参考资料https://docs.phpcomposer.com/00-intro.html.安装到c盘.这个跟之前nodejs一样,都是装c盘.大概是全 ...