2

我有一个关于反序列化数组的问题。因为数组元素可以是各种类型。你可以看看这个例子:

<?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
    {
...

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

[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.

我做错了什么?

4

3 回答 3

2

将类型声明移到集合中怎么样?

[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);
  }
}
于 2013-09-05T08:52:04.403 回答
1

这应该做的工作

    [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; }
    }
于 2013-09-05T08:53:47.850 回答
0

这个问题对我来说也很有趣。我编写了简化的应用程序来实现您的要求:

[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 方案。

于 2013-09-05T08:55:10.777 回答