all groups > dotnet xml > june 2004 >
You're in the

dotnet xml

group:

XmlSerializer Collection with Collections


XmlSerializer Collection with Collections yurps NO[at]SPAM yahoo.co.uk
6/29/2004 8:56:26 AM
dotnet xml:
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 ) );
Re: XmlSerializer Collection with Collections Chris Lovett
6/30/2004 1:05:04 AM
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;
}



[quoted text, click to view]
Re: XmlSerializer Collection with Collections yurps NO[at]SPAM yahoo.co.uk
7/1/2004 3:52:10 AM
First, Thanks for your reply!

When I add [XmlIgnore] public OptionList optionlist
I then don't see any of the options that would normally
appear as children of the <optionlist>

As you can see I already have [XmlElement("Option")] above
my Option array....

Perhaps you mean I must move my Option array out of the OptionList
class...

Any further ideas or suggestions much appreciated...thanks!


[quoted text, click to view]
AddThis Social Bookmark Button