• XML概述
     可扩展标记语言 (Extensible Markup Language, XML) ,用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。 XML是标准通用标记语言 (SGML) 的子集,非常适合 Web 传输。XML 提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据。我经常用它来保存一些数据,或者是一些配置参数。
    • XmlElement
     节点元素
    • XmlAttribute

节点属性

    • InnerText
     节点文本内容
  • 类型定义与XML结构的映射
    • XmlElement
     默认情况下(不加任何Attribute),类型中的属性或者字段,都会生成XmlElement。
    • XmlAttribute
     如果希望类型中的属性或者字段生成XmlAttribute,需要在类型的成员上用[XmlAttribute]来指出。 
public class Class2
{
[XmlAttribute]
public int IntValue { get; set; }
[XmlElement]
public string StrValue { get; set; }
}
    • InnerText
     如果希望类型中的属性或者字段生成InnerText,需要在类型的成员上用[XmlText]来指出。 
public class Class3
{
[XmlAttribute]
public int IntValue { get; set; }
[XmlText]
public string StrValue { get; set; }
}
    • 重命名节点名称
     如果希望类型中的属性或者字段生成InnerText,需要在类型的成员上用[XmlText]来指出。
[XmlType("c4")]
public class Class4
{
[XmlAttribute("id")]
public int IntValue { get; set; }
[XmlElement("name")]
public string StrValue { get; set; }
}
    • 列表和数组的序列化
     数组和列表都能直接序列化,如果要重命名根节点名称,需要创建一个新类型来实现。根节点重命名需要用[XmlRoot]来指出。
[XmlRoot("c4List")]
public class Class4List : List<Class4> { }
    • 列表和数组的做为数据成员的序列化
     数组和列表都在序列化时,默认情况下会根据类型中的数据成员名称生成一个节点,列表项会生成子节点,如果要重命名,可以使用[XmlArrayItem]和[XmlArray]来实现。还可以直接用[XmlElement]控制不生成列表的父节点。 
public class Root
{
public Class3 Class3 { get; set; }
[XmlArrayItem("c2")]
[XmlArray("cccccccccccc")]
public List<Class2> List { get; set; }
}
public class Root
{
public Class3 Class3 { get; set; }
[XmlElement("c2")]
public List<Class2> List { get; set; }
}
    • 类型继承与反序列化
     列表元素可以是同一种类型,也可以不是同一种类型(某个类型的派生类)。同时为列表成员指定多个[XmlArrayItem(typeof(XXX))]可实现多种派生类型混在一起输出。 
<?xml version="1.0" encoding="utf-8"?>
<XRoot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<List>
<x1 aa="1" bb="2" />
<x1 aa="3" bb="4" />
<x2>
<cc>ccccccccccc</cc>
<dd>dddddddddddd</dd>
</x2>
</List>
</XRoot>
public class XBase { }
[XmlType("x1")]
public class X1 : XBase
{
[XmlAttribute("aa")]
public int AA { get; set; }
[XmlAttribute("bb")]
public int BB { get; set; }
}
[XmlType("x2")]
public class X2 : XBase
{
[XmlElement("cc")]
public string CC { get; set; } [XmlElement("dd")]
public string DD { get; set; }
}
public class XRoot
{
[XmlArrayItem(typeof(X1)),
XmlArrayItem(typeof(X2))]
public List<XBase> List { get; set; }
}
    • 排除不需要序列化的成员
     默认情况下,类型的所有公开的数据成员(属性,字段)在序列化时都会被输出,如果希望排除某些成员,可以用[XmlIgnore]来指出。
public class TestIgnore
{
[XmlIgnore] // 这个属性将不会参与序列化
public int IntValue { get; set; }
public string StrValue { get; set; }
public string Url;
}
    • 强制指定成员的序列化顺序
     使用Order指定元素的排序。
public class TestIgnore
{
[XmlElement(Order = 1)]
public string StrValue { get; set; }
[XmlElement(Order = 2)]
public string Url;
}
    • 反序列化
     如果XML是由类型序列化得到那的,那么反序列化的调用代码是很简单的,反之,如果要面对一个没有类型的XML,就需要我们先设计一个(或者一些)类型出来,这是一个逆向推导的过程,请参考以下步骤:
  1. 首先要分析整个XML结构,定义与之匹配的类型。
  2. 如果XML结构有嵌套层次,则需要定义多个类型与之匹配。
  3. 定义具体类型(一个层级下的XML结构)时,请参考以下表格。
  • XML数据读写代码示例
     如果只是为了保存和读取数据而不关心xml文件结构的话,可以使用序列化的方式来读写xml,这样做操作相当的简单。
// 1. 首先要创建或者得到一个数据对象
Order order = GetOrderById(123);
// 2. 用序列化的方法生成XML
string xml = XmlHelper.XmlSerialize(order, Encoding.UTF8);
// 3. 从XML读取数据并生成对象
Order order2 = XmlHelper.XmlDeserialize<Order>(xml, Encoding.UTF8);
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.Xml; public static class XmlHelper
{
        /// <summary>
/// 将一个对象序列化
/// </summary>
        private static void XmlSerializeInternal(Stream stream, object o, Encoding encoding)
{
if( o == null )
throw new ArgumentNullException("o");
if( encoding == null )
throw new ArgumentNullException("encoding");
XmlSerializer serializer = new XmlSerializer(o.GetType());
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.NewLineChars = "\r\n";
settings.Encoding = encoding;
settings.IndentChars = " ";
using( XmlWriter writer = XmlWriter.Create(stream, settings) ) {
serializer.Serialize(writer, o);
writer.Close();
}
}
/// <summary>
/// 将一个对象序列化为XML字符串
/// </summary>
/// <param name="o">要序列化的对象</param>
/// <param name="encoding">编码方式</param>
/// <returns>序列化产生的XML字符串</returns>
public static string XmlSerialize(object o, Encoding encoding)
{
using( MemoryStream stream = new MemoryStream() ) {
XmlSerializeInternal(stream, o, encoding);
stream.Position = 0;
using( StreamReader reader = new StreamReader(stream, encoding) ) {
return reader.ReadToEnd();
}
}
}
/// <summary>
/// 将一个对象按XML序列化的方式写入到一个文件
/// </summary>
/// <param name="o">要序列化的对象</param>
/// <param name="path">保存文件路径</param>
/// <param name="encoding">编码方式</param>
public static void XmlSerializeToFile(object o, string path, Encoding encoding)
{
if( string.IsNullOrEmpty(path) )
throw new ArgumentNullException("path");
using( FileStream file = new FileStream(path, FileMode.Create, FileAccess.Write) ) {
XmlSerializeInternal(file, o, encoding);
}
}
/// <summary>
/// 从XML字符串中反序列化对象
/// </summary>
/// <typeparam name="T">结果对象类型</typeparam>
/// <param name="s">包含对象的XML字符串</param>
/// <param name="encoding">编码方式</param>
/// <returns>反序列化得到的对象</returns>
public static T XmlDeserialize<T>(string s, Encoding encoding)
{
if( string.IsNullOrEmpty(s) )
throw new ArgumentNullException("s");
if( encoding == null )
throw new ArgumentNullException("encoding");
XmlSerializer mySerializer = new XmlSerializer(typeof(T));
using( MemoryStream ms = new MemoryStream(encoding.GetBytes(s)) ) {
using( StreamReader sr = new StreamReader(ms, encoding) ) {
return (T)mySerializer.Deserialize(sr);
}
}
}
/// <summary>
/// 读入一个文件,并按XML的方式反序列化对象。
/// </summary>
/// <typeparam name="T">结果对象类型</typeparam>
/// <param name="path">文件路径</param>
/// <param name="encoding">编码方式</param>
/// <returns>反序列化得到的对象</returns>
public static T XmlDeserializeFromFile<T>(string path, Encoding encoding)
{
if( string.IsNullOrEmpty(path) )
throw new ArgumentNullException("path");
if( encoding == null )
throw new ArgumentNullException("encoding");
string xml = File.ReadAllText(path, encoding);
return XmlDeserialize<T>(xml, encoding);
}
}
 
 
 
 
 
 

深度解析XML的结构与类映射的更多相关文章

  1. mybatis 3.x源码深度解析与最佳实践(最完整原创)

    mybatis 3.x源码深度解析与最佳实践 1 环境准备 1.1 mybatis介绍以及框架源码的学习目标 1.2 本系列源码解析的方式 1.3 环境搭建 1.4 从Hello World开始 2 ...

  2. Spark RDD深度解析-RDD计算流程

    Spark RDD深度解析-RDD计算流程 摘要  RDD(Resilient Distributed Datasets)是Spark的核心数据结构,所有数据计算操作均基于该结构进行,包括Spark ...

  3. spring源码深度解析— IOC 之 容器的基本实现

    概述 上一篇我们搭建完Spring源码阅读环境,spring源码深度解析—Spring的整体架构和环境搭建 这篇我们开始真正的阅读Spring的源码,分析spring的源码之前我们先来简单回顾下spr ...

  4. 深度解析Maven

    此文来源于: https://www.cnblogs.com/hafiz/p/8119964.html 带你深度解析Maven   一.What`s Maven? Maven是基于项目对象模型(POM ...

  5. Spring源码深度解析之数据库连接JDBC

    Spring源码深度解析之数据库连接JDBC JDBC(Java Data Base Connectivity,Java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供 ...

  6. Spring源码深度解析之事务

    Spring源码深度解析之事务 目录 一.JDBC方式下的事务使用示例 (1)创建数据表结构 (2)创建对应数据表的PO (3)创建表和实体之间的映射 (4)创建数据操作接口 (5)创建数据操作接口实 ...

  7. Android之解析XML

    1.XML:可扩展标记语言. 可扩展标记语言是一种很像超文本标记语言的标记语言. 它的设计宗旨是传输数据,而不是显示数据. 它的标记没有被预定义.需要自行定义标签. 它被设计为具有自我描述性. 是W3 ...

  8. Android之DOM解析XML

    一.DOM解析方法介绍 DOM是基于树形结构的节点或信息片段的集合,允许开发人员使用DOM API遍历XML树,检索所需数据.分析该结构通常需要加载整个文档和构造树形结构,然后才可以检索和更新节点信息 ...

  9. 用 ElementTree 在 Python 中解析 XML

    用 ElementTree 在 Python 中解析 XML 原文: http://eli.thegreenplace.net/2012/03/15/processing-xml-in-python- ...

随机推荐

  1. IDEA引入spring的命名空间

    我们在写spring的配置文件的时候,有的时候可能会用到 P 标签,然后我们发现自己并没有p标签啊,那么我们一起来看我是怎么解决的. 首先在我们的xml文件的首部添上这句话: xmlns:contex ...

  2. 报错:Maximum call stack size exceeded

    最后通过查看一篇别人的博客,通过对照,发现我把参数值写反了,把参数a的值写成了参数b的值.详情可以看如下博客: https://www.cnblogs.com/dunitian/p/5865725.h ...

  3. 1.1.5 PROB Friday the Thirteenth

    Friday the Thirteenth Is Friday the 13th really an unusual event? That is, does the 13th of the mont ...

  4. Visual Studio 2017 集成Crystal Report为ASP.NET MVC呈现报表

    最近项目需要实现报表功能,平衡各方面的因素,还是使用Crystal Report(水晶报表) 下载较新版本: http://downloads.businessobjects.com/akdlm/cr ...

  5. Java面试集合(四)

    1. jdk,jre,jvm之间的关系 JVM是Java虚拟机,是Java跨平台的重要保障,JVM实现Java跨平台的前提,可以针对不同的操作系统,有不同的JVM. 可以说Java语言是跨平台的,但J ...

  6. Kali学习笔记27:Burpsuite(上)

    文章的格式也许不是很好看,也没有什么合理的顺序 完全是想到什么写一些什么,但各个方面都涵盖到了 能耐下心看的朋友欢迎一起学习,大牛和杠精们请绕道 如果我只能选择一款工具进行Web渗透,那么一定就是Bu ...

  7. navicat连接mysql报错1251的解决方法

    1.新安装的mysql8,使用破解版的navicat连接的时候一直报错,如图所示: 2.网上查找原因发现是mysql8 之前的版本中加密规则是mysql_native_password,而在mysql ...

  8. AI - 框架(Frameworks)

    1 - Scikit-Learn Sklearn(scikit-learn: machine learning in Python):https://scikit-learn.org/ 文档丰富而又详 ...

  9. 机器学习入门03 - 降低损失 (Reducing Loss)

    原文链接:https://developers.google.com/machine-learning/crash-course/reducing-loss/ 为了训练模型,需要一种可降低模型损失的好 ...

  10. 基于Alpha-Beta剪枝的欢乐斗地主残局辅助

    2019年4月17日更新: 将搜索主函数优化为局部记忆化搜索,再次提高若干倍搜索速度 更新了main和player,helper无更新 #include "Player-v3.0.cpp&q ...