XML反序列化C#数组

Posted

技术标签:

【中文标题】XML反序列化C#数组【英文标题】:XML deserialization C# array 【发布时间】:2012-04-10 11:35:48 【问题描述】:

我想导入 XML 文件中的测验问题。 XML中有问题列表,每个问题都有一个答案列表。有人可以帮助我并告诉我哪里错了吗?

XML 文件“pitanja.xml”:

<?xml version="1.0" encoding="utf-8"?>

<Pitanja>

  <Pitanje>

    <TekstPitanja>
      U kojoj državi se nalazi Ajfelova kula?
    </TekstPitanja>

    <Odgovori>
      <Odgovor tacan = "true" > Francuska </Odgovor>
      <Odgovor> Nemačka </Odgovor>
      <Odgovor> Španija </Odgovor>
      <Odgovor> Italija </Odgovor>
    </Odgovori>

  </Pitanje>

  <Pitanje>

    <TekstPitanja>
      U kom gradu se nalazi Big Ben?
    </TekstPitanja>

    <Odgovori>
      <Odgovor tacan = "true" > London </Odgovor>
      <Odgovor> Pariz </Odgovor>
      <Odgovor> Lisabon </Odgovor>
      <Odgovor> Madrid </Odgovor>
    </Odgovori>

  </Pitanje>

  <Pitanje>

    <TekstPitanja>
      Glavni grad Španije je?
    </TekstPitanja>

    <Odgovori>
      <Odgovor tacan = "true" > Madrid </Odgovor>
      <Odgovor> Barselona </Odgovor>
      <Odgovor> Lisabon </Odgovor>
      <Odgovor> Rim </Odgovor>
    </Odgovori>

  </Pitanje>

</Pitanja>

C#代码:

[XmlRoot("Pitanja")]
public class Pitanja

    [XmlArray("Pitanja")]
    [XmlArrayItem("Pitanje")]
    public List<Pitanje> SvaPitanja  get; set; 



public class Pitanje

    [XmlElement("TekstPitanja")]
    public string TekstPitanja  get; set;  // Tekst pitanja

    [XmlArray("Odgovori")]
    [XmlArrayItem("Odgovor")]
    public List<Odgovor> Odgovori  get; set;     // Niz odgovora na pitanje



public class Odgovor

    [XmlText]
    public string odgovor  get; set; 

    [XmlAttribute]
    public Boolean tacan  get; set; 



public void ucitajpitanja()

    XmlSerializer dsr = new XmlSerializer(typeof(Pitanja));
    using (System.IO.StreamReader str = new System.IO.StreamReader(@"C:\pitanja.xml"))
    
        pitanja = (Pitanja)dsr.Deserialize(str);
    


【问题讨论】:

XmlSerializer 正在寻找(例如)&lt;ArrayOfOdgovor&gt;&lt;Odgovor /&gt;&lt;Odgovor /&gt;&lt;/ArrayOfOdgovor&gt;。它会将&lt;ArrayOfFoo /&gt; 反序列化为Foo[] 数组或List&lt;Foo&gt;。但我不知道在源代码中没有ArrayOfFoo 元素的情况下如何让它做到这一点。 我编辑了一个 XML 文档,但程序仍然无法运行。 嗨 Zoran,我怀疑您需要用 [XmlText] 属性装饰 Odgovor.odgovor 属性。 我添加了 [XmlElement("Odgovor")],但程序仍然无法运行 :( 当您使用[XmlElement("Odgovor")] 装饰 odgovor 属性时,您是在告诉序列化程序 Odgovor 元素包含一个字符串类型的 Odgovor 元素,即:&lt;Odgovori&gt;&lt;Odgovor tacan = "true"&gt;&lt;Odgovor&gt;Madrid&lt;/Odgovor&gt;&lt;/Odgovor&gt;&lt;/Odgovori&gt;。使用[XmlText]表示odgovor属性对应&lt;Odgovor&gt;元素的Text内容;这将匹配您的示例 XML 数据。 【参考方案1】:

我认为您需要将 元素包装在一个附加元素中 - 例如

【讨论】:

我已经编辑了 XML 文件和 C# 代码,我还添加了 ,但程序仍然无法运行,您能帮帮我吗?【参考方案2】:

数组和对象都必须有反序列化器。

[Serializable]
public class Pitanje 
    public Pitanje()  

    [XmlAttribute]
    public Boolean tacan  get; set; 
 

[Serializable]
[XmlRoot("Pitanja", Namespace = "", IsNullable = false)]
public class PitanjaModelList 
   [XmlElementAttribute("Pitanje", Form = XmlSchemaForm.Unqualified)]
   public List<Pitanje> PitanjaList  get; set; 

此处接受的答案:Convert XML String to Object 将告诉您如何为您的 XML 生成完美的反序列化器

【讨论】:

【参考方案3】:

如果您不限于 XML 序列化并且您的目标只是将 XML 文件读入您​​的对象模型,那么作为替代方案,我建议考虑使用 Linq to XML。

作为示例,可以使用以下代码将您的 XML 文件读入您​​的类:

    var result = new Pitanja
    
        SvaPitanja = (from pitanje in System.Xml.Linq.XDocument.Load(@"C:\pitanja.xml").Root.Elements()
                        select new Pitanje
                        
                            TekstPitanja = pitanje.Element("TekstPitanja").Value.Trim(),
                            Odgovori = (from odgovor in pitanje.Elements("Odgovor")
                                        let tacanAttribute = odgovor.Attribute("tacan")
                                        select new Odgovor
                                        
                                            odgovor = odgovor.Value.Trim(),
                                            tacan = tacanAttribute != null && tacanAttribute.Value == "true"
                                        ).ToList()
                        ).ToList()
    ;

【讨论】:

谢谢你的帮助,但我必须使用 XML 反序列化,你能帮我吗?

以上是关于XML反序列化C#数组的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中为 WCF 服务反序列化简单的 XML 数组对象

C#将不同类型的xml数组反序列化为多个数组

WCF XML反序列化不填充数组

C# XML序列化和反序列化(XmlSerializer)

从 XML 文档创建的 Json 反序列化到 POCO 不适用于数组

在C#中序列化和反序列化之间保留xml元素的顺序