我有一个具有以下结构的XML响应:
<Response>
<Block id="1">
<Some_Data_1><Some_Data_1>
<Some_Data_2><Some_Data_2>
</Block>
<Block id="2">
<Another_Data_3><Another_Data_3>
<Another_Data_4><Another_Data_4>
<Another_Data_5><Another_Data_5>
</Block>
<Block id="3">
...
</Block>
</Response>
我需要以最快的方式将每个块反序列化为单独的对象。 到目前为止,我想出了使用 LINQ 手动搜索每个块,并分别反序列化每个块,如下所示:
var Xblock1 = root.Elements("Block").FirstOrDefault(e => e.Attribute("id")?.Value == "1");
Block1 block1 = (Block1)(serializer.Deserialize(Xblock1.CreateReader()));
但我相信有更优化的方法可以做到这一点。
感谢您的时间
XML 序列化速度很慢,需要类和属性名称。相反,我推荐Xml Linq,它的速度要快得多,并且不需要预定义的属性名称
。using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = @"c:temptest.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
Dictionary<int, Dictionary<string, string>> dict = doc.Descendants("Block")
.GroupBy(x => (int)x.Attribute("id"), y => y.Elements()
.GroupBy(a => a.Name.LocalName, b => (string)b)
.ToDictionary(a => a.Key, b => b.FirstOrDefault()))
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
}
}
}
第一种方法是使用序列化,第二种方法是从@jdweng答案中复制。
如前所述,使用Serialize
的方法要慢得多!
对于第一种方法,您还需要一个由 XSD 生成的类.EXE我在此答案末尾链接了该类。
static void Main(string[] args)
{
DateTime start;
start = DateTime.Now;
XmlSerializer ser2 = new XmlSerializer(typeof(Response));
FileStream f = new FileStream(FILENAME, FileMode.Open);
Response response = ser2.Deserialize(f) as Response;
foreach (var item in response.Block)
{
Console.WriteLine(item.id);
}
f.Close();
Console.WriteLine("Method 1: {0}", ((DateTime.Now - start).TotalMilliseconds / 1000));
start = DateTime.Now;
XDocument doc = XDocument.Load(FILENAME);
Dictionary<int, Dictionary<string, string>> dict = doc.Descendants("Block")
.GroupBy(x => (int)x.Attribute("id"), y => y.Elements()
.GroupBy(a => a.Name.LocalName, b => (string)b)
.ToDictionary(a => a.Key, b => b.FirstOrDefault()))
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
foreach (var item in dict.Keys)
{
Console.WriteLine(item);
}
Console.WriteLine("Method 2: {0}", ((DateTime.Now - start).TotalMilliseconds / 1000));
Console.ReadLine();
}
输出:
1
2
3
Method 1: 0,0759927
1
2
3
Method 2: 0,0030262
下面的codde是由XSD.EXE /c file.xsd
生成的,所以你应该从你的XML创建一个XSD(Visual Studio可以为你做(:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System.Xml.Serialization;
//
// This source code was auto-generated by xsd, Version=4.8.3928.0.
//
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3928.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class Response {
private ResponseBlock[] blockField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("Block")]
public ResponseBlock[] Block {
get {
return this.blockField;
}
set {
this.blockField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3928.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class ResponseBlock {
private string another_Data_3Field;
private string another_Data_4Field;
private string another_Data_5Field;
private string some_Data_1Field;
private string some_Data_2Field;
private string[] textField;
private byte idField;
/// <remarks/>
public string Another_Data_3 {
get {
return this.another_Data_3Field;
}
set {
this.another_Data_3Field = value;
}
}
/// <remarks/>
public string Another_Data_4 {
get {
return this.another_Data_4Field;
}
set {
this.another_Data_4Field = value;
}
}
/// <remarks/>
public string Another_Data_5 {
get {
return this.another_Data_5Field;
}
set {
this.another_Data_5Field = value;
}
}
/// <remarks/>
public string Some_Data_1 {
get {
return this.some_Data_1Field;
}
set {
this.some_Data_1Field = value;
}
}
/// <remarks/>
public string Some_Data_2 {
get {
return this.some_Data_2Field;
}
set {
this.some_Data_2Field = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTextAttribute()]
public string[] Text {
get {
return this.textField;
}
set {
this.textField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public byte id {
get {
return this.idField;
}
set {
this.idField = value;
}
}
}