在c#中使用XmlSerializer似乎无法反序列化非常简单的xml

本文关键字:反序列化 非常 简单 xml XmlSerializer | 更新日期: 2023-09-27 18:13:48

我觉得我要完蛋了。我已经写了上百个反序列化例程,但这一个简直要了我的命!

下面是我从服务返回的结果。一个非常简单的字符串数组…我想。

<ArrayOfstring xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <string>Action &amp; Adventure</string>
    <string>Comedy</string>
    <string>Drama</string>
    <string>Family</string>
    <string>Horror</string>
    <string>Independent &amp; World</string>
    <string>Romance</string>
    <string>Sci-Fi/Fantasy</string>
    <string>Thriller &amp; Crime</string>
</ArrayOfstring>

我正在使用开箱反序列化

var serializer = new XmlSerializer(typeof(List<string>));
var reader = new StringReader(xmlString);
var GenreList = (List<string>)serializer.Deserialize(reader);

但是我在反序列化行得到以下错误:

<ArrayOfstring xmlns='http://schemas.microsoft.com/2003/10/Serialization/Arrays'> was not expected

我试过包括命名空间和创建各种各样的外来对象,试图让它工作。时间太长了。最后我用JSON请求了它,并用Json.net对它进行了反序列化。

然而,我很好奇我做错了什么!

在c#中使用XmlSerializer似乎无法反序列化非常简单的xml

当然XmlSerializer可以反序列化它。您只需要创建XmlSerializer,如下所示

var serializer = new XmlSerializer(typeof(List<string>), 
                                   new XmlRootAttribute() { ElementName = "ArrayOfstring", Namespace = "http://schemas.microsoft.com/2003/10/Serialization/Arrays" });

如果没有额外的规范,XML序列化器不能反序列化简单类型或简单类型列表,但是DataContractReader可以:

        string content = @"
        <ArrayOfstring xmlns=""http://schemas.microsoft.com/2003/10/Serialization/Arrays"" xmlns:i=""http://www.w3.org/2001/XMLSchema-instance"">
            <string>Action &amp; Adventure</string>
            <string>Comedy</string>
            <string>Drama</string>
            <string>Family</string>
            <string>Horror</string>
            <string>Independent &amp; World</string>
            <string>Romance</string>
            <string>Sci-Fi/Fantasy</string>
            <string>Thriller &amp; Crime</string>
        </ArrayOfstring>";
        var serializer = new DataContractSerializer(typeof(string[]));
        var reader = new XmlTextReader(new StringReader(content));
        var GenreList = new List<string>((string[])serializer.ReadObject(reader));

您也可以使用一个简单的类来实现相同的结果。注意,为了简洁起见,我从XML文件中删除了名称空间。如果您愿意,可以在序列化器中实现名称空间的读取。

    public class ArrayOfstring
    {
        [XmlElement("string")]
        public List<string> strings;
    }
    private void Deserialize(string xmlString)
    {
        var serializer = new XmlSerializer(typeof(ArrayOfstring));
        var reader = new StringReader(xmlString);
        var GenreList = ((ArrayOfstring) serializer.Deserialize(reader)).strings;
    }

可以了

DataContractSerializer xmlSer = new DataContractSerializer(typeof(string[]));
TextReader reader=new StreamReader(xmlString);
var stringArr= (string[])xmlSer.ReadObject(reader);
List<string> listStr=new List<>();
for(var s in stringArr)
{
listStr.Add(s);
}

我知道这是一个老问题,但我最近遇到了同样的问题,想分享一下对我有用的方法。我尝试了列出的所有可能的解决方案,但没有一个能奏效。即使在XmlRootAttribute方法中指定名称空间,也会抛出在原始问题中报告的"was not expected"错误。我从API中获得ArrayOfString作为响应,所以我使用了XDocument解析方法:

List<string> lstGenre = new List<string>();
var response = await client.PostAsync(url, content);
var responseString = await response.Content.ReadAsStringAsync();
XDocument xdoc = XDocument.Parse(responseString);
XNamespace ns = xdoc.Root.GetDefaultNamespace();
XElement root = xdoc.Element(XName.Get("ArrayOfString", ns.NamespaceName));
IEnumerable<XElement> list = root.Elements();
foreach (XElement element in list)
{
    string item = element.Value;  // <-- individual strings from the "ArrayOfString"
    lstGenre.Add(item);
}