【问题标题】:Deserialize xml to objects将xml反序列化为对象
【发布时间】:2015-06-14 04:45:26
【问题描述】:

我正在尝试将 xml 反序列化为对象。但我不断收到此错误:

System.InvalidOperationException' 发生在 System.Xml.dll 中 附加信息:XML 文档 (1, 1) 包含错误。

这是我用于反序列化的类

[XmlRoot("MRData")]
public class DriverData
{
    [XmlElement("series")]
    public string series { get; set; }

    [XmlElement("url")]
    public string url { get; set; }

    [XmlElement("limit")]
    public int limit { get; set; }

    [XmlElement("offset")]
    public int offset { get; set; }

    [XmlElement("total")]
    public int total { get; set; }
}


[XmlRoot("DriverTable")]
public class DriverTable
{
    [XmlElement("Driver")]
    public List<Driver> Drivers { get; set; }
}

public class Driver
{
    [XmlElement("driverId")]
    public string driverId { get; set; }

    [XmlElement("url")]
    public string url { get; set; }

    [XmlElement("GivenName")]
    public string GivenName { get; set; }

    [XmlElement("FamilyName")]
    public string FamilyName { get; set; }

    [XmlElement("DateOfBirth")]
    public DateTime DateOfBirth { get; set; }

    [XmlElement("Nationality")]
    public string Nationality { get; set; }

}

我很确定DriverDriverTable 是正确的,但也许错误在DriverData

class RacingApiClient
{
    public ObservableCollection<DriverData> GetDrivers()
    {
        var url = "http://ergast.com/api/f1/drivers";

        ObservableCollection<DriverData> drivers = new ObservableCollection<DriverData>();

        // Syncronious comsumption
        var syncClient = new WebClient();
        var content = syncClient.DownloadString(url);

        XmlSerializer serializer = new XmlSerializer(typeof(ObservableCollection<DriverData>));

        using (TextReader reader = new StringReader(url))
        {
            drivers = ((ObservableCollection<DriverData>)serializer.Deserialize(reader));
        }
        return drivers;
    }
}

这行抛出错误:drivers=((ObservableCollection&lt;DriverData&gt;)serializer.Deserialize(reader));

XML 响应是:

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="http://ergast.com/schemas/mrd-1.4.xsl"?>
<MRData xmlns="http://ergast.com/mrd/1.4" series="f1" url="http://ergast.com/api/f1/drivers" limit="30" offset="0" total="833">
    <DriverTable>
        <Driver driverId="abate" url="http://en.wikipedia.org/wiki/Carlo_Mario_Abate">
            <GivenName>Carlo</GivenName>
            <FamilyName>Abate</FamilyName>
            <DateOfBirth>1932-07-10</DateOfBirth>
            <Nationality>Italian</Nationality>
        </Driver>
        <Driver driverId="abecassis" url="http://en.wikipedia.org/wiki/George_Abecassis">
            <GivenName>George</GivenName>
            <FamilyName>Abecassis</FamilyName>
            <DateOfBirth>1913-03-21</DateOfBirth>
            <Nationality>British</Nationality>
        </Driver>
        <Driver driverId="acheson" url="http://en.wikipedia.org/wiki/Kenny_Acheson">
            <GivenName>Kenny</GivenName>
            <FamilyName>Acheson</FamilyName>
            <DateOfBirth>1957-11-27</DateOfBirth>
            <Nationality>British</Nationality>
        </Driver>
        <Driver driverId="adams" url="http://en.wikipedia.org/wiki/Philippe_Adams">
            <GivenName>Philippe</GivenName>
            <FamilyName>Adams</FamilyName>
            <DateOfBirth>1960-11-19</DateOfBirth>
            <Nationality>Belgian</Nationality>
        </Driver>
        <Driver driverId="ader" url="http://en.wikipedia.org/wiki/Walt_Ader">
            <GivenName>Walt</GivenName>
            <FamilyName>Ader</FamilyName>
            <DateOfBirth>1912-12-15</DateOfBirth>
            <Nationality>American</Nationality>
        </Driver>
        <Driver driverId="adolff" url="http://en.wikipedia.org/wiki/Kurt_Adolff">
            <GivenName>Kurt</GivenName>
            <FamilyName>Adolff</FamilyName>
            <DateOfBirth>1921-11-05</DateOfBirth>
            <Nationality>German</Nationality>
        </Driver>
        <Driver driverId="agabashian" url="http://en.wikipedia.org/wiki/Fred_Agabashian">
            <GivenName>Fred</GivenName>
            <FamilyName>Agabashian</FamilyName>
            <DateOfBirth>1913-08-21</DateOfBirth>
            <Nationality>American</Nationality>
        </Driver>
        <Driver driverId="ahrens" url="http://en.wikipedia.org/wiki/Kurt_Ahrens,_Jr.">
            <GivenName>Kurt</GivenName>
            <FamilyName>Ahrens</FamilyName>
            <DateOfBirth>1940-04-19</DateOfBirth>
            <Nationality>German</Nationality>
        </Driver>
        <Driver driverId="albers" code="ALB" url="http://en.wikipedia.org/wiki/Christijan_Albers">
            <GivenName>Christijan</GivenName>
            <FamilyName>Albers</FamilyName>
            <DateOfBirth>1979-04-16</DateOfBirth>
            <Nationality>Dutch</Nationality>
        </Driver>
        <Driver driverId="alboreto" url="http://en.wikipedia.org/wiki/Michele_Alboreto">
            <GivenName>Michele</GivenName>
            <FamilyName>Alboreto</FamilyName>
            <DateOfBirth>1956-12-23</DateOfBirth>
            <Nationality>Italian</Nationality>
        </Driver>
        <Driver driverId="alesi" url="http://en.wikipedia.org/wiki/Jean_Alesi">
            <GivenName>Jean</GivenName>
            <FamilyName>Alesi</FamilyName>
            <DateOfBirth>1964-06-11</DateOfBirth>
            <Nationality>French</Nationality>
        </Driver>
        <Driver driverId="alguersuari" code="ALG" url="http://en.wikipedia.org/wiki/Jaime_Alguersuari">
            <GivenName>Jaime</GivenName>
            <FamilyName>Alguersuari</FamilyName>
            <DateOfBirth>1990-03-23</DateOfBirth>
            <Nationality>Spanish</Nationality>
        </Driver>
        <Driver driverId="alliot" url="http://en.wikipedia.org/wiki/Philippe_Alliot">
            <GivenName>Philippe</GivenName>
            <FamilyName>Alliot</FamilyName>
            <DateOfBirth>1954-07-27</DateOfBirth>
            <Nationality>French</Nationality>
        </Driver>
        <Driver driverId="allison" url="http://en.wikipedia.org/wiki/Cliff_Allison">
            <GivenName>Cliff</GivenName>
            <FamilyName>Allison</FamilyName>
            <DateOfBirth>1932-02-08</DateOfBirth>
            <Nationality>British</Nationality>
        </Driver>
        <Driver driverId="alonso" code="ALO" url="http://en.wikipedia.org/wiki/Fernando_Alonso">
            <PermanentNumber>14</PermanentNumber>
            <GivenName>Fernando</GivenName>
            <FamilyName>Alonso</FamilyName>
            <DateOfBirth>1981-07-29</DateOfBirth>
            <Nationality>Spanish</Nationality>
        </Driver>
        <Driver driverId="amati" url="http://en.wikipedia.org/wiki/Giovanna_Amati">
            <GivenName>Giovanna</GivenName>
            <FamilyName>Amati</FamilyName>
            <DateOfBirth>1962-07-20</DateOfBirth>
            <Nationality>Italian</Nationality>
        </Driver>
        <Driver driverId="amick" url="http://en.wikipedia.org/wiki/Red_Amick">
            <GivenName>Red</GivenName>
            <FamilyName>Amick</FamilyName>
            <DateOfBirth>1929-01-19</DateOfBirth>
            <Nationality>American</Nationality>
        </Driver>
        <Driver driverId="george_amick" url="http://en.wikipedia.org/wiki/George_Amick">
            <GivenName>George</GivenName>
            <FamilyName>Amick</FamilyName>
            <DateOfBirth>1924-10-24</DateOfBirth>
            <Nationality>American</Nationality>
        </Driver>
        <Driver driverId="amon" url="http://en.wikipedia.org/wiki/Chris_Amon">
            <GivenName>Chris</GivenName>
            <FamilyName>Amon</FamilyName>
            <DateOfBirth>1943-07-20</DateOfBirth>
            <Nationality>New Zealander</Nationality>
        </Driver>
        <Driver driverId="anderson" url="http://en.wikipedia.org/wiki/Bob_Anderson_(racing_driver)">
            <GivenName>Bob</GivenName>
            <FamilyName>Anderson</FamilyName>
            <DateOfBirth>1931-05-19</DateOfBirth>
            <Nationality>British</Nationality>
        </Driver>
        <Driver driverId="andersson" url="http://en.wikipedia.org/wiki/Conny_Andersson">
            <GivenName>Conny</GivenName>
            <FamilyName>Andersson</FamilyName>
            <DateOfBirth>1939-12-28</DateOfBirth>
            <Nationality>Swedish</Nationality>
        </Driver>
        <Driver driverId="andretti" url="http://en.wikipedia.org/wiki/Michael_Andretti">
            <GivenName>Michael</GivenName>
            <FamilyName>Andretti</FamilyName>
            <DateOfBirth>1962-10-02</DateOfBirth>
            <Nationality>American</Nationality>
        </Driver>
        <Driver driverId="mario_andretti" url="http://en.wikipedia.org/wiki/Mario_Andretti">
            <GivenName>Mario</GivenName>
            <FamilyName>Andretti</FamilyName>
            <DateOfBirth>1940-02-28</DateOfBirth>
            <Nationality>American</Nationality>
        </Driver>
        <Driver driverId="andrews" url="http://en.wikipedia.org/wiki/Keith_Andrews_(driver)">
            <GivenName>Keith</GivenName>
            <FamilyName>Andrews</FamilyName>
            <DateOfBirth>1920-06-15</DateOfBirth>
            <Nationality>American</Nationality>
        </Driver>
        <Driver driverId="apicella" url="http://en.wikipedia.org/wiki/Marco_Apicella">
            <GivenName>Marco</GivenName>
            <FamilyName>Apicella</FamilyName>
            <DateOfBirth>1965-10-07</DateOfBirth>
            <Nationality>Italian</Nationality>
        </Driver>
        <Driver driverId="armi" url="http://en.wikipedia.org/wiki/Frank_Armi">
            <GivenName>Frank</GivenName>
            <FamilyName>Armi</FamilyName>
            <DateOfBirth>1918-10-12</DateOfBirth>
            <Nationality>American</Nationality>
        </Driver>
        <Driver driverId="arnold" url="http://en.wikipedia.org/wiki/Chuck_Arnold">
            <GivenName>Chuck</GivenName>
            <FamilyName>Arnold</FamilyName>
            <DateOfBirth>1926-05-30</DateOfBirth>
            <Nationality>American</Nationality>
        </Driver>
        <Driver driverId="arnoux" url="http://en.wikipedia.org/wiki/Ren%C3%A9_Arnoux">
            <GivenName>René</GivenName>
            <FamilyName>Arnoux</FamilyName>
            <DateOfBirth>1948-07-04</DateOfBirth>
            <Nationality>French</Nationality>
        </Driver>
        <Driver driverId="arundell" url="http://en.wikipedia.org/wiki/Peter_Arundell">
            <GivenName>Peter</GivenName>
            <FamilyName>Arundell</FamilyName>
            <DateOfBirth>1933-11-08</DateOfBirth>
            <Nationality>British</Nationality>
        </Driver>
        <Driver driverId="ascari" url="http://en.wikipedia.org/wiki/Alberto_Ascari">
            <GivenName>Alberto</GivenName>
            <FamilyName>Ascari</FamilyName>
            <DateOfBirth>1918-07-13</DateOfBirth>
            <Nationality>Italian</Nationality>
        </Driver>
    </DriverTable>
</MRData>

如何修复错误,并返回 ObservableCollection?

【问题讨论】:

  • 您的 XML 文档是否正确?它应该以&lt;?xml version="1.0" encoding="utf-8"?&gt; 开头。现在,它错过了开幕&lt;
  • XmlDocument xml = new XmlDocument(); xml.loadXML(strXML); // presto,你的 XML 在一个对象中。现在您可以随心所欲地运行 XSL、模式、xPath。
  • @Glorfindel 开头&lt; 是我编辑的复制/粘贴错误
  • @WilliamWalseth 我已经拥有content中的 XML

标签: c# xml


【解决方案1】:

你有很多问题:

  1. 您正在尝试将单个 MRData 元素反序列化为 ObservableCollection&lt;DriverData&gt;。这不是一个集合。为单个对象创建一个序列化器:

    XmlSerializer serializer = new XmlSerializer(typeof(DriverData));
    
  2. 您忽略了MRData 的命名空间,您需要更改XmlRoot 属性以包含以下内容:

    [XmlRoot("MRData", Namespace = "http://ergast.com/mrd/1.4")]
    
  3. 您的DriverData 类定义中缺少DriverTable。您还向所有其他属性添加了XmlElement 属性。这些是属性,而不是元素,所以应该有XmlAttribute 属性。完整的更正定义是:

    [XmlRoot("MRData", Namespace = "http://ergast.com/mrd/1.4")]
    public class DriverData
    {
        [XmlAttribute("series")]
        public string series { get; set; }
    
        [XmlAttribute("url")]
        public string url { get; set; }
    
        [XmlAttribute("limit")]
        public int limit { get; set; }
    
        [XmlAttribute("offset")]
        public int offset { get; set; }
    
        [XmlAttribute("total")]
        public int total { get; set; }
    
        [XmlElement("DriverTable")]
        public DriverTable DriverTable { get; set; }
    }
    
  4. Driver 上的两个属性同样具有 XmlElement 属性而不是 XmlAttribute 属性:

    [XmlAttribute("driverId")]
    public string driverId { get; set; }
    
    [XmlAttribute("url")]
    public string url { get; set; }
    
  5. 您的反序列化器使用StringReader 读取url。这是 URI,而不是您的内容。这应该是:

    using (TextReader reader = new StringReader(content))
    

在此处查看工作示例:https://dotnetfiddle.net/bkYr7Q

【讨论】:

    猜你喜欢
    • 2020-05-10
    • 2014-11-30
    • 1970-01-01
    • 1970-01-01
    • 2013-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多