数组的 C# XML 反序列化

本文关键字:反序列化 XML 数组 | 更新日期: 2023-09-27 18:30:17

>我有一个关于反序列化数组的问题。Becouse 数组元素可以是各种类型的。您可以看到以下示例:

<?xml version="1.0" encoding="UTF-8"?><export xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://zakupki.gov.ru/oos/export/1" xmlns:oos="http://zakupki.gov.ru/oos/types/1">
<notificationZK>
    ... item 1 data
</notificationZK>
<notificationZK>
    ... item 2 data
</notificationZK>
<notificationFF>
    ... item 3 data
</notificationFF>
</export>

所有元素都扩展notificationType

   [System.Xml.Serialization.XmlIncludeAttribute(typeof(notificationSZType))]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(notificationPOType))]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(notificationZKType))]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(notificationEFType))]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(notificationOKType))]
    public partial class notificationType
    {
...

所以问题是我如何从我的 XML 文件中获取notificationType元素的集合?我想我不能做这样的事情

[Serializable()]
[System.Xml.Serialization.XmlRoot("export")]
public class NotificationCollection
{
    [XmlArray("")] // ???? what I need write here?
    [XmlArrayItem("", typeof(notificationType))] // ??? and here?
    public notificationType[] notification { get; set; }
}

问候!

添加-------------

所以。我做这个:

[Serializable()]
[System.Xml.Serialization.XmlRoot("export")]
public class NotificationCollection
{
    [XmlElement("notificationSZType", Type = typeof(notificationSZType))]
    [XmlElement("notificationPOType", Type = typeof(notificationPOType))]
    [XmlElement("notificationZKType", Type = typeof(notificationZKType))]
    [XmlElement("notificationEFType", Type = typeof(notificationEFType))]
    [XmlElement("notificationOKType", Type = typeof(notificationOKType))]
    public notificationType[] notification { get; set; }
}
class Program
{
    static void Main(string[] args)
    {
        NotificationCollection collection = null;
        string path = @"E:'notification.xml";
        XmlSerializer serializer = new XmlSerializer(typeof(notificationType));
        StreamReader reader = new StreamReader(path);
        collection = (NotificationCollection) serializer.Deserialize(reader);
        reader.Close();
    }
}

但有 System.InvalidOperationException 在serializer.Deserialize(reader);时未处理

Message=<export xmlns='http://zakupki.gov.ru/oos/export/1'> not expected.

我做错了什么?

数组的 C# XML 反序列化

如何将类型声明移动到集合中?

[XmlRoot("export")]
public class NotificationCollection
{
  [XmlElement("notificationZK", typeof(NotificationTypeZK))]
  [XmlElement("notificationFF", typeof(NotificationTypeFF))]
  public List<NotificationType> Notifications { get; set; }
}
public class NotificationType
{
}
public class NotificationTypeZK : NotificationType { }
public class NotificationTypeFF : NotificationType { }
static void Main(string[] args)
{
  var data = @"<export><notificationZK /><notificationZK /><notificationFF /></export>";
  var serializer = new XmlSerializer(typeof(NotificationCollection));
  using (var reader = new StringReader(data))
  {
    var notifications = serializer.Deserialize(reader);
  }
}

这应该可以完成这项工作

    [Serializable()]
    [System.Xml.Serialization.XmlRoot("export")]
    public class NotificationCollection
    {
        [XmlElement("notificationSZType", Type = typeof(notificationSZType))]
        [XmlElement("notificationPOType", Type = typeof(notificationPOType))]
        [XmlElement("notificationZKType", Type = typeof(notificationZKType))]
        [XmlElement("notificationEFType", Type = typeof(notificationEFType))]
        [XmlElement("notificationOKType", Type = typeof(notificationOKType))]
        public notificationType[] notification { get; set; }
    }
这个问题对我来说

也很有趣。我编写了简化的应用程序来实现您的要求:

[Serializable]
[XmlInclude(typeof(ItemA))]
[XmlInclude(typeof(ItemB))]
public class BaseItem
{
    public bool Value { get; set; }
}
[Serializable]
public class ItemA : BaseItem
{
    public string Text { get; set; }
}
[Serializable]
public class ItemB : BaseItem
{
    public int Number { get; set; }
}
[Serializable]
public class ItemsArray
{
    public BaseItem[] Items { get; set; }
}
class Program
{
    static void Main(string[] args)
    {
        var array = new ItemsArray
        {
            Items = new BaseItem[]
            {
                new ItemA { Value = true, Text = "Test" },
                new ItemB { Value = false, Number = 7 }
            }
        };
        ItemsArray output;
        using (var stream = new MemoryStream())
        {
            var serializer = new XmlSerializer(typeof(ItemsArray));
            serializer.Serialize(stream, array);
            stream.Position = 0;
            output = (ItemsArray)serializer.Deserialize(stream);
        }
    }
}

反序列化后,我们得到的正是我们序列化的内容。流中的 XML 如下所示:

<?xml version="1.0"?>
<ItemsArray xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Items>
    <BaseItem xsi:type="ItemA">
      <Value>true</Value>
      <Text>Test</Text>
    </BaseItem>
    <BaseItem xsi:type="ItemB">
      <Value>false</Value>
      <Number>7</Number>
    </BaseItem>
  </Items>
</ItemsArray>

正如其他答案中提到的,您不能在 XML 数组中使用不同的标记。但是,仍然可以存储不同的类型。序列化程序通过使用 xsi:type 属性执行此操作。

为了解决您的问题,您可能需要使用另一种XML方案。

相关文章: