• 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. python学习,excel操作之xlsxwriter常用操作

    from datetime import datetime import xlsxwriter #打开文件 workbook = xlsxwriter.Workbook('Expenses03.xls ...

  2. xmlhttprequest readyState 属性的五种状态

    关于readystate五个状态总结如下: readyState 状态    状态说明(0)未初始化此阶段确认XMLHttpRequest对象是否创建,并为调用open()方法进行未初始化作好准备.值 ...

  3. G++与C++的区别

    C++是一门计算机编程语言,G++不是语言,是一款编译器中编译C++程序的命令而已. 不同的编译器,会对代码做出一些不同的优化 比如说: a++;  和 ++a; 如果从标准C的角度去理解.a++这个 ...

  4. Exp4 恶意代码分析 ——20164325王晓蕊

    1.实践目标 监控你自己系统的运行状态,看有没有可疑的程序在运行. 分析一个恶意软件,就分析Exp2或Exp3中生成后门软件:分析工具尽量使用原生指令或sysinternals,systracer套件 ...

  5. Tinkoff Challenge - Final Round (Codeforces Round #414, rated, Div. 1 + Div. 2)

    A: 思路:就是找b,c之前有多个s[i] 代码: #include<stdio.h>#define ll long longusing namespace std;ll a,b,c;in ...

  6. datepart in ssis

    "\\\\"+_"+ (DT_STR,4,1252)DATEPART( "yyyy" , @[System::StartTime] ) + RIGHT ...

  7. [转]CSS clear both清除浮动

    DIV+CSS clear both清除产生浮动 我们知道有时使用了css float浮动会产生css浮动,这个时候就需要清理清除浮动,我们就用clear样式属性即可实现. 接下来我们来认识与学习cs ...

  8. Docker学习笔记-Docker for Linux 安装

    前言: 环境:centos7.5 64 位 正文: Docker 软件包已经包括在默认的 CentOS-Extras 软件源里.因此想要安装 docker,只需要运行下面的 yum 命令: yum i ...

  9. 全栈开发工程师微信小程序-上(下)

    全栈开发工程师微信小程序-上(下) icon 图标 success, success_no_circle, info, warn, waiting, cancel, download, search, ...

  10. Java面试集合(七)

    前言: Java面试集合(六) 的回顾,对于final可以修饰常量,方法,和类,一旦常量定义好后就不可改变,而方法,用final来修饰方法,方法不可重载,继承,重写,final用来修饰类,该类不能被继 ...