简体   繁体   English

确定类如何用于反序列化 XML 的最有效方法

[英]Most efficient way to determine how class use to Deserialize XML

I have many .xsd files for many xml schemas我有许多 .xsd 文件用于许多 xml 模式

example例子

XML 1.0 - xml_1_0.xml XML 1.0 - xml_1_0.xml

<?xml version="1.0" encoding="UTF-8"?>
     <cars version="1.00">
         <car>Honda</car>
         <car>Ferrari</car>
     </cars>

XML 2.0 - xml_2_0.xml XML 2.0 - xml_2_0.xml

<?xml version="1.0" encoding="UTF-8"?>
 <cars version="2.00">
     <car>
       <name>Honda</name>
       <color>White</color>
     </car>

     <car>
       <name>Honda</name>
       <color>Red</color>
     </car>
 </cars>

I create my classes from .xsd like this我像这样从 .xsd 创建我的类

xsd.exe cars_1_0.xsd /c

xsd.exe cars_2_0.xsd /c

And Deserialize like this:并像这样反序列化:

foreach(string file in files) {
     XmlDocument doc = new XmlDocument();
     doc.Load(file);    
     string version =   doc.SelectSingleNode("/Cars/@version").Value;

     if(version == "1.00")
     {
         Stream reader = new FileStream(file, FileMode.Open);
         XmlSerializer serializer = new XmlSerializer(typeof(v1.Cars));

         v1.Cars XML = new v1.Cars();
         XML = (v1.Cars)serializer.Deserialize(reader);
     } 
     else if(version == "2.00") 
     {
         Stream reader = new FileStream(file, FileMode.Open);
         XmlSerializer serializer = new XmlSerializer(typeof(v2.Cars));

         v2.Cars XML = new v2.Cars();
         XML = (v2.Cars)serializer.Deserialize(reader);
     }
}

Does anyone know a better way to do this, or have a better performance?有谁知道更好的方法来做到这一点,或者有更好的表现?

You have several options, depending on how far you want to take this.您有多种选择,具体取决于您想走多远。 One fairly non invasive option would be to not use XmlDocument and avoid loading the stream more than once.一种相当非侵入性的选择是不使用XmlDocument并避免多次加载流。 For example, your existing code could be simplified/streamlined to :例如,您现有的代码可以简化/精简为:

foreach (string file in files)
{
    using (var stream = new FileStream(file, FileMode.Open))
    {
        var settings = new XmlReaderSettings();
        settings.CloseInput = false;
        string version = "";
        using (var xmlReader = XmlReader.Create(stream))
        {
            if (xmlReader.ReadToFollowing("Cars"))
            {
                version = xmlReader.GetAttribute("version");
            }
            else
            {
                throw new XmlException("Could not get 'version' attribute of 'Cars' root element!");
            }                    
        }
        stream.Position = 0;
        if (version == "1.00")
        {
            XmlSerializer serializer = new XmlSerializer(typeof(v1.Cars));

            v1.Cars XML = new v1.Cars();
            XML = (v1.Cars)serializer.Deserialize(stream);
        }
        else if (version == "2.00")
        {
            XmlSerializer serializer = new XmlSerializer(typeof(v2.Cars));

            v2.Cars XML = new v2.Cars();
            XML = (v2.Cars)serializer.Deserialize(stream);

        }
    }
}

Since you're just reading off the root element, you might even be able to get away with deserializing from the XmlReader and not have to reset the position on the FileStream .由于您只是读取根元素,因此您甚至可以从XmlReader进行反序列化,而不必重置FileStream上的位置。

This avoids the overhead of loading the entire file twice (once for XmlDocument , then again for XmlSerializer ) - and particularly avoids the memory overhead of creating a DOM for each document.这避免了两次加载整个文件的开销(一次用于XmlDocument ,然后再次用于XmlSerializer ) - 特别是避免了为每个文档创建 DOM 的内存开销。

A more nuclear option would be implementing IXmlSerializable on a set of custom classes, which would have custom logic in the ReadXml methods to parse the version attribute and instantiate the correct child type(s) - eg a CarCollection class that has a List<Car> property, where Car is an abstract class that has CarV1 and CarV2 as descendants.一个更核心的选择是在一组自定义类上实现IXmlSerializable ,这将在ReadXml方法中具有自定义逻辑来解析版本属性并实例化正确的子类型 - 例如具有List<Car>CarCollection类属性,其中Car是一个抽象类,具有CarV1CarV2作为后代。 This would be about as efficient as you could get (and offer very fine grained control over your class hierarchy design), but would eliminate the possibility of using xsd.exe to generate your classes.这将尽可能高效(并提供对类层次结构设计的非常细粒度的控制),但会消除使用 xsd.exe 生成类的可能性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM