我正在重构一些解析预先存在的XML文件的代码(我没有创建并且无法控制设计)。目前,我将XML读入XDocument
并执行各种linq查询以提取数据。我想要做的是使用XML 反序列化来完成所有这些工作。
我想这样做,因为代码的其他部分使用XML反序列化(我希望在操作中使代码保持一致),并且还要更好地记录此XML文件的结构。
但是在XML内部隐藏了7层深层的是以下数据:
<objects>
<object name="Fred">
<type>
<BOOL/>
</type>
</object>
<object name="Barney">
<type>
<WORD/>
</type>
</object>
<object name="Wilma">
<type>
<derived name="Special1"/>
</type>
</object>
<object name="Betty">
<type>
<array>
<dimension upper="3" lower="0"/>
<INT/>
</array>
</type>
</object>
<object name="Dino">
<type>
<array>
<dimension upper="3" lower="0"/>
<derived name="Special2"/>
</array>
</type>
</object>
</objects>
到目前为止,我已经能够通过定义简单的类来建模XML。
但是对于object
数据,Type
元素的值表示为明确定义的类型的子元素(而不是属性)(EG BOOL
,{ {1}})。在用户定义类型的情况下,使用不同的子元素,最终类型名称在该子元素的WORD
属性中定义(EG name
或Special1
)。 (另请注意,我没有/不能有完整的标准类型列表。)
(请注意,虽然此XML设计得很糟糕,但没有格式错误。)
当对象是数组并且类型包含在Special2
元素中时,事情变得更加混乱。
最终,我希望array
(包含标准和用户定义)和type
作为array dimensions
类的属性(以及object
类型的指示符遇到了)。
我不确定如何构建一个可以从这个XML反序列化的类,但我怀疑我需要深入研究这个类的一些自定义XML处理(或者可能是XSLT转换?)。
答案 0 :(得分:1)
为什么to use XML deserialization to do all that work for me
?
你已经手动完成了,为什么要做额外的工作?额外的工作将是:很多课程,通过attributes
进行大量替换(以<type>
为例)。
或者,如果您希望here,请继续我的示例。
Here是反序列化,正如您所看到的,它完全相同。
为方便起见,我将在此处发布代码:
using System;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
public class Program
{
[Serializable]
[XmlRoot("Objects")]
public class MyXml
{
[XmlElement("Object")]
public MyObject[] MyObjects;
}
[Serializable]
[XmlRoot("Object")]
public class MyObject
{
[XmlAttribute("name")]
public string MyName;
[XmlElement("Type")]
public object MyType;
}
public static void Main()
{
var data = new MyXml();
data.MyObjects = new MyObject[] {new MyObject() { MyName = "Fred"}, new MyObject()};
using (var stream = new MemoryStream())
{
var space = new XmlSerializerNamespaces();
space.Add("", "");
var serializer = new XmlSerializer(data.GetType());
serializer.Serialize(stream, data, space);
var text = Encoding.Default.GetString(stream.ToArray());
foreach(var line in text.Split(System.Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
Console.WriteLine(line);
stream.Seek(0, SeekOrigin.Begin);
var test = serializer.Deserialize(stream) as MyXml;
Console.WriteLine("\nTest: " + test.MyObjects[0].MyName);
}
}
}
答案 1 :(得分:0)
正如已经说过的那样,除了手动处理之外,我没有看到任何其他选择,正如您已经在做的那样。
如果您(可能也不是XML所有者)不知道XML将如何(以架构方式说话),为什么您认为任何技术都能自动理解?
所以,我认为你手动完成它是正确的。