C#中对XML的访问提供了序列化、流式非缓存和XML模型缓存三种方式。这三种方式在不同的场合各有特点。
(1) 序列化XmlSerializer类
这个类将对象序列化到XmlWriter、TextWriter或Stream中,或者从XmlReader、TextReader或Stream中,反系列化后生成对象。
假定有对象
public class TestObject
{
[XmlAttribute]
public int a { get; set; }
public string b { get; set; }
}
对这个对象的序列化代码是
TestObject o = new TestObject { a = 1, b = "abc" };
XmlTextWriter writer = null;
writer = new XmlTextWriter(filename, Encoding.UTF8);
writer.Formatting = Formatting.Indented;
XmlSerializer serializer = new XmlSerializer(typeof(TestObject));
serializer.Serialize(writer, o);
writer.Close();
生成的XML文件是
<?xml version="1.0" encoding="UTF-8"?>
<TestObject a="1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<b>abc</b>
</TestObject>
这里由于属性a加了XmlAttribute修饰,因此作为对象TestObject的属性,而属性b未加修饰,因此是TestObject的子节点。
对象的反序列代码是
XmlTextReader reader = null;
reader = new XmlTextReader(filename);
XmlSerializer serializer = new XmlSerializer(typeof(TestObject));
TestObject t = (TestObject)serializer.Deserialize(reader);
XmlSerializer对象参考链接:https://msdn.microsoft.com/zh-cn/library/system.xml.serialization.xmlserializer(v=vs.110).aspx
(2) 使用XDocument 类进行缓存访问
XDocument对象是在内存中建立先XML结构关系的模型。这个模型只有一个XElement节点,即根节点,XElement节点可以有子节点(XElement)和属性(XAttribute)。然后可以将这个XDocument写入XmlWriter、TextWriter、Stream或String。
建立XDocument和写入XML的代码
XElement root = new XElement("TestObject");
root.SetAttributeValue("a", o.a);
root.SetElementValue("b", o.b);
XDocument doc = new XDocument(root);
XmlTextWriter writer = null;
writer = new XmlTextWriter(filename, Encoding.UTF8);
writer.Formatting = Formatting.Indented;
doc.WriteTo(writer);
writer.Close();
读取的时候,是从XmlReader、TextReader、Stream或String中读取生成XDocument对象,然后由用户解读XDocument生成对应的对象。
代码示例
XmlTextReader reader = new XmlTextReader(filename);
XDocument doc = XDocument.Load(reader);
TestObject t = new TestObject();
XElement root = doc.Root;
t.a = (int)root.Attribute("a");
t.b = (string)root.Element("b");
XDocument的对象参考链接:https://msdn.microsoft.com/zh-cn/library/system.xml.linq.xdocument(v=vs.110).aspx
(3) 使用XmlWriter/XmlReader进行非缓存访问
这个类是非缓存的将Xml片段写到流中,或者从流中读取Xml的片段。由用户完全控制写入和读取的操作。
https://msdn.microsoft.com/zh-cn/library/system.xml.xmlreader(v=vs.110).aspx
https://msdn.microsoft.com/zh-cn/library/system.xml.xmlwriter(v=vs.110).aspx
这三种方式中,序列化方法是代码效率最高,也最缺乏灵活性的。用户能够控制Xml输入和输出的手段比较有限。XmlSerializer类会选择对象的全部public、可以读写(get/set)属性(property)进行序列化。系列化过程中,可以使用XmlAttributeAttribute、XmlElementAttribute、XmlIgnoreAttribute等修饰属性,以控制序列化和反序列化的结果。
这种方法比较适用在以数据为中心的类中,与Xml的转换不需要复杂逻辑的场合,例如将某种数据对象序列化后通过网络传递。
XDocument与XmlWriter/XmlReader这两种方式都适用在需要对XML数据进行强控制的场合。例如,由于软件版本升级,需要对原有版本提供兼容支持的;或是需要根据读取的对象,完成很多初始化操作的;或不能将对象数据直接写入XML,而是要进行计算的。
这两种方式的区别在于,XDocument是缓存的方式,先在内存中建立了完整的Xml对象模型,然后再进行处理;而XmlWriter/XmlReader是非缓存的,以流的方式对Xml进行处理。
缓存方式适用在小型Xml文档的处理、需要根据Xml模型查询统计的,或是处理某个XML片段的。
非缓存的方式一般适用在大型Xml文档的处理。