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.
First posted :
03/24/2008
Times viewed :
1503
XmlSerializer Namespaces
We can also have the
XmlSerializer create prefix declarations and qualified names instead of
repeating namespace declarations on every element or attribute. The first
approach puts the control over prefix declarations inside the serialized
object. The XmlSerializer checks objects it serializes for a field of type
XmlSerializerNamespaces adorned with an XmlNamespaceDeclarations attribute. If
it finds such a field, it writes the prefix declarations contained in the
XmlNamespaceDeclarations object with the top element of the object graph. Whenever
a field or child object references a namespace declared in the
XmlNamespaceDeclarations, the XmlSerializer generates the declared prefix
instead of writing out another local namespace declaration.
The code in Listing 10.10
demonstrates the use of an XmlSerializerNamespaces field to declare prefixes
for the namespaces of the Make, Model and Year fields.
14
Listing 10.10 A class
with a field for namespace prefix declarations.
public class
CarWithQualifiedNames
{
[XmlAttribute(Namespace="urn:cars-makes")]
public string Make;
[XmlElement(Namespace="urn:cars-models")]
public string Model;
public int Year;
[XmlNamespaceDeclarations]
public XmlSerializerNamespaces Namespaces;
}
public static void
SerializeCar(CarWithQualifiedNames car,
XmlTextWriter writer )
{
car.Namespaces = new XmlSerializerNamespaces();
car.Namespaces.Add( "mk", "urn:cars-makes" );
car.Namespaces.Add( "md", "urn:cars-models"
);
XmlSerializer serializer = new
XmlSerializer(
typeof(CarWithQualifiedNames) );
serializer.Serialize( writer, car );
}
When we serialize an object
of this class, the XmlSerializer declares the prefixes we added to the
Namespaces map before we called Serialize() on the start tag of the object.
While these declarations are in scope, i.e. for all fields or the
CarWithQualifiedNames class and its children, these namespaces are referenced
through these prefixes (listing 10.11).
15
Listing 10.11 A
serialized Car objects with namespace prefixes
The single prefix
declaration in this example does not illustrate the benefit of prefix
declarations well. However, when you serialize large hierarchies with types
from many different namespaces, the resulting documents quickly become
cluttered with local namespace declarations.
WARNING: Declaring prefixes
is a good and widely-used approach to tidy up XML documents, but declaring
prefixes in the class code is very risky. You should always define namespace
prefixes in the scope of the document in which they are valid to maintain
flexibility into which documents you serialize you classes. Always leave prefix
declarations up to the application, not to the serialized objects.
The Namespaces collection
also serves a second purpose. The XmlSerializer stores the prefixes found the
in the XML document when it deserializes an object. Nevertheless, you should
not care about the namespace prefixes defined throughout a particular document
instance.