Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在c语言中使用名称相同但属性和结构不同的元素反序列化XML#_C#_Xml_Deserialization_Xml Deserialization - Fatal编程技术网

C# 如何在c语言中使用名称相同但属性和结构不同的元素反序列化XML#

C# 如何在c语言中使用名称相同但属性和结构不同的元素反序列化XML#,c#,xml,deserialization,xml-deserialization,C#,Xml,Deserialization,Xml Deserialization,我有一个具有以下结构的XML响应: <Response> <Block id="1"> <Some_Data_1><Some_Data_1> <Some_Data_2><Some_Data_2> </Block> <Block id="2"> <Another_Data_3><

我有一个具有以下结构的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>
但我相信有更优化的方法来做到这一点


非常感谢您的时间

Xml序列化速度慢,需要类和属性名。相反,我推荐XMLLINQ,它速度更快,不需要预定义的属性名

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:\temp\test.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());

        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Xml;
使用System.Xml.Linq;
命名空间控制台应用程序1
{
班级计划
{
常量字符串文件名=@“c:\temp\test.xml”;
静态void Main(字符串[]参数)
{
XDocument doc=XDocument.Load(文件名);
Dictionary dict=文档子体(“块”)
.GroupBy(x=>(int)x.Attribute(“id”),y=>y.Elements()
.GroupBy(a=>a.Name.LocalName,b=>(字符串)b)
.ToDictionary(a=>a.Key,b=>b.FirstOrDefault())
.ToDictionary(x=>x.Key,y=>y.FirstOrDefault());
}
}
}

Xml序列化速度慢,需要类和属性名。相反,我推荐XMLLINQ,它速度更快,不需要预定义的属性名

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:\temp\test.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());

        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Xml;
使用System.Xml.Linq;
命名空间控制台应用程序1
{
班级计划
{
常量字符串文件名=@“c:\temp\test.xml”;
静态void Main(字符串[]参数)
{
XDocument doc=XDocument.Load(文件名);
Dictionary dict=文档子体(“块”)
.GroupBy(x=>(int)x.Attribute(“id”),y=>y.Elements()
.GroupBy(a=>a.Name.LocalName,b=>(字符串)b)
.ToDictionary(a=>a.Key,b=>b.FirstOrDefault())
.ToDictionary(x=>x.Key,y=>y.FirstOrDefault());
}
}
}

第一个方法是Serialize,第二个方法是@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();

}
下面的codde是由
XSD.EXE/c file.XSD
生成的,因此您应该从XML中创建一个XSD(Visual Studio可以为您这样做):

//------------------------------------------------------------------------------
// 
//这段代码是由一个工具生成的。
//运行时版本:4.0.30319.42000
//
//对此文件的更改可能会导致不正确的行为,如果
//重新生成代码。
// 
//------------------------------------------------------------------------------
使用System.Xml.Serialization;
// 
//此源代码由xsd自动生成,版本=4.8.3928.0。
// 
/// 
[System.CodeDom.Compiler.GeneratedCodeAttribute(“xsd”,“4.8.3928.0”)]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute(“代码”)]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace=”“,IsNullable=false)]
公众部分班级反应{
私有响应块[]块域;
/// 
[System.Xml.Serialization.XmlElementAttribute(“块”)]
公共响应块[]块{
得到{
返回此.blockField;
}
设置{
this.blockField=值;
}
}
}
/// 
[System.CodeDom.Compiler.GeneratedCodeAttribute(“xsd”,“4.8.3928.0”)]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute(“代码”)]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
公共部分类响应块{
私有字符串另一个_数据_3字段;
私有字符串另一个_数据_4字段;
私有字符串另一个_数据_5字段;
私有字符串部分数据字段;
私有字符串某些_数据_2字段;
私有字符串[]文本字段;
专用字节字段;
/// 
公共字符串另一个\u数据\u 3{
得到{
返回此。另一个_数据_3字段;
}
设置{
this.other_Data_3Field=值;
}
}
/// 
公共字符串另一个\u数据\u 4{
得到{
返回this.other_Data_4字段;
}
设置{
this.other_Data_4Field=值;
}
}
/// 
公共字符串另一个_数据_5{
得到{
返回this.other_Data_5字段;
}
设置{
this.other_Data_5Field=值;
}
}
/// 
公共字符串某些\u数据\u 1{
得到{
返回this.some_Data_1字段;
}
设置{
this.some_Data_1字段=值;
}
}
/// 
公共字符串某些\u数据\u 2{
得到{
返回this.some_Data_2字段;
}
设置{
this.some_Data_2字段=值;
}
}
/// 
[System.Xml.Serialization.XmlTextAttribute()]
公共字符串[]文本{
得到{
返回this.textField;
}
设置{
this.textField=值;
}
}
/// 
[System.Xml.Serialization.XmlAttributeAttribute()]
公共字节id{
得到{
返回此.idField;
}
设置{
this.idField=值;
}
}
}

第一个方法是Serialize,第二个方法是@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();

}
下面的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;
        }
    }
}