3

I want to import questions for quiz which are in XML file. There are list of questions in XML, and every questions have a list of answers. Can someone help me and tell me where I´m wrong?

XML file "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# code:

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

}
Zoran Đukić
  • 767
  • 1
  • 6
  • 12
  • The XmlSerializer is looking for (for example) ``. It will deserialize an `` into a `Foo[]` array or a `List`. But I don't know of a way to get it to do that in the absence of `ArrayOfFoo` elements in the source. – phoog Mar 26 '12 at 23:00
  • I edit a XML document, but the program still does not work. – Zoran Đukić Mar 27 '12 at 17:53
  • Hi Zoran, I suspect you need to decorate the `Odgovor.odgovor` property with the `[XmlText]` attribute. – phoog Mar 27 '12 at 18:02
  • I add [XmlElement("Odgovor")], but the program still does not work :( – Zoran Đukić Mar 27 '12 at 20:23
  • when you decorate the odgovor property with `[XmlElement("Odgovor")]` you're telling the serializer that the Odgovor element contains an Odgovor element of type string, that is, something like this: `Madrid`. Use `[XmlText]` to indicate that the `odgovor` property corresponds to the Text content of the `` element; that will match your sample XML data. – phoog Mar 27 '12 at 20:27
  • Thanks for your help. This is the first time I use XML and Deserialization, because that I make many errors. I understand what you wrote and I was edit code as you said. But, unfortunately, the program still does not load the XML. – Zoran Đukić Mar 27 '12 at 20:54
  • Hi again Zoran, I don't have time to test this today, but I can suggest that you try creating your object graph in memory and then serializing it. This will help you understand how the attributes work. When the output of that exercise matches your input file, you'll know that you have the correct attributes. The problem might be that you've declared both a root "Pitanja" and an array "Pitanja" -- you can nest ` – phoog Mar 27 '12 at 21:02
  • I add ... and XML loaded perfectly. Thank you very much for helping. My problem is solved! – Zoran Đukić Mar 27 '12 at 21:29

3 Answers3

1

I think you need to wrap the <Odgovor> elements in an additional element - e.g. <Odgovori>

0

Both the Array and the object must have deserializers.

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

The accepted answer here: Convert XML String to Object will give you how to generate a perfect deserializer for your XML

Community
  • 1
  • 1
Hupperware
  • 979
  • 1
  • 6
  • 15
0

If you are not restricted to XML Serialization and your objective is simply to read the XML file into your object model, then as an alternative I suggest considering using Linq to XML.

As a sample, your XMLfile could be read into your classes using the following code:

    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()
    };
000
  • 807
  • 7
  • 14