Mark Wilson I am the creator of TopXML. I am available for international and local (Australia) contracts. I am a Solution Architect/Business Analyst. I have worked in IT in several countries (NZ, Australia, South Africa, UK) building and training teams for government and very large non-governmental organizations. I am ex-Microsoft Consulting Services. I wrote the first book on Microsoft XML published in 2000 called XML Programming with VB and ASP. Most recently I have been building tools for the SEO industry. Ask me for a 37 point SEO health-checkup for your website.
Up until now our focus was on mapping elements and attributes in
an XML document to fields of a .NET class. We have yet to talk about how we can
process other features of XML documents, e.g. comments or processing
instructions, with the XmlSerializer. These features are more rooted in
document processing than data exchange. Processing instructions, for example,
convey application specific information directly to the processor of the
document, they should not carry data like elements and attributes do.
Nevertheless, the XmlSerializer allows us to output these types of XML nodes
through serialization or to retrieve them from documents through
deserialization.
Processing XML documents with the XmlSerializer still requires an
object-centered approach. It is not a general purpose parsing solution like the
XmlDocument or the XmlTextReader and -Writer. We still have to serialize or
deserialize objects to write or read the XML content. After all, it is still
the XmlSerializer that is doing the work.
The key is to design classes with fields of the XML node classes
in the System.Xml namespace to produce the required document items. If we
exchange documents with an application that requires special processing
instructions, for example, we can add a field of type XmlProcessingInstruction
to the class that we serialize to produce the document. The XmlSerializer
places the processing instruction directly into the output stream eliminating
the need for any post-serialization processing steps to inject the processing
instruction.
This concept works for all objects of classes derived from
XmlNode: XmlDocument, XmlComment, XmlCDataSection, just to name a few more.
When the XmlSerializer serializes these types of objects, it writes their
OuterXml property, which provides the literal XML encapsulated by the object,
verbatim to the output stream. Serializing an object of the following class,
for example, will produce an XML document containing a processing instruction.
XmlSerializer xs = new
XmlSerializer(typeof(CarWithPI));
XmlTextWriter writer =
new XmlTextWriter("car.xml", Encoding.UTF8);
writer.Formatting = Formatting.Indented;
xs.Serialize( writer,
car );
writer.Close();
}
}
The serialized representation of the object looks like this:
<?xml version="1.0" encoding="utf-8"?>
<CarWithPI …>
<Instruction>
<?park and
lock?>
</Instruction>
</CarWithPI>
The XmlSerializer created an element node for the Instruction
field. You can see now that the XmlSerializer created an XML processing
instruction inside the Instruction element. It did not create an element
structure for the public properties of the XmlProcessingInstruction class.
WARNING: We can only serialize XmlDocument objects that contain
XML fragments, because a valid XML document must not have two document
declarations (<?xml version … ). The XmlSerializer creates the first
declaration automatically, serializing a complete document would create a
second one, but the XmlTextWriter in charge of creating the output document
detects the second declaration and throws and exception.
This brings us already very close to being able to produce XML
documents with information items besides elements and attributes with the
XmlSerializer, but the element surrounding the items still undesirable in most
cases.