数组的C#XML反序列化
我对反序列化数组有一个问题。因为数组元素可以是各种类型。您可以看到以下示例:数组的C#XML反序列化,c#,xml,arrays,C#,Xml,Arrays,我对反序列化数组有一个问题。因为数组元素可以是各种类型。您可以看到以下示例: <?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"> <notif
<?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>
因此,问题是如何从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();
}
}
但have System.invalidoOperationException在序列化程序.反序列化(读取器)时未处理代码>
Message=不需要。
我做错了什么?将类型声明移动到集合中如何
[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);
}
}
[XmlRoot(“导出”)]
公共类通知集合
{
[XmlElement(“notificationZK”,typeof(NotificationTypeZK))]
[XmlElement(“notificationFF”,类型化(NotificationTypeFF))]
公共列表通知{get;set;}
}
公共类通知类型
{
}
公共类NotificationTypeZK:NotificationType{}
公共类NotificationTypeFF:NotificationType{}
静态void Main(字符串[]参数)
{
var数据=@;
var serializer=新的XmlSerializer(typeof(NotificationCollection));
使用(变量读取器=新的StringReader(数据))
{
var通知=序列化程序。反序列化(读取器);
}
}
这应该可以完成这项工作
[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>
真的
试验
假的
7.
正如在另一个答案中提到的,您不能在XML数组中使用不同的标记。但是,仍然可以存储不同的类型。序列化程序通过使用xsi:type
属性来实现这一点
为了解决您的问题,您可能需要使用另一种XML模式。示例XML缺少开头标记。为什么缺少?这是我工作项目中的真实XML:(这里是真实文件的示例:忽略我。我误读了:(我测试了你的3个答案,它们都有效。但它对我不起作用:(我从XSD生成了C#类。XSD可以在这里下载。可能的生成类丢失了?如果导出的格式不固定,我也会使用这种方法。根据您的模式,具有不同的子元素标记名是有效的XML。保留问题中定义的模式时,可以解决此问题。@Gusdor如果元素未知,我如何实现它?在OP的情况下,元素的名称是已知的。在我的情况下,我不能执行[XmlElement(“notificationOKType”,Type=typeof(notificationOKType))]公共notificationType[]通知{get;set;}因为元素“notificationOKType”可以有任何name@wintersolstice这是可能的(而且是直截了当的),但你应该提出另一个问题。
[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 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>