Re: XmlSerializer Collection with Collections

From: Chris Lovett (chris_at_!nospam!.net)
Date: 06/30/04


Date: Wed, 30 Jun 2004 01:05:04 -0700

What you can do here is hide the OptionList from serialization as follows:

          [XmlIgnore] public OptionList optionlist;

Then add a property that exposes the nested Option[] array:

           [XmlElement("Option")]
            public Option[] Options {
                get {
                    return optionlist.Options;
                }
                set {
                    optionlist.Options = value;
                }
            }

Note: Make sure you always test that you can round trip your XML by
serializing, then deserializing the result, then you can serialize again and
windiff the two serialized outputs. They should be identical. I also find
it handy to put the Seralize helper methods on the class being serialized,
in this case the QuestionList class, so they end up looking like this:

             public void Serialize(string filename) {
                XmlSerializer s = new XmlSerializer( typeof(
QuestionList ) );
                XmlTextWriter w = new XmlTextWriter(filename,
System.Text.Encoding.UTF8);
                w.Formatting = Formatting.Indented;
                s.Serialize( w, this );
                w.Close();
            }

            public static QuestionList Deserialize(string filename) {
                XmlSerializer s = new XmlSerializer( typeof(
QuestionList ) );
                XmlTextReader r = new XmlTextReader(filename);
                QuestionList result = (QuestionList)s.Deserialize(r);
                r.Close();
                return result;
            }

"magister" <yurps@yahoo.co.uk> wrote in message
news:984bebc3.0406290756.3e141a44@posting.google.com...
> Hello I got this working but it is not how I really want it, basically
> I have an xml file which has a root of <test> and can be filled with 3
> different types of <question> elements with different attributes, all
> share a base set of 4, one of the question types can have children
> with <option> elements, this is how the xml looks after
> serialization....
>
> If you notice there is an extra <SelectionList> around the <option>'s
> in the
> final <question>, how can I write my class so I don't have this extra
> <SelectionList> element....my class follows, you can see in the 2nd
> public Question constructor is where I add the OptionList type....any
> ideas, I know that really there is nothing wrong with having an extra
> <SelectionList> element around the <option> elements but I really want
> to know if my class is properly constucted.
>
>
> <?xml version="1.0" encoding="utf-8"?>
> <Test xmlns:xsd="http://www.w3.org/2001/XMLSchema"
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
> <Question text="What is love?" type="Input" score="3"
> mandatory="false" multiLine="false" maxlength="0" minlength="0"
> validate="None" />
> <Question text="This is better than sliced bread?" type="Input"
> score="9" mandatory="false" multiLine="false" maxlength="0"
> minlength="0" validate="None" />
> <Question text="input question" type="Input" score="8"
> mandatory="true" multiLine="true" maxlength="7" minlength="1"
> initialvalue="hello" validate="Currency" answer="this is the answer"
> />
> <Question text="What is square root of 2?" type="selection"
> score="3" mandatory="false" multiLine="false" maxlength="0"
> minlength="0" validate="None">
> <SelectionList>
> <Option text="first" selected="true" tooltip="hovertext"
> answer="false" />
> <Option text="second" selected="true" tooltip="hovertext"
> answer="true" />
> </SelectionList>
> </Question>
> </Test>
>
> using System;
> using System.Collections;
> using System.IO;
> using System.Xml;
> using System.Xml.Serialization;
>
> namespace TestCreator
> {
> public class TestSerializer
> {
> public TestSerializer()
> {
> //
> // TODO: Add constructor logic here
> //
> }
>
> //test class which will be serialized
> [XmlRoot("Test")]
> public class QuestionList
> {
> private ArrayList listQuestions;
>
> public QuestionList()
> {
> listQuestions = new ArrayList();
> }
>
> [XmlElement("Question")]
> public Question[] Questions
> {
> get
> {
> Question[] questions = new Question[ listQuestions.Count ];
> listQuestions.CopyTo( questions );
> return questions;
> }
> set
> {
> if( value == null ) return;
> Question[] questions = (Question[])value;
> listQuestions.Clear();
> foreach( Question question in questions )
> listQuestions.Add( question );
> }
> }
>
> public int AddQuestion( Question question )
> {
> return listQuestions.Add( question );
> }
> }
>
> public class OptionList
> {
> private ArrayList listOptions;
>
> public OptionList()
> {
> listOptions = new ArrayList();
> }
> [XmlElement("Option")]
> public Option[] Options
> {
> get
> {
> Option[] options = new Option[ listOptions.Count ];
> listOptions.CopyTo( options );
> return options;
> }
> set
> {
> if( value == null ) return;
> Option[] options = (Option[])value;
> listOptions.Clear();
> foreach( Option option in options )
> listOptions.Add( option );
> }
> }
> public int AddOption( Option option )
> {
> return listOptions.Add( option );
> }
> }
>
> public class Question
> {
> [XmlAttribute("text")] public string questionText;
> [XmlAttribute("type")] public string type;
> [XmlAttribute("score")] public int score;
> [XmlAttribute("mandatory")] public bool mandatory;
> [XmlAttribute("multiLine")] public bool multiline;
> [XmlAttribute("maxlength")] public int maxlength;
> [XmlAttribute("minlength")] public int minlength;
> [XmlAttribute("initialvalue")] public string initialvalue;
> [XmlAttribute("validate")] public Validation validate;
> [XmlAttribute("answer")] public string answer;
> [XmlElement("SelectionList")] public OptionList optionlist;
> //[XmlElement("go")] public ArrayList optionlist;
>
> public enum Validation
> {
> None,
> Date,
> Integer,
> Currency
> }
> public Question()
> {
> }
>
> public Question( string QuestionText, string Type, int Score, bool
> Mandatory, OptionList opl )
> {
> questionText = QuestionText;
> type = Type;
> score = Score;
> mandatory = Mandatory;
> optionlist = opl;
> }
>
> public Question( string QuestionText, string Type, int Score, bool
> Mandatory, bool MultiLine, int MaxLength, int MinLength, string
> InitialValue, Validation Validate, string Answer)
> {
> questionText = QuestionText;
> type = Type;
> score = Score;
> mandatory = Mandatory;
> multiline = MultiLine;
> maxlength = MaxLength;
> minlength = MinLength;
> initialvalue = InitialValue;
> validate = Validate;
> answer = Answer;
> }
> }
>
> public class Option
> {
> [XmlAttribute("text")] public string label;
> [XmlAttribute("selected")] public bool selected;
> [XmlAttribute("tooltip")] public string tooltip;
> [XmlAttribute("answer")] public bool answer;
>
> public Option()
> {
> }
>
> public Option( string Label, bool Selected, string Tooltip, bool
> Answer )
> {
> label = Label;
> selected = Selected;
> tooltip = Tooltip;
> answer = Answer;
> }
> }
>
> public static void Serialize(QuestionList myList)
> {
> XmlSerializer s = new XmlSerializer( typeof( QuestionList ) );
> TextWriter w = new StreamWriter( @"c:\list.xml" );
> s.Serialize( w, myList );
> w.Close();
> }
> }
> }
>
> To test do this:
> TestSerializer.QuestionList myList = new
> TestSerializer.QuestionList();
> myList.AddQuestion( new TestSerializer.Question("What is
> love?","Input",3,false ) );
>
> TestSerializer.OptionList opl = new TestSerializer.OptionList();
> opl.AddOption( new TestSerializer.Option("first",true,"hovertext",false));
> opl.AddOption( new TestSerializer.Option("second",true,"hovertext",true));
> myList.AddQuestion( new TestSerializer.Question("What is the square
> root of 2?","selection",3,false,opl ) );
> TestSerializer.Serialize(myList);



Relevant Pages

  • XmlSerializer Collection with Collections
    ... public class TestSerializer ... public int AddQuestion(Question question) ... public Question(string QuestionText, string Type, int Score, bool ...
    (microsoft.public.dotnet.xml)
  • Re: invoke
    ... String theClass) ... public class Ehg extends Applet ...
    (comp.lang.java.help)
  • Re: XmlSerializer Collection with Collections
    ... > What you can do here is hide the OptionList from serialization as follows: ... >> public class TestSerializer ... >> public Question(string QuestionText, string Type, int Score, bool ...
    (microsoft.public.dotnet.xml)
  • MVC and subClass
    ... B(int ii, String ss) ... public int getI() ... public class D1 extends B ... public static void main ...
    (comp.object)
  • Re: Need XML Serialization Help (Long Post!)
    ... > learn) and XML serialization is all new ground for me. ... > Private Sub CreateXML(ByVal filename As String) ... > Public Class ShowBase ...
    (microsoft.public.dotnet.xml)