XML反序列化 C# 数组

3
我想导入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);
    }

}

我编辑了一个XML文档,但程序仍然无法工作。 - Zoran Đukić
嗨Zoran,我怀疑你需要使用[XmlText]属性来修饰Odgovor.odgovor属性。 - phoog
我添加了[XmlElement("Odgovor")],但程序仍然无法工作 :( - Zoran Đukić
当你使用[XmlElement("Odgovor")]修饰odgovor属性时,你告诉序列化器Odgovor元素包含一个类型为字符串的Odgovor元素,就像这样:<Odgovori><Odgovor tacan="true"><Odgovor>Madrid</Odgovor></Odgovor></Odgovori>。使用[XmlText]来指示odgovor属性对应于<Odgovor>元素的文本内容;这将匹配你的示例XML数据。 - phoog
再次问候Zoran,我今天没有时间测试这个,但我建议你尝试在内存中创建对象图,然后对其进行序列化。这将帮助您了解属性的工作原理。当该练习的输出与您的输入文件匹配时,您就会知道您拥有正确的属性。问题可能是您声明了一个根“Pitanja”和一个数组“Pitanja” - 您可以嵌套<Pitanja><Pitanja><Pitanje...>来检查,或者尝试将根声明为“Root”,并使用XML <Root><Pitanja><Pitanje...>。 - phoog
显示剩余3条评论
3个回答

1

我认为你需要在一个额外的元素中包装<Odgovor>元素,例如<Odgovori>


我已经编辑了XML文件和C#代码,我还添加了<Odgovori>,但程序仍然无法工作,你能帮我吗? - Zoran Đukić

0

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

[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; }
}

这里的被接受答案:将XML字符串转换为对象 将会告诉你如何生成一个完美的XML反序列化器


0

如果您不受限于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反序列化,您能帮我吗? - Zoran Đukić

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接