• 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. MATLAB2016a安装破解教程

    首先,下载软件:下面是某博主的分享,可以下载软件. 链接:https://pan.baidu.com/s/1i6BgD8p       密码:17gg  第一步:安装软件 1,下载文件,得到R2016 ...

  2. Android开发者的Anko使用指南(三)之资源

    添加依赖 dependencies { compile "org.jetbrains.anko:anko-commons:$anko_version" } Color 0xff00 ...

  3. ORACLE知识点总结

    一.ORACEL常用命令 1.解锁账户:ALTER USER username ACCOUNT UNLOCK; 2.查看数据库字符集:SELECT USERENV ('language') FROM ...

  4. Android学习笔记(2):build.grandle的常用设置

    1 > java开发中有两个大名鼎鼎的项目构建ANT.Maven. 2 > Google推荐使用的Android Studio是采用Gradle来构建项目的.Gradle是一个非常先进的项 ...

  5. 最强大的跨语言调用生成工具:Swig 快速实用教程

    swig是一个生成其他高级语言调用c和C++代码的工具,比如,大家都知道java的jni,可能没写过,因为非常麻烦,swig可以帮助生成这样的代码,编译生成的代码后,它会生成java类和c代码文件.分 ...

  6. 2018年1月20日上海MVP线下技术分享会纪实

    1月20日正值大寒节气,在微软MVP朱兴亮的组织牵头下,上海MVP自发举办了题为<跟社区专家一起聊聊混合云.领域驱动.区块链和数字营销>的技术交流会.四名来自上海的MVP分别在自己擅长的技 ...

  7. 背水一战 Windows 10 (105) - 通知(Toast): 带按钮的 toast, 带输入的 toast(文本输入框,下拉选择框)

    [源码下载] 背水一战 Windows 10 (105) - 通知(Toast): 带按钮的 toast, 带输入的 toast(文本输入框,下拉选择框) 作者:webabcd 介绍背水一战 Wind ...

  8. MySQL优化技巧

    目录 MySQL的特点 数据类型优化 整型类型 小数类型 字符串类型 时间类型 主键类型的选择 特殊类型的数据 索引优化 一个使用Hash值创建索引的技巧 前缀索引 多列索引 聚簇索引 覆盖索引 重复 ...

  9. ReentrantReadWriteLock 读写锁解析

    4 java中锁是个很重要的概念,当然这里的前提是你会涉及并发编程. 除了语言提供的锁关键字 synchronized和volatile之外,jdk还有其他多种实用的锁. 不过这些锁大多都是基于AQS ...

  10. 机器学习入门01 - 框架处理(Framing)

    原文链接:https://developers.google.com/machine-learning/crash-course/framing (监督式)机器学习的定义:机器学习系统通过学习如何组合 ...