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 :
319
Specifying Namespaces
XML Namespaces
The System.Xml.Serialization.XmlRootAttribute declares the XML namespace of
the corresponding element. Here, the Namespace property is empty because the
input schema did not specify a targetNamespace. When the attribute does declare
a namespace and we serialize an instance of this class the XmlSerializer will
add an xmlns namespace declaration to the start tag for the object.
According to the schema, the complexTypegarage can have one child element
desc of type xs:string, therefore the corresponding garage class has a public
string field desc. A System.Xml.Serialization.XmlElementAttribute() adornment
on the field is not necessary here because the name of the property is already
the name of the XML element.
Besides the <desc> element, a garage can contain multiple <car>
elements. The class maps the <car> elements through an array field
(expressed by the square brackets [] behind the type declaration garageCar)
named after the element. When the tool generates a class for the <car>
element’s type it has to make up a unique name because the schema declared the
type inline without providing a name. It concatenates the names of the element
car and its parent element garage to name the class: garageCar. The car
element’s type declared three attributes make, model and year. These attributes
are represented as public fields in the garageCar class. The
System.Xml.Serialization.XmlAttributeAttributeon each field indicates that they
map to attributes in an XML document. Their types are again according to the
type mapping for the .NET system.
WARNING: The generated code file contains nothing that prevents garageCar
objects to be serialized outside of the scope of a Car object. The serializer
would produce a top-level <garageCar> element if a garageCar object by
itself is serialized to an XML document. The resulting document cannot be
validated against the original schema however, because the schema – from which
this class was generated(!) – does not declare a top-level element garageCar.
We have to ensure manually that our applications only serialize classes that
produce schema-valid documents.
TIP: It is not good practice to modify automatically generated code files.
Sometimes during development early phases the schema you are developing against
is still in flux and you frequently have to re-generate the corresponding
classes. Any changes made in the generated files are lost if you do not to take
measures to carry them over to the new version. You can avoid this problem
entirely by inheriting classes from the automatically generated classes and
making all modifications in the derived classes.
.NET Namespaces
The garage schema in listing C.2 did not explicitly declare a
targetNamespace, because we started with a simple example document. In real
world applications that’s not the case. The XSD tool can save us some work when
we have to create classes for a schema that is importing elements and types
from other namespaces. It will automatically add the necessary attributes to
the generated classes with their Namespace properties set to express the
correct namespace. Suppose the garage schema declared a targetNamespace:
<xs:schema id="NewDataSet"
targetNamespace="urn:christoph-garage"
xmlns:mstns="urn:christoph-garage"
xmlns="urn:christoph-garage"
…
then classes created for the elements in the schema reference their XML
namespace through the XmlTypeAttribute’s and the XmlRootAttribute’s Namespace
properties:
The tool will also set the Namespace property on XmlElementAttribute and
XmlAttributeAttribute attributes if any elements or attributes belong to
different namespaces.
Now we have seen how we can use the XSD tool to include references to XML
namespaces. But what about .NET namespaces, can the tool automatically generate
those as well? Sure, it can. We simply need to add the /n switch to the command
line to declare the .NET namespace for the generated classes.
Let’s see this work and add a .NET namespace around the garage classes we
generated in section 3.1. I usually use “Christoph” as my top-level namespace
and add another namespace to identify the application I am working on. Nested
namespaces are separated by a ‘.’ between the parent and the child
namespace. If we add namespace declaration to the command line with the
/n switch: