我有很多 xml 模式的 .xsd 文件
例子
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 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>
我像这样从 .xsd 创建我的类
xsd.exe cars_1_0.xsd /c
xsd.exe cars_2_0.xsd /c
像这样反序列化:
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);
}
}
有没有人知道更好的方法,或者有更好的性能?
最佳答案
您有多种选择,具体取决于您想走多远。一个相当非侵入性的选择是不使用 XmlDocument
并避免多次加载流。例如,您现有的代码可以简化/精简为:
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);
}
}
}
由于您只是读取根元素,您甚至可以从 XmlReader
中进行反序列化。而不必重置 FileStream
上的位置.
这避免了两次加载整个文件的开销(一次用于 XmlDocument
,然后再次用于 XmlSerializer
)- 特别是避免了为每个文档创建 DOM 的内存开销。
一个更核的选择是实现 IXmlSerializable
在一组自定义类上,这些类将在 ReadXml
中具有自定义逻辑解析版本属性并实例化正确子类型的方法 - 例如一个CarCollection
具有 List<Car>
的类属性(property),在哪里Car
是一个具有 CarV1
的抽象类和 CarV2
作为后代。这将尽可能高效(并提供对类层次结构设计的非常细粒度的控制),但会消除使用 xsd.exe 生成类的可能性。
关于c# - 确定类如何使用反序列化 XML 的最有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42137447/