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.
Two of the namespace support features of the XmlSerializer enable
namespace management inside the source code of a class. When we develop classes
to bind data from XML schema types we
can add the namespaces directly to the source code by attaching metadata attributes.
The XmlSerializer reads the namespace information and produces the namespace
declarations upon serialization of an object. Of course, it will also account
for namespace correct-ness when it is deserializing an XML stream. If a
metadata attributes defines for a field to bind to an XML node from a specific
namespace then the XmlSerializer will only populate that field from an XML node
where node name and namespace match the attribute.
The seconds feature allows providing prefix declarations for
namespaces, but more on that later, first we will see how to define namespace
relationships in the source code.
You may have noticed the
Namespace property on most of the metadata attributes when you studied table
9.4, but we have yet to examine what they do. When we attach XML serialization
attribute to a field, we can set the attribute’s Namespace property to tell the
XmlSerializer which XML namespace the element or attribute corresponding to the
field belongs to. We can declare XML namespaces at different levels inside a
class.
At the highest level, we
can specify the XML namespace of the schema type with class’ XmlRoot attribute.
However, the XmlSerializer does not consider XmlRoot when an object is not at
the top of a serialization hierarchy. This is not a problem if all classes in
an object model correspond to types from the same XML schema. However, if we
model a schema that imports types from different namespaces, our classes have
to reflect this at the field and property definitions. We declare the external
namespaces by attaching metadata attributes to fields referencing an imported
type.
Let’s put see how this
works when we actually design a class! We start out with an XML schema to
describe a type named Car_T. The schema imports types from two other
namespaces. One is referenced by an attribute; one is referenced by an element
of the Car_T type. The Car_T type declares another element, Year, which is part
of the schema’s namespace (listing 10.7).
11
Listing 10.7 A schema
importing types from two other namespaces
Then we write a Car class
that the XmlSerializer will relate to the Car_T type. To make sure the
XmlSerializer includes the correct namespace declaration when we serialize a
Car object we specify the namespace through an XmlRoot attribute attached to
the class. We also have to attach XmlAttribute and XmlElement attributes on the
fields corresponding to the types imported from another namespace. Note that we
have to declare namespaces on fields even when their classes already contain
XmlRoot attributes to declare their XML namespace.
12
Listing 10.8 A class
with XML namespace declarations
When the XmlSerializer serializes
an instance of this class, it automatically includes the namespace declarations
from attached attributes. The root element declares the XML namespace we
specified to the XmlRoot attribute as the type’s default namespace. It also
generates the declaration of the Make attribute with a dummy prefix, since the
attribute does not belong to the default namespace. Finally, it declares the
Model element’s namespace through another local namespace declaration on the
model element.
13
Listing 10.9 A serialized
instance of the Car class