如何反序列化 System.Xml.Linq.XElement?

Posted

技术标签:

【中文标题】如何反序列化 System.Xml.Linq.XElement?【英文标题】:How I can deserialize a System.Xml.Linq.XElement? 【发布时间】:2020-11-28 04:32:16 【问题描述】:

我试过了:

using (XmlReader reader = XmlReader.Create(_xmlPath))

    while (reader.Read())
    
        if (reader.NodeType.Equals(XmlNodeType.Element) && reader.Name.Equals("Obj"))
        
            Obj obj = new Obj();
            while (reader.Read())
            
                if (reader.NodeType.Equals(XmlNodeType.EndElement) && reader.Name.Equals("Obj"))
                    break;
                if (reader.NodeType.Equals(XmlNodeType.Element))
                
                    switch (reader.Name)
                    
                        case "Code":
                            obj.Code = reader.ReadElementContentAsString();
                            break;
                        case "Data":
                            XElement el = (XElement) XNode.ReadFrom(reader);
                            XmlReader r = el.CreateReader();
                            XmlSerializer serializer = new XmlSerializer(typeof(Data));
                            Data data = (Data) serializer.Deserialize(r);
                            obj.Data = data;
                            break;
                    
                
            
        
    

XML:

<Root>
    <Obj>
        <Code>code</Code>
        <Data>
            <Date>2020-08-07</Date>
            <Amount>1000</Amount>
        </Data>
    </Obj>
</Root>

数据类:

public class Data
    public DateTime Date get;set;
    public decimal Amount get;set;

通常,它是一个很大的 XML 文件,这就是为什么我尝试将它切割成片段并使用 XmlReader 解析它的原因。 反序列化不起作用,如果你有其他方式我是一个接受者

【问题讨论】:

您可能想要发布 XML 和 Data 类的代码。它真的返回一个包含"None"的字符串吗? @Flydog57 我编辑了我的问题 【参考方案1】:

尝试以下:

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);
            Data data = doc.Descendants("Data")
                .Select(x => new Data()  Date = (DateTime)x.Element("Date"), Amount = (decimal)x.Element("Amount") ).FirstOrDefault();
        
    
    public class Data
    
        public DateTime Date  get; set; 
        public decimal Amount  get; set; 
    

对于大文件,请使用以下内容:

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)
        
            XmlReader reader = XmlReader.Create(FILENAME);
            List<Data> data = new List<Data>();
            while (!reader.EOF)
            
                if (reader.Name != "Data")
                
                    reader.ReadToFollowing("Data");
                
                if (!reader.EOF)
                
                    XElement xData = (XElement)XElement.ReadFrom(reader);
                    Data newData = new Data()  Date = (DateTime)xData.Element("Date"), Amount = (decimal)xData.Element("Amount") ;
                    data.Add(newData);
                
            
        
    
    public class Data
    
        public DateTime Date  get; set; 
        public decimal Amount  get; set; 
    

【讨论】:

这是一个很大的XML文件,我不想通过Load方法将它加载到内存中 我为大文件添加了解决方案。【参考方案2】:

我简化了你的代码。它应该可以工作。

var serializer = new XmlSerializer(typeof(Obj));

using (XmlReader reader = XmlReader.Create(_xmlPath))

    while (reader.ReadToFollowing("Obj"))
    
        Obj obj = (Obj)serializer.Deserialize(reader);
    

如果实际的 xml 结构更复杂,并且这段代码不起作用,请告诉我们。

【讨论】:

是的,它比示例更复杂,最后我通过使用 reader.ReadOuterXml() 使其工作,我将发布解决方案

以上是关于如何反序列化 System.Xml.Linq.XElement?的主要内容,如果未能解决你的问题,请参考以下文章

如何序列化/反序列化的ArrayList

什么是序列化? 如何实现(反)序列化 序列化的应用

什么是序列化? 如何实现(反)序列化 序列化的应用

什么是序列化? 如何实现(反)序列化 序列化的应用

guid的值为null如何在C#反序列化

如何反序列化具有相同名称但不同类型的 API 响应