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 のもう 1 つのスキームを使用する必要があります。

于 2013-09-05T08:55:10.777 に答える