如何在将 xml 文件反序列化为 C# 模型时停止 XmlReader.Create() 缓冲结果

How can I stop XmlReader.Create() from buffering results while deserializing an xml file to a C# model

我使用以下函数将 xml 文档反序列化为 C# 模型:

 public XmlModel OpenModel(string filePath)
        {
            using (XmlReader reader = XmlReader.Create(filePath, readerSettings))
                return (XmlModel)serializer.Deserialize(reader);
        }

我知道 XmlReader.Create 是静态的。但是,我认为使用 using 函数会在每次调用后处理 reader 。但是,当我不止一次使用这个函数时,返回的 XmlModel 总是被缓冲,结果重复。也就是说,XmlModel的成员是从读取的xml文件(filePath)读取的值的累加。如果我调用 XmlReader.Create 三次,我会得到三倍的值,等等。我使用 reader.Close() 无济于事。

我的应用程序将“状态”值存储为 XML。用户应该能够加载保存的“状态”并从那里继续工作。第一次加载“状态”时,一切正常。但是,当加载新的“状态”或 xml 文件时,应用程序只是加载最后一个“状态”加上新的“状态”,我可以将其追溯到 XmlReader。也许有人可以提供帮助...

顺便说一下,我在 Json 中使用了类似的功能,一切正常...

 public JsonModel OpenModel(string filePath)
        {
            using (StreamReader file = File.OpenText(filePath))
                return (JsonModel)serializer.Deserialize(file, typeof(JsonModel));     
        }

编辑

这里有更多信息,希望能更详细地解释我的问题。我添加的信息显示了我如何调用该函数以及我从我的应用程序保存的示例 xml 文件 ...

public  void Import()
{
    var file = FileExporting.GetFileFromLocation();
    if (!string.IsNullOrEmpty(file) && File.Exists(file))
    {
        var extension = Path.GetExtension(file);

        if (!string.IsNullOrEmpty(extension) && string.Equals(extension, ".xml"))
        {
            // Get the xml model
            XmlModel model = new XmlSession().OpenModel(file) as XmlModel; // model is always a buffer, not what is desired

            // Load onto session
            ImportModel(model as XmlModel);

        }        
    }
}

届会Class

public class XmlSession
    {
        #region Private Members
        private readonly XmlSerializer serializer = new XmlSerializer(typeof(XmlModel));
        private static readonly XmlWriterSettings writerSettings = new XmlWriterSettings()
        {
            Indent = true,
            IndentChars = @"    ",
            NewLineChars = Environment.NewLine,
            NewLineHandling = NewLineHandling.Replace,
        };

        private static readonly XmlReaderSettings readerSettings = new XmlReaderSettings()
        {
            CloseInput = true
        };

        #endregion

        #region Constructor
        public XmlSession() { }

        #endregion

        #region Public Methods


        public XmlModel OpenModel(string filePath)
        {
            using (XmlReader reader = XmlReader.Create(filePath, readerSettings))
                return (XmlModel)serializer.Deserialize(reader);
        }

        public void SaveModel(XmlModel model, string filePath)
        {
            using (XmlWriter writer = XmlWriter.Create(filePath, writerSettings))
                serializer.Serialize(writer, model);
        }

    }

样本Xml文件

<?xml version="1.0" encoding="utf-8"?>
<XmlModel xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <head>
        <author>Max Mustermann</author>
        <date>7-16-2020</date>
        <copyright>All rights reserved - Max Mustermann Company</copyright>
        <application>Knowledge-Base</application>
        <name>C:\Users\MM\Downloads\Part.SLDPRT</name>
        <location>C:\Users\MM\Desktop\mre.xml</location>
    </head>
    <application>
        <versions>
            <version>1</version>
        </versions>
        <extensions>
            <extension>.xml</extension>
        </extensions>
    </application>
    <knowledgebase>
        <components>
            <component>
                <ObjectName>Part</ObjectName>
                <ObjectType>Component</ObjectType>
                <IsHeader>false</IsHeader>
                <PersistId>200050000000005000000000255254255000000000000000</PersistId>
                <Notes>A cad component</Notes>
                <IsVisible>true</IsVisible>
                <IsHidden>false</IsHidden>
                <IsSuppressed>false</IsSuppressed>
                <Attributes>
                    <ObjectAttribute>
                        <Name>Material</Name>
                        <Domain>Text</Domain>
                        <Value xsi:type="xsd:string">Iron</Value>
                        <AttributeNotes>Some notes</AttributeNotes>
                    </ObjectAttribute>
                </Attributes>
                <ThisDimensionValue>123</ThisDimensionValue>
            </component>
        </components>
        <project />
        <company />
        <customer />
        <rules />
    </knowledgebase>
</XmlModel>

第二次编辑

ImportModel方法

private  void ImportModel(XmlModel xmlModel)
{
    if (CapturedObjects.Items.Any())
    {
        var userInput = ShowMessageBox("Current information in memory will be cleard. Do you want to continue?", MessageBoxIcon.Question, MessageBoxButtons.YesNo);

        if (userInput == MessageBoxResult.No)
        {
            return;
        }
    }

    // Get the knowledge-base
    var KnowledgeBase = xmlModel.XmlBase;

    // Clear
    CapturedObjects.Items.Clear();
    CapturedObjects.ProjectInformation = null;
    CapturedObjects.CustomerInformation = null;
    CapturedObjects.ProjectInformation = null;

    // Get components
    foreach (var i in KnowledgeBase.Components)
    {
        CapturedObjects.Items.Add(i);
    }

    // Get Customer information
    CapturedObjects.CustomerInformation = KnowledgeBase.Customer;

    // Get Company information
    CapturedObjects.CompanyInformation = KnowledgeBase.Company;

    // Get Project Information
    CapturedObjects.ProjectInformation = KnowledgeBase.Project;

}

你应该有一个列表,然后将每个文件添加到列表中,这样你就可以保存所有数据而不是覆盖结果。

使用下面的方法做Xml序列化

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.Globalization;
namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XmlReader reader = XmlReader.Create(FILENAME);
            XmlSerializer serializer = new XmlSerializer(typeof(XmlModel));
            List<XmlModel> models = new List<XmlModel>();
            XmlModel model = (XmlModel)serializer.Deserialize(reader);
            models.Add(model);            }
    }
    public class XmlModel
    {
        public Head head { get; set; }
        public Application application { get; set; }
        public Knowledgebase knowledgebase { get; set; }
    }
    public class Head
    {
        public string author { get; set; }

        private DateTime _date { get; set; }
        public string date 
        { 
            get {return _date.ToString("M-dd-yyyy");} 
            set {_date = DateTime.ParseExact(value, "M-dd-yyyy", CultureInfo.InvariantCulture);} 
        }
        public string copyright { get; set; }
        public string application { get; set; }
        public string name { get; set; }
        public string location { get; set; }
    }
    public class Application
    {
        [XmlArray("versions")]
        [XmlArrayItem("version")]
        public string[] versions { get; set; }

        [XmlArray("extensions")]
        [XmlArrayItem("extension")]
        public string[] extensions { get; set; }
    }
    public class Knowledgebase
    {
        [XmlArray("components")]
        [XmlArrayItem("component")]
        public Component[] component { get; set; }

        public string project { get; set; }
        public string company { get; set; }
        public string customer { get; set; }
        public string rules { get; set; }
    }
    public class Component
    {
        public string ObjectName { get; set; }
        public string ObjectType { get; set; }
        public Boolean IsHeader { get; set; }
        public string PersistId { get; set; }
        public string Notes { get; set; }
        public Boolean IsVisible { get; set; }
        public Boolean IsHidden { get; set; }
        public Boolean IsSuppressed { get; set; }
        public int ThisDimensionValue { get; set; }
        [XmlArray("Attributes")]
        [XmlArrayItem("ObjectAttribute")]
        public Attribute[] attribute { get; set; }
    }
    public class Attribute
    {
        public string Name { get; set; }
        public string Domain { get; set; }
        public string Value { get; set; }
        public string AttributeNotes { get; set; }
    }
}