对同一节点反序列化具有不同树结构的XML

时间:2013-04-23 19:12:21

标签: c# .net xml serialization xml-parsing

问题

我正在使用如下所示的XML结构,我遇到了问题,因为<value>标记可以包含多种类型的数据,并且有时可以具有嵌套值。我已经尝试使用ListItem的抽象类,并且值有几种不同的类型,但它似乎不起作用,因为XmlSerializer要求我用一些方法在不同的密封类之间进行选择 - 我不能这样做

<listContainer>
    <listItem>
        <value>
            <boolean>true</boolean>
        </value>
    </listItem>
    <listItem>
        <value>1</value>
    </listItem>
    <listItem>
        <value>HAI IM A STRING!</value>
    </listItem>
</listContainer>

附加说明

  1. 我还尝试编写一个XmlReaderReader(http://msdn.microsoft.com/en-us/library/t2abc1zd(v=vs.71).aspx)来尽可能深入到嵌套标记中,但这似乎不是一个可行的解决方案。
  2. 我无法更改XML的格式,它来自第三方供稿。
  3. XML文件大约有几个演出。我正在使用BufferedStream和传递给默认XmlSerializer的仅向前XmlReader,以便出于性能原因进行读取/反序列化。
  4. 这不是根级XML,它嵌套在其他几个节点中,但我只需要有关如何正确序列化的建议。
  5. public class listContainer {
        [XmlArray(ElementName="listItem")]
        [XmlArrayItem(Type=typeof(listItem), ElementName="listItem")]
        public List<listItem> listItem { get; set; }
    }
    
    public class listItem {
        // ... help ...
    }
    

1 个答案:

答案 0 :(得分:0)

Xml架构包含歧义 - 在您的示例中,HAI ...和1可以是相同类型,字符串或1可以反序列化为整数。

我认为没有简单的方法将这些隐式规则表示为可序列化对象,因此我建议将其反序列化为XmlNode,然后根据节点属性进行手动识别。例如,如果XmlNode包含单个嵌套标记 - 反序列化为bool,如果没有标记 - 尝试解析为int,否则使用字符串等。样本非常小,因此很难判断是否会有很多规则。

我必须修改示例,以包含一个以上的根级别,以正确反序列化。但是你说这个xml已经嵌套了,所以这应该没问题。

[XmlRoot("root")]
public class container {
  [XmlArray("listContainer")]
  public List<listItem> listItem;
}

public class listItem {
    public XmlNode value;
}

class App {
  static void Main() {
    StreamReader fs = new StreamReader(@"sample.xml");
    XmlSerializer serializer = new XmlSerializer(typeof(container));
    var result = serializer.Deserialize(fs) as container;  
    foreach (var res in result.listItem)
      Console.WriteLine(res.value.OuterXml);
  }
}

sample.xml中:

<root>
<listContainer>
    <listItem><value><boolean>true</boolean></value></listItem>
    <listItem><value>1</value></listItem>
    <listItem><value>HAI IM A STRING!</value></listItem>
</listContainer>
</root>