Let's say we need to create an XML document that looks something like this:
<?xml version="1.0" encoding="utf-8"?>
<Form>
<Name>Name</Name>
<Description>Short Description</Description>
<Variables>
<Variable>
<Name>VarName</Name>
<Description>Short Description</Description>
<Type>ListDataSource</Type>
<Values>
<Value>
<ValueMember>1</ValueMember>
<DisplayMember>New</DisplayMember>
</Value>
<Value>
<ValueMember>2</ValueMember>
<DisplayMember>Old</DisplayMember>
</Value>
</Values>
</Variable>
</Variables>
</Form>
You get the picture, right?
Well, supposing we needed to create these over and over and over and these XML documents are fed into another program for processing. Perfect time to use serialization, right? Right. But that is sometimes easier said that done. Here's how I go about it.
Step 1: You will need a class the "root level," which in this case would be "FormLayout" your class declaration would look like this:
[Serializable]
public class FormLayout
Step 2: Create a class for every element that has its own sub-elements. In our example we would need to create a class for both "Variable" and "Value." Their class declarations would look like this:
[Serializable]
public class Variable
[Serializable]
public class Value
Step 3: Starting with the highest (most indented?) elements, create a public property for each element under it. In our case we would start by creating a public property for "ValueMember" and "DisplayMember" (encapsulating private variables of course):
public string ValueMember
{
get { return _valueMember; }
set { _valueMember = value; }
}
public string DisplayMember
{
get { return _displayMember; }
set { _displayMember = value; }
}
Continue with the rest of the classes in the same way...
Step 4: When you arrive at a "Repeating" element, make its declaration in its parent class as an array. So for instance a "Variable" object would have a repeating list of "Value" elements, so we would create a public property in the "Variable" class that was an array of type "Value". Like so:
public Value[] Values
{
get { return _values; }
set { _values = value; }
}
NOTE!!!!: It is important at this step to make sure your property names (in this case "Values" is the element that you want surrounding your repeating elements. We named ours "Values" here because we want our XML Doc to look like:
<Values>
<Value>
...
</Value>
<Value>
...
</Value>
</Values>
Step 5: Mark all of your array properties with the
[XmlArrayItem(ElementName="Foo", Type=typeof(Bar)] attribute. Where "Foo" is what you want your repeating elements to be, and Bar is the type of array. In our case we want ElementName="Value" (see XML Snippet above) and Bar = Value. So our Value[] array in our "Variable" class would look like this:
[XmlArrayItem(ElementName="Value", Type=typeof(Value))]
public Value[] Values
{
get { return _values; }
set { _values = value; }
}
Serialize Me!
NOTE: You'll need a using System.Xml.Serialization and System.IO for this to work
public void Run()
{
FileStream _fileStream =
new FileStream("c:\file.xml", FileMode.Create);
FormLayout _formLayout = new FormLayout();
// Do something that would fill the FormLayout's properties...
XmlSerializer _xmlSerializer =
new XmlSerializer(typeof(FormLayout));
_xmlSerializer.Serialize(_fileStream, _formLayout);
}
Barring any complications, you should have an XML Document at "C:\file.xml" that follows the structure you need exactly.
Problems Foreseen:
- Make sure every class is labeled public, otherwise the XmlSerializer can't see it.
- Make sure every class has an empty constructor, even if you won't be using it. This is what the XmlSerializer class uses to serialize and deserialize objects.
- If for some reason you need to have public properties in the classes that you don't want to show up when serialized, mark them with the [XmlIgnore] attribute.
0 comments:
Post a Comment