Groups | Blog | Home
all groups > dotnet xml > september 2004 >

dotnet xml : xml serialization of a class and adding qualified namespace


geakewil NO[at]SPAM hotmail.com
9/8/2004 4:13:39 PM
I am successfully serializing to XML from a class like this:

private static void CreateXML()
{
testClass c = new testClass();
c.stringElement = "data1";
c.stringElement2 = "data2";

subClassDataType s = new subClassDataType();
s.subThingElement1 = "data3";
s.subThingElement2 = "data4";

c.subThing = s;

XmlSerializer mySerializer = new XmlSerializer(typeof(testClass));
System.IO.StreamWriter myWriter = new
System.IO.StreamWriter("test3.xml");
mySerializer.Serialize(myWriter, c);
}

My class definitions are as follows:

[Serializable]
[System.Xml.Serialization.XmlRootAttribute("testClass",
Namespace="urn:test")]
public class testClass
{
public string stringElement;
public string stringElement2;
public subClassDataType subThing;
}

public class subClassDataType
{
public string subThingElement1;
public string subThingElement2;
}

And here are the results:
<?xml version="1.0" encoding="utf-8"?>
<testClass xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:test">
<stringElement>data1</stringElement>
<stringElement2>data2</stringElement2>
<subThing>
<subThingElement1>data3</subThingElement1>
<subThingElement2>data4</subThingElement2>
</subThing>
</testClass>

However, for my real world application, subThing is defined in another
namespace. When I am done, my resulting file needs to look like this:

<?xml version="1.0" encoding="utf-8"?>
<testClass xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:test"
xmlns:ns2="somethingelse">
<stringElement>data1</stringElement>
<stringElement2>data2</stringElement2>
<subThing>
<ns2:subThingElement1>data3</subThingElement1>
<ns2:subThingElement2>data4</subThingElement2>
</subThing>

Note the additional namespace declaration in the root element, along
with the qualified names in subThing. This is relatively easy when
creating an XML Document from scratch with the CreateAttribute()
method, however since I am serializing from a class, how can I
accomplish this? THANK YOU in advance for any help!

-Bill
Derek Harmon
9/10/2004 12:27:58 AM
[quoted text, click to view]

Add XmlElementAttributes to the properties of subThing belonging
to this second namespace. XmlElementAttributes allow you to
customize the ElementName, Namespace (URI), and other
properties of how the property/field gets serialized.

public class subClassDataType
{
[XmlElement( Namespace="somethingelse")]
public string subThingElement1;

[XmlElement( Namespace="somethingelse")]
public string subThingElement2;
}

This produces a document that ought to be equivalent to
your requirements, but if you want to manifest additional
control that guarantees the ns2 prefix is used, it would
be necessary that an XmlSerializerNamespaces gets
created, has the "ns2" prefix (associated of course with the
same Namespace URI you've given to these child elements
of subThing) added to it, and is passed to the XmlSerializer
when you call Serialize( ).

// Create XmlSerializer for your Type.
XmlSerializer mySerializer = new XmlSerializer(typeof(testClass));

// Create an XmlSerializerNamespaces to control the prefixes
// that get generated for namespace URIs appearing in the
// serialized XML.
XmlSerializerNamespaces myNamespaces = new
XmlSerializerNamespaces( );

// Associate ns2 with the namespace URI used for subThing's
// child elements.
myNamespaces.Add( "ns2", "somethingelse");

// When using XmlSerializerNamespaces, you must specify xsi
// and xsd namespace declarations if you want them.
myNamespaces.Add( "xsi", "http://www.w3.org/2001/XMLSchema-instance");
myNamespaces.Add( "xsd", "http://www.w3.org/2001/XMLSchema");

// Create a StreamWriter to write the XML serialization to.
StreamWriter myWriter = new StreamWriter("test3.xml");

// Serialize the instance, c, using the XmlSerializerNamespaces.
mySerializer.Serialize( myWriter, c, myNamespaces);

// Flush and close the StreamWriter to ensure everything gets
// committed to file.
myWriter.Flush( );
myWriter.Close( );


Derek Harmon

AddThis Social Bookmark Button