user5615996
user5615996

Reputation:

Assign xml to c# struct

Is that possible to assgin xml file to struct?

I have xml file :

<?xml version="1.0" encoding="utf-8" ?>
<Questions> 
 <Question id="1">
     <QuestionText>Question 1?</QuestionText>
       <Ans1>Answer</Ans1>
       <Ans2>Answer</Ans2>
       <Ans3>Answer</Ans3>
       <Ans4>Answer</Ans4>
       <CorrectAnswer>2</CorrectAnswer>
     </Question>
  <Question id="2">
    <QuestionText>Question 2?</QuestionText>
      <Ans1>Answer</Ans1>
      <Ans2>Answer</Ans2>
      <Ans3>Answer</Ans3>
      <Ans4>Answer</Ans4>
    <CorrectAnswer>1</CorrectAnswer>
  </Question>
</Questions>

And c# code

public struct Question
    {
        public string questionText;
        public string[] answers;
        public int correctAnswerIndex;
        public Question(string questionText, string[] answers, int correctAnswerIndex)
        {
            this.questionText = questionText;
            this.answers = answers;
            this.correctAnswerIndex = correctAnswerIndex;
        }
    }

I would like to create new question foreach xml Question with id, and assign QuestionText from xml to my questionText from struct , struct answers = Ans1,2,3,4 , and correctAnswerIndex would be Correct Answer from xml. I would be grateful for every advice.

Upvotes: 1

Views: 3197

Answers (2)

Alex C
Alex C

Reputation: 137

Yes, System.Xml.Serialization is your friend. But it work best if your class have the same structure as your XML.

using System.Xml.Serialization;

public class Question
{
    [XmlElement("QuestionText")]
    public string QuestionText {get;set;}
    [XmlElement("Answer")]
    public string[] Answer {get;set;}
    [XmlElement("CorrectAnswer")]
    public string CorrectAnswer {get;set;}
}
[XmlRoot("Questions")
public class Questions
{
    [XmlElement("Question")]
    public Question[] Question {get;set;}
}

Or if you are always going to have 4 possibles answer you can like this too

public class Question
{
    [XmlElement("QuestionText")]
    public string QuestionText {get;set;}
    [XmlElement("Ans1")]
    public string Answer1 {get;set;}
    [XmlElement("Ans2")]
    public string Answer2 {get;set;}
    [XmlElement("Ans3")]
    public string Answer3 {get;set;}
    [XmlElement("Ans4")]
    public string Answer4 {get;set;}
    [XmlElement("CorrectAnswer")]
    public string CorrectAnswer {get;set;}
}
[XmlRoot("Questions")
public class Questions
{
    [XmlElement("Question")]
    public Question[] Question {get;set;}
}

And the Deserialize is rather easy after

Questions questions = null;
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Questions));
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(yourPathToFile);

string xmlString = xmlXrds.OuterXml.ToString();
byte[] buffer = ASCIIEncoding.UTF8.GetBytes(xmlString);
MemoryStream ms = new MemoryStream(buffer);

using (XmlReader reader = XmlReader.Create(ms))
{
   questions= (Questions)xmlSerializer.Deserialize(reader);
}

Or you can get it in stream right away

StreamReader reader = new StreamReader(yourXmlPath);
questions = (Questions)serializer.Deserialize(reader);

Hope it help

Upvotes: 1

bkdev
bkdev

Reputation: 432

You could use the XML Schema Definition tool (Xsd.exe) to auto generate the C# class from your XML file and use Deserialization to read the data from XML directly into the C# object

Steps:

  • generate xsd schema file from your xml file by using the Xsd.exe

    xsd Questions.xml /outputdir:C:\myDir  
    

This will generate Questions.xsd under the directory C:\myDir

  • generate c# class from the generated xsd file by using the same Xsd.exe

    xsd Questions.xsd /classes /outputdir:C:\myDir   
    

This will generate Questions.cs under the directory C:\myDir

  • use Deserialization to read from XML into C# object

    string XmlPath = @"C:\myDir\Questions.xml";
    YourQuestionClass qObj = null;
    XmlSerializer serializer = new XmlSerializer(typeof(YourQuestionClass));
    StreamReader reader = new StreamReader(XmlPath);
    qObj = (QuestionClass)serializer.Deserialize(reader);
    reader.Close();
    

Upvotes: 4

Related Questions