反序列化设计糟糕的XML

时间:2014-01-20 15:14:48

标签: c# xml-parsing

我正在重构一些解析预先存在的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 nameSpecial1 )。 (另请注意,我没有/不能有完整的标准类型列表。)

(请注意,虽然此XML设计得很糟糕,但没有格式错误。)

当对象是数组并且类型包含在Special2元素中时,事情变得更加混乱。

最终,我希望array(包含标准和用户定义)和type作为array dimensions类的属性(以及object类型的指示符遇到了)。

我不确定如何构建一个可以从这个XML反序列化的类,但我怀疑我需要深入研究这个类的一些自定义XML处理(或者可能是XSLT转换?)。

2 个答案:

答案 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将如何(以架构方式说话),为什么您认为任何技术都能自动理解?

所以,我认为你手动完成它是正确的。