public class XmlSerializer
|
The data in your objects is described using programming language constructs like classes, fields, properties, primitive types, arrays, and even embedded XML in the form of XmlElement or XmlAttribute objects. You have the option of creating your own classes, annotated with attributes, or using the the conceptual topic at MSDN: xmlschemadefinitiontoolxsdexe to generate the classes based on an existing XML Schema definition (XSD) document. If you have an XML Schema, you can run the Xsd.exe to produce a set of classes that are strongly typed to the schema and annotated with attributes to adhere to the schema when serialized.
To transfer data between objects and XML requires a mapping from the programming language constructs to XML Schema and vice versa. The XmlSerializer, and related tools like Xsd.exe, provide the bridge between these two technologies at both design time and run time. At design time, use the Xsd.exe to produce an XML Schema document (.xsd) from your custom classes, or to produce classes from a given schema. In either case, the classes are annotated with custom attributes to instruct the XmlSerializer how to map between the XML Schema system to the common language runtime. At run time, instances of the classes can be serialized into XML documents that follow the given schema. Likewise, these XML documents can be deserialized into run time objects. (Note that the XML Schema is optional, and not needed at design time or run time.)
To control the generated XML, you can apply special attributes to classes and members. For example, to specify a different XML element name, apply an XmlElementAttribute to a public field or property, and set the XmlElementAttribute.ElementName property. For a list of all attributes, see the conceptual topic at MSDN: attributesthatcontrolserialization.
If the XML generated must conform to section 5 of the World Wide Consortium (www.w3.org) document, "Simple Object Access Protocol (SOAP) 1.1", you must construct the XmlSerializer with an XmlTypeMapping. To further control the encoded SOAP XML, use the attributes listed in the conceptual topic at MSDN: attributesthatcontrolsoapencodedserialization.
With the XmlSerializer you can take advantage of working with strongly typed classes and still have the flexibility of XML. Using fields or properties of type XmlElement, XmlAttribute or XmlNode in your strongly typed classes, you can read parts of the XML document directly into XML objects.
If you work with extensible XML schemas, you can also use the XmlAnyElementAttribute and XmlAnyAttributeAttribute attributes to serialize and deserialize elements or attributes that are not found in the original schema. To use the objects, apply an XmlAnyElementAttribute to a field that returns an array of XmlElement objects, or apply an XmlAnyAttributeAttribute to a field that returns an array of XmlAttribute objects.
If a property or field returns a complex object (such as an array or a class instance), the XmlSerializer converts it to an element nested within the main XML document. For example, the first class in the following C# code returns an instance of the second class.
public class MyClass { public MyObject MyObjectProperty; } public class MyObject { public string ObjectName; }
The serialized, XML output looks like this:
<MyClass> <MyObjectProperty> <Objectname>My String</ObjectName> </MyObjectProperty> </MyClass>
You can also override the serialization of any set of objects and their fields and properties by creating one of the appropriate attributes, and adding it to an XmlAttributes. Overriding serialization in this way has two uses: first, you can control and augment the serialization of objects found in a DLL, even if you don't have access to the source; second, you can create one set of serializable classes, but serialize the objects in multiple ways. For more details, see the XmlAttributeOverrides class.
To serialize an object, call the XmlSerializer.Serialize method. To deserialize an object, call the XmlSerializer.Deserialize method.
To add XML namespaces to an XML document, see XmlSerializerNamespaces.
PurchaseOrder
and
Test
. The
PurchaseOrder
class contains information about a single purchase. The
Test
class contains the methods that create the purchase order, and that read the created purchase order.using System; using System.Xml; using System.Xml.Serialization; using System.IO; /* The XmlRootAttribute allows you to set an alternate name (PurchaseOrder) of the XML element, the element namespace; by default, the XmlSerializer uses the class name. The attribute also allows you to set the XML namespace for the element. Lastly, the attribute sets the IsNullable property, which specifies whether the xsi:null attribute appears if the class instance is set to a null reference. */ [XmlRootAttribute("PurchaseOrder", Namespace="http://www.cpandl.com", IsNullable = false)] public class PurchaseOrder { public Address ShipTo; public string OrderDate; /* The XmlArrayAttribute changes the XML element name from the default of "OrderedItems" to "Items". */ [XmlArrayAttribute("Items")] public OrderedItem[] OrderedItems; public decimal SubTotal; public decimal ShipCost; public decimal TotalCost; } public class Address { /* The XmlAttribute instructs the XmlSerializer to serialize the Name field as an XML attribute instead of an XML element (the default behavior). */ [XmlAttribute] public string Name; public string Line1; /* Setting the IsNullable property to false instructs the XmlSerializer that the XML attribute will not appear if the City field is set to a null reference. */ [XmlElementAttribute(IsNullable = false)] public string City; public string State; public string Zip; } public class OrderedItem { public string ItemName; public string Description; public decimal UnitPrice; public int Quantity; public decimal LineTotal; /* Calculate is a custom method that calculates the price per item, and stores the value in a field. */ public void Calculate() { LineTotal = UnitPrice * Quantity; } } public class Test { public static void Main() { // Read and write purchase orders. Test t = new Test(); t.CreatePO("po.xml"); t.ReadPO("po.xml"); } private void CreatePO(string filename) { // Create an instance of the XmlSerializer class; // specify the type of object to serialize. XmlSerializer serializer = new XmlSerializer(typeof(PurchaseOrder)); TextWriter writer = new StreamWriter(filename); PurchaseOrder po=new PurchaseOrder(); // Create an address to ship and bill to. Address billAddress = new Address(); billAddress.Name = "Teresa Atkinson"; billAddress.Line1 = "1 Main St."; billAddress.City = "AnyTown"; billAddress.State = "WA"; billAddress.Zip = "00000"; // Set ShipTo and BillTo to the same addressee. po.ShipTo = billAddress; po.OrderDate = System.DateTime.Now.ToLongDateString(); // Create an OrderedItem object. OrderedItem i1 = new OrderedItem(); i1.ItemName = "Widget S"; i1.Description = "Small widget"; i1.UnitPrice = (decimal) 5.23; i1.Quantity = 3; i1.Calculate(); // Insert the item into the array. OrderedItem [] items = {i1}; po.OrderedItems = items; // Calculate the total cost. decimal subTotal = new decimal(); foreach(OrderedItem oi in items) { subTotal += oi.LineTotal; } po.SubTotal = subTotal; po.ShipCost = (decimal) 12.51; po.TotalCost = po.SubTotal + po.ShipCost; // Serialize the purchase order, and close the TextWriter. serializer.Serialize(writer, po); writer.Close(); } protected void ReadPO(string filename) { // Create an instance of the XmlSerializer class; // specify the type of object to be deserialized. XmlSerializer serializer = new XmlSerializer(typeof(PurchaseOrder)); /* If the XML document has been altered with unknown nodes or attributes, handle them with the UnknownNode and UnknownAttribute events.*/ serializer.UnknownNode+= new XmlNodeEventHandler(serializer_UnknownNode); serializer.UnknownAttribute+= new XmlAttributeEventHandler(serializer_UnknownAttribute); // A FileStream is needed to read the XML document. FileStream fs = new FileStream(filename, FileMode.Open); // Declare an object variable of the type to be deserialized. PurchaseOrder po; /* Use the Deserialize method to restore the object's state with data from the XML document. */ po = (PurchaseOrder) serializer.Deserialize(fs); // Read the order date. Console.WriteLine ("OrderDate: " + po.OrderDate); // Read the shipping address. Address shipTo = po.ShipTo; ReadAddress(shipTo, "Ship To:"); // Read the list of ordered items. OrderedItem [] items = po.OrderedItems; Console.WriteLine("Items to be shipped:"); foreach(OrderedItem oi in items) { Console.WriteLine("\t"+ oi.ItemName + "\t" + oi.Description + "\t" + oi.UnitPrice + "\t" + oi.Quantity + "\t" + oi.LineTotal); } // Read the subtotal, shipping cost, and total cost. Console.WriteLine("\t\t\t\t\t Subtotal\t" + po.SubTotal); Console.WriteLine("\t\t\t\t\t Shipping\t" + po.ShipCost); Console.WriteLine("\t\t\t\t\t Total\t\t" + po.TotalCost); } protected void ReadAddress(Address a, string label) { // Read the fields of the Address object. Console.WriteLine(label); Console.WriteLine("\t"+ a.Name ); Console.WriteLine("\t" + a.Line1); Console.WriteLine("\t" + a.City); Console.WriteLine("\t" + a.State); Console.WriteLine("\t" + a.Zip ); Console.WriteLine(); } protected void serializer_UnknownNode (object sender, XmlNodeEventArgs e) { Console.WriteLine("Unknown Node:" + e.Name + "\t" + e.Text); } protected void serializer_UnknownAttribute (object sender, XmlAttributeEventArgs e) { System.Xml.XmlAttribute attr = e.Attr; Console.WriteLine("Unknown attribute " + attr.Name + "='" + attr.Value + "'"); } }
ctor #2 | Overloaded:.ctor(Type type) Initializes a new instance of the XmlSerializer class that can serialize objects of the specified type into XML documents, and vice versa. |
ctor #3 | Overloaded:.ctor(XmlTypeMapping xmlTypeMapping) Initializes an instance of the XmlSerializer class using an object that maps one type to another. |
ctor #4 | Overloaded:.ctor(Type type, string defaultNamespace) Initializes a new instance of the XmlSerializer class that can serialize objects of the specified type into XML documents, and vice versa. Specifies the default namespace for all the XML elements. |
ctor #5 | Overloaded:.ctor(Type type, Type[] extraTypes) Initializes a new instance of the XmlSerializer class that can serialize objects of the specified type into XML documents, and vice versa. If a property or field returns an array, the extraTypes parameter specifies objects that can be inserted into the array. |
ctor #6 | Overloaded:.ctor(Type type, XmlAttributeOverrides overrides) Initializes a new instance of the XmlSerializer class that can serialize objects of the specified type into XML documents, and vice versa. Each object to be serialized can itself contain instances of classes, which this overload can override with other classes. |
ctor #7 | Overloaded:.ctor(Type type, XmlRootAttribute root) Initializes a new instance of the XmlSerializer class that can serialize objects of the specified type into XML documents, and vice versa. Specifies the class to use as the XML root element. |
ctor #8 | Overloaded:.ctor(Type type, XmlAttributeOverrides overrides, Type[] extraTypes, XmlRootAttribute root, string defaultNamespace) Initializes a new instance of the XmlSerializer class that can serialize objects of type Object into XML document instances, and vice versa. Each object to be serialized can itself contain instances of classes, which this overload can override with other classes. This overload also specifies the default namespace for all the XML elements, and the class to use as the XML root element. |
CanDeserialize | Gets a value indicating whether this XmlSerializer can deserialize a specified XML document. |
Deserialize | Overloaded:Deserialize(Stream stream) Deserializes the XML document contained by the specified Stream. |
Deserialize | Overloaded:Deserialize(TextReader textReader) Deserializes the XML document contained by the specified TextReader. |
Deserialize | Overloaded:Deserialize(XmlReader xmlReader) Deserializes the XML document contained by the specified XmlReader. |
Equals (inherited from System.Object) |
See base class member description: System.Object.Equals Derived from System.Object, the primary base class for all objects. |
FromMappings | |
FromTypes | Returns an array of XmlSerializer objects created from an array of types. |
GetHashCode (inherited from System.Object) |
See base class member description: System.Object.GetHashCode Derived from System.Object, the primary base class for all objects. |
GetType (inherited from System.Object) |
See base class member description: System.Object.GetType Derived from System.Object, the primary base class for all objects. |
Serialize | Overloaded:Serialize(Stream stream, object o) Serializes the specified Object and writes the XML document to a file using the specified Stream. |
Serialize | Overloaded:Serialize(TextWriter textWriter, object o) Serializes the specified Object and writes the XML document to a file using the specified TextWriter. |
Serialize | Overloaded:Serialize(XmlWriter xmlWriter, object o) Serializes the specified Object and writes the XML document to a file using the specified XmlWriter. |
Serialize | Overloaded:Serialize(Stream stream, object o, XmlSerializerNamespaces namespaces) Serializes the specified Object and writes the XML document to a file using the specified Stream, referencing the specified namespaces. |
Serialize | Overloaded:Serialize(TextWriter textWriter, object o, XmlSerializerNamespaces namespaces) Serializes the specified Object and writes the XML document to a file using the specified TextWriter, referencing the specified namespaces. |
Serialize | Overloaded:Serialize(XmlWriter xmlWriter, object o, XmlSerializerNamespaces namespaces) Serializes the specified Object and writes the XML document to a file using the specified XmlWriter, referencing the specified namespaces. |
ToString (inherited from System.Object) |
See base class member description: System.Object.ToString Derived from System.Object, the primary base class for all objects. |
UnknownAttribute | Occurs when the XmlSerializer encounters an XML attribute of unknown type during deserialization. |
UnknownElement | Occurs when the XmlSerializer encounters an XML element of unknown type during deserialization. |
UnknownNode | Occurs when the XmlSerializer encounters an XML node of unknown type during deserialization. |
UnreferencedObject | Occurs during deserialization of a SOAP-encoded XML stream, when the XmlSerializer encounters a recognized type that is not used (unreferenced). |
ctor #1 | Overloaded:.ctor() Default constructor. This constructor is called by derived class constructors to initialize state in this type.Constructs a new instance of the XmlSerializer class. |
CreateReader | Returns an object used to read the XML document to be serialized. |
CreateWriter | Supports the Shared Source CLI infrastructure and is not intended to be used directly from your code |
Deserialize | Overloaded:Deserialize(XmlSerializationReader reader) Supports the Shared Source CLI infrastructure and is not intended to be used directly from your code |
Finalize (inherited from System.Object) |
See base class member description: System.Object.Finalize Derived from System.Object, the primary base class for all objects. |
MemberwiseClone (inherited from System.Object) |
See base class member description: System.Object.MemberwiseClone Derived from System.Object, the primary base class for all objects. |
Serialize | Overloaded:Serialize(object o, XmlSerializationWriter writer) Supports the Shared Source CLI infrastructure and is not intended to be used directly from your code |
Hierarchy:
protected XmlSerializer(); |
public XmlSerializer( |
type
private void SerializeObject(string filename) { XmlSerializer serializer = new XmlSerializer(typeof(OrderedItem)); // Create an instance of the class to be serialized. OrderedItem i = new OrderedItem(); // Set the public property values. i.ItemName = "Widget"; i.Description = "Regular Widget"; i.Quantity = 10; i.UnitPrice = (decimal) 2.30; // Writing the document requires a TextWriter. TextWriter writer = new StreamWriter(filename); // Serialize the object, and close the TextWriter. serializer.Serialize(writer, i); writer.Close(); } // This is the class that will be serialized. public class OrderedItem { public string ItemName; public string Description; public decimal UnitPrice; public int Quantity; }
public XmlSerializer( |
xmlTypeMapping
Group
. The serialization of the
GroupName
,
IgnoreThis
fields, and the members of the GroupType enumeration are overridden. In the
CreateOverrideSerializer
method, a SoapAttributeOverrides object is created, and for each overridden member or enumeration, a SoapAttributes object is created with the appropriate property set, and added to the SoapAttributeOverrides object. An XmlMapping object is created using the SoapAttributeOverrides object, and that XmlMapping object is used to create the XmlSerializer that overrides the default serialization.using System; using System.IO; using System.Text; using System.Xml; using System.Xml.Serialization; using System.Xml.Schema; public class Group { [SoapAttribute (Namespace = "http://www.cpandl.com")] public string GroupName; [SoapAttribute(DataType = "base64Binary")] public Byte [] GroupNumber; [SoapAttribute(DataType = "date", AttributeName = "CreationDate")] public DateTime Today; [SoapElement(DataType = "nonNegativeInteger", ElementName = "PosInt")] public string PostitiveInt; // This is ignored when serialized unless it's overridden. [SoapIgnore] public bool IgnoreThis; public GroupType Grouptype; public Vehicle MyVehicle; // The SoapInclude allows the method to return a Car. [SoapInclude(typeof(Car))] public Vehicle myCar(string licNumber) { Vehicle v; if(licNumber == "") { v = new Car(); v.licenseNumber = "!!!!!!"; } else { v = new Car(); v.licenseNumber = licNumber; } return v; } } // SoapInclude allows Vehicle to accept Car type. [SoapInclude(typeof(Car))] public abstract class Vehicle { public string licenseNumber; public DateTime makeDate; } public class Car: Vehicle { } public enum GroupType { // These enums can be overridden. [SoapEnum("Small")] A, [SoapEnum("Large")] B } public class Run { public static void Main() { Run test = new Run(); test.SerializeOriginal("SoapOriginal.xml"); test.SerializeOverride("SoapOverrides.xml"); test.DeserializeOriginal("SoapOriginal.xml"); test.DeserializeOverride("SoapOverrides.xml"); } public void SerializeOriginal(string filename) { // Create an instance of the XmlSerializer class. XmlTypeMapping myMapping = (new SoapReflectionImporter().ImportTypeMapping( typeof(Group))); XmlSerializer mySerializer = new XmlSerializer(myMapping); Group myGroup=MakeGroup(); // Writing the file requires a TextWriter. XmlTextWriter writer = new XmlTextWriter(filename, Encoding.UTF8); writer.Formatting = Formatting.Indented; writer.WriteStartElement("wrapper"); // Serialize the class, and close the TextWriter. mySerializer.Serialize(writer, myGroup); writer.WriteEndElement(); writer.Close(); } public void SerializeOverride(string filename) { // Create an instance of the XmlSerializer class // that overrides the serialization. XmlSerializer overRideSerializer = CreateOverrideSerializer(); Group myGroup=MakeGroup(); // Writing the file requires a TextWriter. XmlTextWriter writer = new XmlTextWriter(filename, Encoding.UTF8); writer.Formatting = Formatting.Indented; writer.WriteStartElement("wrapper"); // Serialize the class, and close the TextWriter. overRideSerializer.Serialize(writer, myGroup); writer.WriteEndElement(); writer.Close(); } private Group MakeGroup(){ // Create an instance of the class that will be serialized. Group myGroup = new Group(); // Set the object properties. myGroup.GroupName = ".NET"; Byte [] hexByte = new Byte[2]{Convert.ToByte(100), Convert.ToByte(50)}; myGroup.GroupNumber = hexByte; DateTime myDate = new DateTime(2002,5,2); myGroup.Today = myDate; myGroup.PostitiveInt= "10000"; myGroup.IgnoreThis=true; myGroup.Grouptype= GroupType.B; Car thisCar =(Car) myGroup.myCar("1234566"); myGroup.MyVehicle=thisCar; return myGroup; } public void DeserializeOriginal(string filename) { // Create an instance of the XmlSerializer class. XmlTypeMapping myMapping = (new SoapReflectionImporter().ImportTypeMapping( typeof(Group))); XmlSerializer mySerializer = new XmlSerializer(myMapping); // Reading the file requires an XmlTextReader. XmlTextReader reader= new XmlTextReader(filename); reader.ReadStartElement("wrapper"); // Deserialize and cast the object. Group myGroup; myGroup = (Group) mySerializer.Deserialize(reader); reader.ReadEndElement(); reader.Close(); } public void DeserializeOverride(string filename) { // Create an instance of the XmlSerializer class. XmlSerializer overRideSerializer = CreateOverrideSerializer(); // Reading the file requires an XmlTextReader. XmlTextReader reader= new XmlTextReader(filename); reader.ReadStartElement("wrapper"); // Deserialize and cast the object. Group myGroup; myGroup = (Group) overRideSerializer.Deserialize(reader); reader.ReadEndElement(); reader.Close(); ReadGroup(myGroup); } private void ReadGroup(Group myGroup){ Console.WriteLine(myGroup.GroupName); Console.WriteLine(myGroup.GroupNumber[0]); Console.WriteLine(myGroup.GroupNumber[1]); Console.WriteLine(myGroup.Today); Console.WriteLine(myGroup.PostitiveInt); Console.WriteLine(myGroup.IgnoreThis); Console.WriteLine(); } private XmlSerializer CreateOverrideSerializer() { SoapAttributeOverrides mySoapAttributeOverrides = new SoapAttributeOverrides(); SoapAttributes soapAtts = new SoapAttributes(); SoapElementAttribute mySoapElement = new SoapElementAttribute(); mySoapElement.ElementName = "xxxx"; soapAtts.SoapElement = mySoapElement; mySoapAttributeOverrides.Add(typeof(Group), "PostitiveInt", soapAtts); // Override the IgnoreThis property. SoapIgnoreAttribute myIgnore = new SoapIgnoreAttribute(); soapAtts = new SoapAttributes(); soapAtts.SoapIgnore = false; mySoapAttributeOverrides.Add(typeof(Group), "IgnoreThis", soapAtts); // Override the GroupType enumeration. soapAtts = new SoapAttributes(); SoapEnumAttribute xSoapEnum = new SoapEnumAttribute(); xSoapEnum.Name = "Over1000"; soapAtts.SoapEnum = xSoapEnum; // Add the SoapAttributes to the // mySoapAttributeOverridesrides object. mySoapAttributeOverrides.Add(typeof(GroupType), "A", soapAtts); // Create second enumeration and add it. soapAtts = new SoapAttributes(); xSoapEnum = new SoapEnumAttribute(); xSoapEnum.Name = "ZeroTo1000"; soapAtts.SoapEnum = xSoapEnum; mySoapAttributeOverrides.Add(typeof(GroupType), "B", soapAtts); // Override the Group type. soapAtts = new SoapAttributes(); SoapTypeAttribute soapType = new SoapTypeAttribute(); soapType.TypeName = "Team"; soapAtts.SoapType = soapType; mySoapAttributeOverrides.Add(typeof(Group),soapAtts); // Create an XmlTypeMapping that is used to create an instance // of the XmlSerializer. Then return the XmlSerializer object. XmlTypeMapping myMapping = (new SoapReflectionImporter( mySoapAttributeOverrides)).ImportTypeMapping(typeof(Group)); XmlSerializer ser = new XmlSerializer(myMapping); return ser; } }
type
defaultNamespace
private void SerializeObject(string filename) { XmlSerializer serializer = new XmlSerializer (typeof(OrderedItem), "http://www.cpandl.com"); // Create an instance of the class to be serialized. OrderedItem i = new OrderedItem(); // Insert code to set property values. // Writing the document requires a TextWriter. TextWriter writer = new StreamWriter(filename); // Serialize the object, and close the TextWriter serializer.Serialize(writer, i); writer.Close(); } private void DeserializeObject(string filename) { XmlSerializer serializer = new XmlSerializer (typeof(OrderedItem), "http://www.cpandl.com"); // A FileStream is needed to read the XML document. FileStream fs = new FileStream(filename, FileMode.Open); // Declare an object variable of the type to be deserialized. OrderedItem i; // Deserialize the object. i = (OrderedItem) serializer.Deserialize(fs); // Insert code to use the properties and methods of the object. }
type
extraTypes
You can also use the extraTypes parameter to specify types derived from a base class. For example, suppose a base class named Phone exists, and a class named InternationalPhone derives from it. Use the extraTypes parameter to specify the derived type as well.
using System; using System.IO; using System.Xml; using System.Xml.Serialization; // This defines the object that will be serialized. public class Teacher { public string Name; public Teacher(){} /* Note that the Info field returns an array of objects. Any object can be added to the array by adding the object type to the array passed to the extraTypes argument. */ [XmlArray (ElementName = "ExtraInfo", IsNullable = true)] public object[] Info; public Phone PhoneInfo; } // This defines one of the extra types to be included. public class Address { public string City; public Address(){} public Address(string city) { City = city; } } // Another extra type to include. public class Phone { public string PhoneNumber; public Phone(){} public Phone(string phoneNumber) { PhoneNumber = phoneNumber; } } // Another type, derived from Phone public class InternationalPhone:Phone { public string CountryCode; public InternationalPhone(){} public InternationalPhone(string countryCode) { CountryCode = countryCode; } } public class Run { public static void Main() { Run test = new Run(); test.SerializeObject("Teacher.xml"); test.DeserializeObject("Teacher.xml"); } private void SerializeObject(string filename) { // Writing the file requires a TextWriter. TextWriter myStreamWriter = new StreamWriter(filename); // Create a Type array. Type [] extraTypes= new Type[3]; extraTypes[0] = typeof(Address); extraTypes[1] = typeof(Phone); extraTypes[2] = typeof(InternationalPhone); // Create the XmlSerializer instance. XmlSerializer mySerializer = new XmlSerializer (typeof(Teacher),extraTypes); Teacher teacher = new Teacher(); teacher.Name = "Mike"; // Add extra types to the Teacher object object [] info = new object[2]; info[0] = new Address("Springville"); info[1] = new Phone("000-0000"); teacher.Info = info; teacher.PhoneInfo = new InternationalPhone("000"); mySerializer.Serialize(myStreamWriter,teacher); myStreamWriter.Close(); } private void DeserializeObject(string filename) { // Create a Type array. Type [] extraTypes= new Type[3]; extraTypes[0] = typeof(Address); extraTypes[1] = typeof(Phone); extraTypes[2] = typeof(InternationalPhone); // Create the XmlSerializer instance. XmlSerializer mySerializer = new XmlSerializer (typeof(Teacher),extraTypes); // Reading a file requires a FileStream. FileStream fs = new FileStream(filename, FileMode.Open); Teacher teacher = (Teacher) mySerializer.Deserialize(fs); // Read the extra information. Address a = (Address)teacher.Info[0]; Phone p = (Phone) teacher.Info[1]; InternationalPhone Ip = (InternationalPhone) teacher.PhoneInfo; Console.WriteLine(teacher.Name); Console.WriteLine(a.City); Console.WriteLine(p.PhoneNumber); Console.WriteLine(Ip.CountryCode); } }
public XmlSerializer( |
type
overrides
// Beginning of HighSchool.dll namespace HighSchool { public class Student { public string Name; public int ID; } public class MyClass { public Student[] Students; } } namespace College { using System; using System.IO; using System.Xml; using System.Xml.Serialization; using HighSchool; public class Graduate:HighSchool.Student { public Graduate(){} // Add a new field named University. public string University; } public class Run { public static void Main() { Run test = new Run(); test.WriteOverriddenAttributes("College.xml"); test.ReadOverriddenAttributes("College.xml"); } private void WriteOverriddenAttributes(string filename) { // Writing the file requires a TextWriter. TextWriter myStreamWriter = new StreamWriter(filename); // Create an XMLAttributeOverrides class. XmlAttributeOverrides attrOverrides = new XmlAttributeOverrides(); // Create the XmlAttributes class. XmlAttributes attrs = new XmlAttributes(); /* Override the Student class. "Alumni" is the name of the overriding element in the XML output. */ XmlElementAttribute attr = new XmlElementAttribute("Alumni", typeof(Graduate)); /* Add the XmlElementAttribute to the collection of elements in the XmlAttributes object. */ attrs.XmlElements.Add(attr); /* Add the XmlAttributes to the XmlAttributeOverrides. "Students" is the name being overridden. */ attrOverrides.Add(typeof(HighSchool.MyClass), "Students", attrs); // Create the XmlSerializer. XmlSerializer mySerializer = new XmlSerializer (typeof(HighSchool.MyClass), attrOverrides); MyClass myClass = new MyClass(); Graduate g1 = new Graduate(); g1.Name = "Jackie"; g1.ID = 1; g1.University = "Alma Mater"; Graduate g2 = new Graduate(); g2.Name = "Megan"; g2.ID = 2; g2.University = "CM"; Student[] myArray = {g1,g2}; myClass.Students = myArray; mySerializer.Serialize(myStreamWriter, myClass); myStreamWriter.Close(); } private void ReadOverriddenAttributes(string filename) { /* The majority of the code here is the same as that in the WriteOverriddenAttributes method. Because the XML being read doesn't conform to the schema defined by the DLL, the XMLAttributesOverrides must be used to create an XmlSerializer instance to read the XML document.*/ XmlAttributeOverrides attrOverrides = new XmlAttributeOverrides(); XmlAttributes attrs = new XmlAttributes(); XmlElementAttribute attr = new XmlElementAttribute("Alumni", typeof(Graduate)); attrs.XmlElements.Add(attr); attrOverrides.Add(typeof(HighSchool.MyClass), "Students", attrs); XmlSerializer readSerializer = new XmlSerializer (typeof(HighSchool.MyClass), attrOverrides); // To read the file, a FileStream object is required. FileStream fs = new FileStream(filename, FileMode.Open); MyClass myClass; myClass = (MyClass) readSerializer.Deserialize(fs); /* Here is the difference between reading and writing an XML document: You must declare an object of the derived type (Graduate) and cast the Student instance to it.*/ Graduate g; foreach(Graduate grad in myClass.Students) { g = (Graduate) grad; Console.Write(g.Name + "\t"); Console.Write(g.ID + "\t"); Console.Write(g.University + "\n"); } } } }
public XmlSerializer( |
type
root
private void SerializeObject(string filename) { // Create an XmlRootAttribute, and set its properties. XmlRootAttribute xRoot = new XmlRootAttribute(); xRoot.ElementName = "CustomRoot"; xRoot.Namespace = "http://www.cpandl.com"; xRoot.IsNullable = true; // Construct the XmlSerializer with the XmlRootAttribute. XmlSerializer serializer = new XmlSerializer (typeof(OrderedItem),xRoot); // Create an instance of the object to serialize. OrderedItem i = new OrderedItem(); // Insert code to set properties of the ordered item. // Writing the document requires a TextWriter. TextWriter writer = new StreamWriter(filename); serializer.Serialize(writer, i); writer.Close(); } private void DeserializeObject(string filename) { // Create an XmlRootAttribute, and set its properties. XmlRootAttribute xRoot = new XmlRootAttribute(); xRoot.ElementName = "CustomRoot"; xRoot.Namespace = "http://www.cpandl.com"; xRoot.IsNullable = true; XmlSerializer serializer = new XmlSerializer (typeof(OrderedItem),xRoot); // A FileStream is needed to read the XML document. FileStream fs = new FileStream(filename, FileMode.Open); // Deserialize the object. OrderedItem i = (OrderedItem) serializer.Deserialize(fs); // Insert code to use the object's properties and methods. }
public XmlSerializer( |
type
overrides
extraTypes
root
defaultNamespace
By default, if a public property or field returns an object, or array of objects, the object types will be automatically serialized. However, if a class contains a field or property that returns an array of type Object, any object can be inserted into that array. In that case, the XmlSerializer must be instructed to expect all of the possible object types that will be inserted into the Object array. To do this, use the extraTypes parameter to specify the extra object types to serialize or deserialize.
The root element of an XML document encloses all the other elements. By default, the object specified by the type parameter is serialized as the root element. Properties, such as the XML element name of the root element are taken from the type object. However, the root parameter allows you to supplant the default object's information by specifying an XmlRootAttribute; the object allows you to set a different namespace, element name, and so on.
Use the defaultName parameter to specify the default name of all XML elements generated by the XmlSerializer.
// Beginning of the HighSchool.dll namespace HighSchool { public class Student { public string Name; public int ID; } public class MyClass { public Student[] Students; } } namespace College { using System; using System.IO; using System.Xml; using System.Xml.Serialization; using HighSchool; public class Graduate:HighSchool.Student { public Graduate(){} // Add a new field named University. public string University; // Use extra types to use this field. public object[]Info; } public class Address { public string City; } public class Phone { public string Number; } public class Run { public static void Main() { Run test = new Run(); test.WriteOverriddenAttributes("College.xml"); test.ReadOverriddenAttributes("College.xml"); } private void WriteOverriddenAttributes(string filename) { // Writing the file requires a TextWriter. TextWriter myStreamWriter = new StreamWriter(filename); // Create an XMLAttributeOverrides class. XmlAttributeOverrides attrOverrides = new XmlAttributeOverrides(); // Create the XmlAttributes class. XmlAttributes attrs = new XmlAttributes(); /* Override the Student class. "Alumni" is the name of the overriding element in the XML output. */ XmlElementAttribute attr = new XmlElementAttribute("Alumni", typeof(Graduate)); /* Add the XmlElementAttribute to the collection of elements in the XmlAttributes object. */ attrs.XmlElements.Add(attr); /* Add the XmlAttributes to the XmlAttributeOverrides. "Students" is the name being overridden. */ attrOverrides.Add(typeof(HighSchool.MyClass), "Students", attrs); // Create array of extra types. Type [] extraTypes = new Type[2]; extraTypes[0]=typeof(Address); extraTypes[1]=typeof(Phone); // Create an XmlRootAttribute. XmlRootAttribute root = new XmlRootAttribute("Graduates"); /* Create the XmlSerializer with the XmlAttributeOverrides object. */ XmlSerializer mySerializer = new XmlSerializer (typeof(HighSchool.MyClass), attrOverrides, extraTypes, root, "http://www.cpandl.com"); MyClass myClass= new MyClass(); Graduate g1 = new Graduate(); g1.Name = "Jacki"; g1.ID = 1; g1.University = "Alma"; Graduate g2 = new Graduate(); g2.Name = "Megan"; g2.ID = 2; g2.University = "CM"; Student[] myArray = {g1,g2}; myClass.Students = myArray; // Create extra information. Address a1 = new Address(); a1.City = "Ionia"; Address a2 = new Address(); a2.City = "Stamford"; Phone p1 = new Phone(); p1.Number = "000-0000"; Phone p2 = new Phone(); p2.Number = "111-1111"; Object[]o1 = new Object[2]{a1, p1}; Object[]o2 = new Object[2]{a2,p2}; g1.Info = o1; g2.Info = o2; mySerializer.Serialize(myStreamWriter,myClass); myStreamWriter.Close(); } private void ReadOverriddenAttributes(string filename) { /* The majority of the code here is the same as that in the WriteOverriddenAttributes method. Because the XML being read doesn't conform to the schema defined by the DLL, the XMLAttributesOverrides must be used to create an XmlSerializer instance to read the XML document.*/ XmlAttributeOverrides attrOverrides = new XmlAttributeOverrides(); XmlAttributes attrs = new XmlAttributes(); XmlElementAttribute attr = new XmlElementAttribute("Alumni", typeof(Graduate)); attrs.XmlElements.Add(attr); attrOverrides.Add(typeof(HighSchool.MyClass), "Students", attrs); Type [] extraTypes = new Type[2]; extraTypes[0] = typeof(Address); extraTypes[1] = typeof(Phone); XmlRootAttribute root = new XmlRootAttribute("Graduates"); XmlSerializer readSerializer = new XmlSerializer (typeof(HighSchool.MyClass), attrOverrides, extraTypes, root, "http://www.microsoft.com"); // A FileStream object is required to read the file. FileStream fs = new FileStream(filename, FileMode.Open); MyClass myClass; myClass = (MyClass) readSerializer.Deserialize(fs); /* Here is the difference between reading and writing an XML document: You must declare an object of the derived type (Graduate) and cast the Student instance to it.*/ Graduate g; Address a; Phone p; foreach(Graduate grad in myClass.Students) { g = (Graduate) grad; Console.Write(g.Name + "\t"); Console.Write(g.ID + "\t"); Console.Write(g.University + "\n"); a = (Address) g.Info[0]; Console.WriteLine(a.City); p = (Phone) g.Info[1]; Console.WriteLine(p.Number); } } } }
xmlReader
private void TestDocument(string filename, Type objType) { // Using a FileStream, create an XmlTextReader. Stream fs = new FileStream(filename, FileMode.Open); XmlReader reader = new XmlTextReader(fs); XmlSerializer serializer = new XmlSerializer(objType); if(serializer.CanDeserialize(reader)) { Object o = serializer.Deserialize(reader); } fs.Close(); }
protected virtual XmlSerializationReader CreateReader(); |
protected virtual XmlSerializationWriter CreateWriter(); |
stream
Before deserializing, an XmlSerializer must be constructed using the type of the object that is being deserialized.
Use the stream parameter to specify an object that derives from the Stream class, which is designed to write to streams. Classes that derive from the Stream class include:
using System; using System.IO; using System.Xml.Serialization; // This is the class that will be deserialized. public class OrderedItem { [XmlElement(Namespace = "http://www.cpandl.com")] public string ItemName; [XmlElement(Namespace = "http://www.cpandl.com")] public string Description; [XmlElement(Namespace="http://www.cohowinery.com")] public decimal UnitPrice; [XmlElement(Namespace = "http://www.cpandl.com")] public int Quantity; [XmlElement(Namespace="http://www.cohowinery.com")] public decimal LineTotal; // A custom method used to calculate price per item. public void Calculate() { LineTotal = UnitPrice * Quantity; } } public class Test { public static void Main() { Test t = new Test(); // Read a purchase order. t.DeserializeObject("simple.xml"); } private void DeserializeObject(string filename) { Console.WriteLine("Reading with Stream"); // Create an instance of the XmlSerializer. XmlSerializer serializer = new XmlSerializer(typeof(OrderedItem)); // Reading the XML document requires a FileStream. Stream reader= new FileStream(filename,FileMode.Open); // Declare an object variable of the type to be deserialized. OrderedItem i; // Call the Deserialize method to restore the object's state. i = (OrderedItem) serializer.Deserialize(reader); // Write out the properties of the object. Console.Write( i.ItemName + "\t" + i.Description + "\t" + i.UnitPrice + "\t" + i.Quantity + "\t" + i.LineTotal); } }
<?xml version="1.0"?> <OrderedItem xmlns:inventory="http://www.cpandl.com" xmlns:money="http://www.cohowinery.com"> <inventory:ItemName>Widget</inventory:ItemName> <inventory:Description>Regular Widget</inventory:Description> <money:UnitPrice>2.3</money:UnitPrice> <inventory:Quantity>10</inventory:Quantity> <money:LineTotal>23</money:LineTotal> </OrderedItem>
public object Deserialize( |
textReader
Before deserializing, an XmlSerializer must be constructed using the type of the object that is being deserialized.
Classes that inherit from TextReader include StringReader and StreamReader. If you are using a StreamReader to deserialize an object, you must construct the StreamReader with an appropriate Encoding. The encoding specified by the XML document will be ignored.
using System; using System.IO; using System.Text; using System.Xml.Serialization; // This is the class that will be deserialized. public class OrderedItem { public string ItemName; public string Description; public decimal UnitPrice; public int Quantity; public decimal LineTotal; // A custom method used to calculate price per item. public void Calculate() { LineTotal = UnitPrice * Quantity; } } public class Test { public static void Main() { Test t = new Test(); // Read a purchase order. t.DeserializeObject("simple.xml"); } private void DeserializeObject(string filename) { Console.WriteLine("Reading with TextReader"); // Create an instance of the XmlSerializer specifying type. XmlSerializer serializer = new XmlSerializer(typeof(OrderedItem)); /* Create a TextReader to read the file. Specify an Encoding to use. */ TextReader reader = new StreamReader(filename, Encoding.Unicode); // Declare an object variable of the type to be deserialized. OrderedItem i; // Use the Deserialize method to restore the object's state. i = (OrderedItem) serializer.Deserialize(reader); // Write out the properties of the object. Console.Write( i.ItemName + "\t" + i.Description + "\t" + i.UnitPrice + "\t" + i.Quantity + "\t" + i.LineTotal); } }
xmlReader
The XmlReader automatically detects and uses the encoding specified by the XML document.
using System; using System.IO; using System.Text; using System.Xml; using System.Xml.Serialization; // This is the class that will be deserialized. public class OrderedItem { public string ItemName; public string Description; public decimal UnitPrice; public int Quantity; public decimal LineTotal; // A custom method used to calculate price per item. public void Calculate() { LineTotal = UnitPrice * Quantity; } } public class Test { public static void Main(string[] args) { Test t = new Test(); // Read a purchase order. t.DeserializeObject("simple.xml"); } private void DeserializeObject(string filename) { Console.WriteLine("Reading with XmlReader"); // Create an instance of the XmlSerializer specifying type and namespace. XmlSerializer serializer = new XmlSerializer(typeof(OrderedItem)); // A FileStream is needed to read the XML document. FileStream fs = new FileStream(filename, FileMode.Open); XmlReader reader = new XmlTextReader(fs); // Declare an object variable of the type to be deserialized. OrderedItem i; // Use the Deserialize method to restore the object's state. i = (OrderedItem) serializer.Deserialize(reader); // Write out the properties of the object. Console.Write( i.ItemName + "\t" + i.Description + "\t" + i.UnitPrice + "\t" + i.Quantity + "\t" + i.LineTotal); } }
<?xml version="1.0"?> <OrderedItem xmlns:inventory="http://www.cpandl.com" xmlns:money="http://www.cohowinery.com"> <inventory:ItemName>Widget</inventory:ItemName> <inventory:Description>Regular Widget</inventory:Description> <money:UnitPrice>2.3</money:UnitPrice> <inventory:Quantity>10</inventory:Quantity> <money:LineTotal>23</money:LineTotal> </OrderedItem>
protected virtual object Deserialize( |
reader
~XmlSerializer(); |
public static XmlSerializer[] FromMappings( |
mappings
public static XmlSerializer[] FromTypes( |
types
using System; using System.IO; using System.Xml.Serialization; /* Three classes are included here. Each one will be used to create three XmlSerializer objects. */ public class Instrument { public string InstrumentName; } public class Player { public string PlayerName; } public class Piece { public string PieceName; } public class Test { public static void Main() { Test t = new Test(); t.GetSerializers(); } public void GetSerializers() { // Create an array of types. Type[]types = new Type[3]; types[0] = typeof(Instrument); types[1] = typeof(Player); types[2] = typeof(Piece); // Create an array for XmlSerializer objects. XmlSerializer[]serializers= new XmlSerializer[3]; serializers = XmlSerializer.FromTypes(types); // Create one Instrument and serialize it. Instrument i = new Instrument(); i.InstrumentName = "Piano"; // Create a TextWriter to write with. TextWriter writer = new StreamWriter("Inst.xml"); serializers[0].Serialize(writer,i); writer.Close(); } }
public virtual int GetHashCode(); |
public Type GetType(); |
protected object MemberwiseClone(); |
protected virtual void Serialize( |
o
writer
stream
o
In the stream parameter, specify an object that derives from the abstract Stream class. Classes that derive from Stream include:
using System; using System.IO; using System.Xml.Serialization; // This is the class that will be serialized. public class OrderedItem { public string ItemName; public string Description; public decimal UnitPrice; public int Quantity; public decimal LineTotal; // A custom method used to calculate price per item. public void Calculate() { LineTotal = UnitPrice * Quantity; } } public class Test{ public static void Main(string[] args) { Test t = new Test(); // Write a purchase order. t.SerializeObject("simple.xml"); } private void SerializeObject(string filename) { Console.WriteLine("Writing With Stream"); XmlSerializer serializer = new XmlSerializer(typeof(OrderedItem)); OrderedItem i = new OrderedItem(); i.ItemName = "Widget"; i.Description = "Regular Widget"; i.Quantity = 10; i.UnitPrice = (decimal) 2.30; i.Calculate(); // Create a FileStream to write with. Stream writer = new FileStream(filename, FileMode.Create); // Serialize the object, and close the TextWriter serializer.Serialize(writer, i); writer.Close(); } }
<?xml version="1.0"?> <OrderedItem xmlns:inventory="http://www.cpandl.com" xmlns:money="http://www.cohowinery.com"> <inventory:ItemName>Widget</inventory:ItemName> <inventory:Description>Regular Widget</inventory:Description> <money:UnitPrice>2.3</money:UnitPrice> <inventory:Quantity>10</inventory:Quantity> <money:LineTotal>23</money:LineTotal> </OrderedItem>
public void Serialize( |
textWriter
o
In the textWriter parameter, specify an object that derives from the abstract TextWriter class. Classes that derive from TextWriter include:
using System; using System.IO; using System.Text; using System.Xml.Serialization; // This is the class that will be serialized. public class OrderedItem { public string ItemName; public string Description; public decimal UnitPrice; public int Quantity; public decimal LineTotal; // A custom method used to calculate price per item. public void Calculate() { LineTotal = UnitPrice * Quantity; } } public class Test{ public static void Main(string[] args) { Test t = new Test(); // Write a purchase order. t.SerializeObject("simple.xml"); } private void SerializeObject(string filename) { Console.WriteLine("Writing With TextWriter"); XmlSerializer serializer = new XmlSerializer(typeof(OrderedItem)); OrderedItem i = new OrderedItem(); i.ItemName = "Widget"; i.Description = "Regular Widget"; i.Quantity = 10; i.UnitPrice = (decimal) 2.30; i.Calculate(); /* Create a StreamWriter to write with. First create a FileStream object, and create the StreamWriter specifying an Encoding to use. */ FileStream fs = new FileStream(filename, FileMode.Create); TextWriter writer = new StreamWriter(fs, new UTF8Encoding()); // Serialize using the XmlTextWriter. serializer.Serialize(writer, i); writer.Close(); } }
<?xml version="1.0"?> <OrderedItem xmlns:inventory="http://www.cpandl.com" xmlns:money="http://www.cohowinery.com"> <inventory:ItemName>Widget</inventory:ItemName> <inventory:Description>Regular Widget</inventory:Description> <money:UnitPrice>2.3</money:UnitPrice> <inventory:Quantity>10</inventory:Quantity> <money:LineTotal>23</money:LineTotal> </OrderedItem>
xmlWriter
o
In the xmlWriter parameter, specify an object that derives from the abstract XmlWriter class. The XmlTextWriter derives from the XmlWriter.
using System; using System.IO; using System.Text; using System.Xml; using System.Xml.Serialization; // This is the class that will be serialized. public class OrderedItem { public string ItemName; public string Description; public decimal UnitPrice; public int Quantity; public decimal LineTotal; // A custom method used to calculate price per item. public void Calculate() { LineTotal = UnitPrice * Quantity; } } public class Test{ public static void Main() { Test t = new Test(); // Write a purchase order. t.SerializeObject("simple.xml"); } private void SerializeObject(string filename) { Console.WriteLine("Writing With XmlTextWriter"); XmlSerializer serializer = new XmlSerializer(typeof(OrderedItem)); OrderedItem i = new OrderedItem(); i.ItemName = "Widget"; i.Description = "Regular Widget"; i.Quantity = 10; i.UnitPrice = (decimal) 2.30; i.Calculate(); // Create an XmlTextWriter using a FileStream. Stream fs = new FileStream(filename, FileMode.Create); XmlWriter writer = new XmlTextWriter(fs, Encoding.Unicode); // Serialize using the XmlTextWriter. serializer.Serialize(writer, i); writer.Close(); } }
<?xml version="1.0"?> <OrderedItem xmlns:inventory="http://www.cpandl.com" xmlns:money="http://www.cohowinery.com"> <inventory:ItemName>Widget</inventory:ItemName> <inventory:Description>Regular Widget</inventory:Description> <money:UnitPrice>2.3</money:UnitPrice> <inventory:Quantity>10</inventory:Quantity> <money:LineTotal>23</money:LineTotal> </OrderedItem>
public void Serialize(Stream stream, object o, XmlSerialize( |
stream
o
namespaces
Use the stream parameter to specify an object that derives from the abstract Stream class, which is designed to write to streams. Classes that derive from the Stream class include:
using System; using System.IO; using System.Xml.Serialization; // This is the class that will be serialized. public class OrderedItem { [XmlElement(Namespace = "http://www.cpandl.com")] public string ItemName; [XmlElement(Namespace = "http://www.cpandl.com")] public string Description; [XmlElement(Namespace="http://www.cohowinery.com")] public decimal UnitPrice; [XmlElement(Namespace = "http://www.cpandl.com")] public int Quantity; [XmlElement(Namespace="http://www.cohowinery.com")] public decimal LineTotal; // A custom method used to calculate price per item. public void Calculate() { LineTotal = UnitPrice * Quantity; } } public class Test { public static void Main() { Test t = new Test(); // Write a purchase order. t.SerializeObject("simple.xml"); t.DeserializeObject("simple.xml"); } private void SerializeObject(string filename) { Console.WriteLine("Writing With Stream"); XmlSerializer serializer = new XmlSerializer(typeof(OrderedItem)); OrderedItem i = new OrderedItem(); i.ItemName = "Widget"; i.Description = "Regular Widget"; i.Quantity = 10; i.UnitPrice = (decimal) 2.30; i.Calculate(); // Create an XmlSerializerNamespaces object. XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); // Add two prefix-namespace pairs. ns.Add("inventory", "http://www.cpandl.com"); ns.Add("money", "http://www.cohowinery.com"); // Create a FileStream to write with. Stream writer = new FileStream(filename, FileMode.Create); // Serialize the object, and close the TextWriter serializer.Serialize(writer, i, ns); writer.Close(); } private void DeserializeObject(string filename) { Console.WriteLine("Reading with Stream"); // Create an instance of the XmlSerializer. XmlSerializer serializer = new XmlSerializer(typeof(OrderedItem)); // Writing the file requires a Stream. Stream reader= new FileStream(filename,FileMode.Open); // Declare an object variable of the type to be deserialized. OrderedItem i; /* Use the Deserialize method to restore the object's state using data from the XML document. */ i = (OrderedItem) serializer.Deserialize(reader); // Write out the properties of the object. Console.Write( i.ItemName + "\t" + i.Description + "\t" + i.UnitPrice + "\t" + i.Quantity + "\t" + i.LineTotal); } }
public void Serialize(TextWriter textWriter, object o, XmlSerialize( |
textWriter
o
namespaces
Use the textWriter parameter to specify an object that derives from the abstract TextWriter class. Classes that derive from TextWriter include:
using System; using System.IO; using System.Xml.Serialization; // This is the class that will be serialized. public class OrderedItem { [XmlElement(Namespace = "http://www.cpandl.com")] public string ItemName; [XmlElement(Namespace = "http://www.cpandl.com")] public string Description; [XmlElement(Namespace="http://www.cohowinery.com")] public decimal UnitPrice; [XmlElement(Namespace = "http://www.cpandl.com")] public int Quantity; [XmlElement(Namespace="http://www.cohowinery.com")] public decimal LineTotal; // A custom method used to calculate price per item. public void Calculate() { LineTotal = UnitPrice * Quantity; } } public class Test{ public static void Main(string[] args) { Test t = new Test(); // Write a purchase order. t.SerializeObject("simple.xml"); } private void SerializeObject(string filename) { Console.WriteLine("Writing With TextWriter"); // Create an XmlSerializer instance using the type. XmlSerializer serializer = new XmlSerializer(typeof(OrderedItem)); OrderedItem i = new OrderedItem(); i.ItemName = "Widget"; i.Description = "Regular Widget"; i.Quantity = 10; i.UnitPrice = (decimal) 2.30; i.Calculate(); // Create an XmlSerializerNamespaces object. XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); // Add two namespaces with prefixes. ns.Add("inventory", "http://www.cpandl.com"); ns.Add("money", "http://www.cohowinery.com"); // Create a StreamWriter to write with. TextWriter writer = new StreamWriter(filename); /* Serialize using the object using the TextWriter and namespaces. */ serializer.Serialize(writer, i, ns); writer.Close(); } }
<?xml version="1.0"?> <OrderedItem xmlns:inventory="http://www.cpandl.com" xmlns:money="http://www.cohowinery.com"> <inventory:ItemName>Widget</inventory:ItemName> <inventory:Description>Regular Widget</inventory:Description> <money:UnitPrice>2.3</money:UnitPrice> <inventory:Quantity>10</inventory:Quantity> <money:LineTotal>23</money:LineTotal> </OrderedItem>
public void Serialize(XmlWriter xmlWriter, object o, XmlSerialize( |
xmlWriter
o
namespaces
Use the xmlWriter parameter to specify an object that derives from the abstract XmlWriter class, which is designed to write XML documents. The XmlTextWriter derives from the XmlWriter.
using System; using System.IO; using System.Text; using System.Xml; using System.Xml.Serialization; // This is the class that will be serialized. public class OrderedItem { [XmlElement(Namespace = "http://www.cpandl.com")] public string ItemName; [XmlElement(Namespace = "http://www.cpandl.com")] public string Description; [XmlElement(Namespace="http://www.cohowinery.com")] public decimal UnitPrice; [XmlElement(Namespace = "http://www.cpandl.com")] public int Quantity; [XmlElement(Namespace="http://www.cohowinery.com")] public decimal LineTotal; // A custom method used to calculate price per item. public void Calculate() { LineTotal = UnitPrice * Quantity; } } public class Test{ public static void Main() { Test t = new Test(); // Write a purchase order. t.SerializeObject("simple.xml"); } private void SerializeObject(string filename) { Console.WriteLine("Writing With XmlTextWriter"); XmlSerializer serializer = new XmlSerializer(typeof(OrderedItem)); OrderedItem i = new OrderedItem(); i.ItemName = "Widget"; i.Description = "Regular Widget"; i.Quantity = 10; i.UnitPrice = (decimal) 2.30; i.Calculate(); // Create an XmlSerializerNamespaces object. XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); // Add two namespaces with prefixes. ns.Add("inventory", "http://www.cpandl.com"); ns.Add("money", "http://www.cohowinery.com"); // Create an XmlTextWriter using a FileStream. Stream fs = new FileStream(filename, FileMode.Create); XmlWriter writer = new XmlTextWriter(fs, new UTF8Encoding()); // Serialize using the XmlTextWriter. serializer.Serialize(writer, i, ns); writer.Close(); } }
<?xml version="1.0"?> <OrderedItem xmlns:inventory="http://www.cpandl.com" xmlns:money="http://www.cohowinery.com"> <inventory:ItemName>Widget</inventory:ItemName> <inventory:Description>Regular Widget</inventory:Description> <money:UnitPrice>2.3</money:UnitPrice> <inventory:Quantity>10</inventory:Quantity> <money:LineTotal>23</money:LineTotal> </OrderedItem>
public virtual string ToString(); |
public event XmlAttributeEventHandler UnknownAttribute;
|
If the instance of the class being deserialized contains a field that returns an array of XmlAttribute objects, and an XmlAnyAttributeAttribute has been applied to the field, the XmlSerializer.UnknownAttribute event will not occur. Instead, all unknown XML attributes will be collected into the array.
using System; using System.IO; using System.Xml.Serialization; using System.Xml; using System.Xml.Schema; public class Group{ public string GroupName; } public class Test{ static void Main(){ Test t = new Test(); // Deserialize the file containing unknown elements. t.DeserializeObject("UnknownAttributes.xml"); } private void Serializer_UnknownAttribute(object sender, XmlAttributeEventArgs e){ Console.WriteLine("Unknown Attribute"); Console.WriteLine("\t" + e.Attr.Name + " " + e.Attr.InnerXml); Console.WriteLine("\t LineNumber: " + e.LineNumber); Console.WriteLine("\t LinePosition: " + e.LinePosition); Group x = (Group) e.ObjectBeingDeserialized; Console.WriteLine (x.GroupName); Console.WriteLine (sender.ToString()); } private void DeserializeObject(string filename){ XmlSerializer ser = new XmlSerializer(typeof(Group)); // Add a delegate to handle unknown element events. ser.UnknownAttribute+=new XmlAttributeEventHandler(Serializer_UnknownAttribute); // A FileStream is needed to read the XML document. FileStream fs = new FileStream(filename, FileMode.Open); Group g = (Group) ser.Deserialize(fs); fs.Close(); } }
public event XmlElementEventHandler UnknownElement;
|
Group
that from a file named UnknownElements.xml. Whenever an element is found in the file that has no corresponding member in the class, the XmlSerializer.UnknownElement event occurs. To try the example, paste the XML code below into a file named UnknownElements.xml.<?xml version="1.0" encoding="utf-8"?> <Group xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <GroupName>MyGroup</GroupName> <GroupSize>Large</GroupSize> <GroupNumber>444</GroupNumber> <GroupBase>West</GroupBase> </Group>
using System; using System.IO; using System.Xml.Serialization; using System.Xml; using System.Xml.Schema; public class Group{ public string GroupName; } public class Test{ static void Main(){ Test t = new Test(); // Deserialize the file containing unknown elements. t.DeserializeObject("UnknownElements.xml"); } private void Serializer_UnknownElement(object sender, XmlElementEventArgs e){ Console.WriteLine("Unknown Element"); Console.WriteLine("\t" + e.Element.Name + " " + e.Element.InnerXml); Console.WriteLine("\t LineNumber: " + e.LineNumber); Console.WriteLine("\t LinePosition: " + e.LinePosition); Group x = (Group) e.ObjectBeingDeserialized; Console.WriteLine (x.GroupName); Console.WriteLine (sender.ToString()); } private void DeserializeObject(string filename){ XmlSerializer ser = new XmlSerializer(typeof(Group)); // Add a delegate to handle unknown element events. ser.UnknownElement+=new XmlElementEventHandler(Serializer_UnknownElement); // A FileStream is needed to read the XML document. FileStream fs = new FileStream(filename, FileMode.Open); Group g = (Group) ser.Deserialize(fs); fs.Close(); } }
public event XmlNodeEventHandler UnknownNode;
|
using System; using System.IO; using System.Xml; using System.Xml.Serialization; public class Group{ // Only the GroupName field will be known. public string GroupName; } public class Test{ static void Main(){ Test t = new Test(); t.DeserializeObject("UnknownNodes.xml"); } private void DeserializeObject(string filename){ XmlSerializer mySerializer = new XmlSerializer(typeof(Group)); FileStream fs = new FileStream(filename, FileMode.Open); mySerializer.UnknownNode += new XmlNodeEventHandler(serializer_UnknownNode); Group myGroup = (Group) mySerializer.Deserialize(fs); fs.Close(); } protected void serializer_UnknownNode (object sender, XmlNodeEventArgs e){ Console.WriteLine ("UnknownNode Name: {0}", e.Name); Console.WriteLine ("UnknownNode LocalName: {0}" ,e.LocalName); Console.WriteLine ("UnknownNode Namespace URI: {0}", e.NamespaceURI); Console.WriteLine ("UnknownNode Text: {0}", e.Text); XmlNodeType myNodeType = e.NodeType; Console.WriteLine("NodeType: {0}", myNodeType); Group myGroup = (Group) e.ObjectBeingDeserialized; Console.WriteLine("GroupName: {0}", myGroup.GroupName); Console.WriteLine(); } } /* Paste this XML into a file named UnknownNodes: <?xml version="1.0" encoding="utf-8"?> <Group xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:coho = "http://www.cohowinery.com" xmlns:cp="http://www.cpandl.com"> <coho:GroupName>MyGroup</coho:GroupName> <cp:GroupSize>Large</cp:GroupSize> <cp:GroupNumber>444</cp:GroupNumber> <coho:GroupBase>West</coho:GroupBase> <coho:ThingInfo> <Number>1</Number> <Name>Thing1</Name> <Elmo> <Glue>element</Glue> </Elmo> </coho:ThingInfo> </Group> */
public event UnreferencedObjectEventHandler UnreferencedObject;
|
Documents that conform to section 5 are in a special format. At the very least, such a document includes the main body of the SOAP message. However, rather than having all types defined inline in the document, some type definitions may be encoded as references to top-level elements in the document. Thus, for every element found in the main body that is a reference, there must be a corresponding element that contains the type definition. To correlate the referencing element and the type definition, the type definition has an id attribute set to a unique string ID and the referencing element has an href attribute that references the same ID.
<Group xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" id="id1" n1:GroupName=".NET" GroupNumber="ZDI=" CreationDate="2002-05-02" xmlns:n1="http:'www.cpandl.com"> <PosInt xsi:type="xsd:nonNegativeInteger">10000</PosInt> <GroupVehicle href="#id2" /> </Group> <Vehicle id="id2" n1:type="Vehicle" xmlns:n1="http://www.w3.org/2001/XMLSchema-instance"> <licenseNumber xmlns:q1="http://www.w3.org/2001/XMLSchema" n1:type="q1:string">1234</licenseNumber> </Vehicle>
The XmlSerializer.UnreferencedObject event will thus occur when there is a type definition found in the document, but no parameter in the main body references it. When the event occurs, you can retrieve the XML type of the unreferenced object by examining the UnreferencedObjectEventArgs.UnreferencedObject property of the UnreferencedObjectEventArgs class. The XML ID of the object is returned by the UnreferencedObjectEventArgs.UnreferencedId property.
The XmlSerializer.UnreferencedObject event should not be confused with the XmlSerializer.UnknownElement and XmlSerializer.UnknownNode events, which occur when there is no class member corresponding to the XML node or element type.
Serializer_UnreferencedObject
method. To run the example, you should cut and paste the following XML into a file named "UnrefObj.xml".<wrapper> <Group xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" id="id1" n1:GroupName=".NET" xmlns:n1="http://www.cpandl.com"> </Group> <Vehicle id="id2" n1:type="Vehicle" xmlns:n1="http://www.w3.org/2001/XMLSchema-instance"> <licenseNumber xmlns:q1="http://www.w3.org/2001/XMLSchema" n1:type="q1:string">ABCD</licenseNumber> </Vehicle> <Vehicle id="id3" n1:type="Vehicle" xmlns:n1="http://www.w3.org/2001/XMLSchema-instance"> <licenseNumber xmlns:q1="http://www.w3.org/2001/XMLSchema" n1:type="q1:string">1234</licenseNumber> </Vehicle> </wrapper>
using System; using System.IO; using System.Text; using System.Xml; using System.Xml.Serialization; using System.Xml.Schema; // You must use the SoapIncludeAttribute to inform the XmlSerializer // that the Vehicle type should be recognized when deserializing. [SoapInclude(typeof(Vehicle))] public class Group { public string GroupName; public Vehicle GroupVehicle; } [SoapInclude(typeof(Vehicle))] public class Vehicle { public string licenseNumber; } public class Run { public static void Main() { Run test = new Run(); test.DeserializeObject("UnrefObj.xml"); } public void DeserializeObject(string filename) { // Create an instance of the XmlSerializer class. XmlTypeMapping myMapping = (new SoapReflectionImporter().ImportTypeMapping( typeof(Group))); XmlSerializer mySerializer = new XmlSerializer(myMapping); mySerializer.UnreferencedObject += new UnreferencedObjectEventHandler (Serializer_UnreferencedObject); // Reading the file requires an XmlTextReader. XmlTextReader reader= new XmlTextReader(filename); reader.ReadStartElement(); // Deserialize and cast the object. Group myGroup; myGroup = (Group) mySerializer.Deserialize(reader); reader.ReadEndElement(); reader.Close(); } private void Serializer_UnreferencedObject (object sender, UnreferencedObjectEventArgs e){ Console.WriteLine("UnreferencedObject:"); Console.WriteLine("ID: " + e.UnreferencedId); Console.WriteLine("UnreferencedObject: " + e.UnreferencedObject); Vehicle xxx = (Vehicle) e.UnreferencedObject; Console.WriteLine("License: " + xxx.licenseNumber); } } // The file named "UnrefObj.xml" should contain this XML: // <wrapper> // <Group xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" //xmlns:xsd="http://www.w3.org/2001/XMLSchema" id="id1" //n1:GroupName=".NET" xmlns:n1="http://www.cpandl.com"> // </Group> //<Vehicle id="id2" n1:type="Vehicle" //xmlns:n1="http://www.w3.org/2001/XMLSchema-instance"> // <licenseNumber xmlns:q1="http://www.w3.org/2001/XMLSchema" //n1:type="q1:string">ABCD</licenseNumber> // </Vehicle> //<Vehicle id="id3" n1:type="Vehicle" //xmlns:n1="http://www.w3.org/2001/XMLSchema-instance"> // <licenseNumber xmlns:q1="http://www.w3.org/2001/XMLSchema" //n1:type="q1:string">1234</licenseNumber> // </Vehicle> //</wrapper>