Reputation: 24222
I have generated types from XSDs that look like this:
[XmlType(Namespace = "http://example.com")]
public class Foo
{
public string Bar { get; set; }
}
When serialised like this:
var stream = new MemoryStream();
new XmlSerializer(typeof(Foo)).Serialize(stream, new Foo() { Bar = "hello" });
var xml = Encoding.UTF8.GetString(stream.ToArray());
the output is this:
<?xml version="1.0"?>
<Foo xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Bar xmlns="http://example.com">hello</Bar>
</Foo>
Why does the root element not have the namespace set? Sure, I can force it like this:
var stream = new MemoryStream();
var defaultNamespace = ((XmlTypeAttribute)Attribute.GetCustomAttribute(typeof(Foo), typeof(XmlTypeAttribute))).Namespace;
new XmlSerializer(typeof(Foo), defaultNamespace).Serialize(stream, new Foo() { Bar = "hello" });
var xml = Encoding.UTF8.GetString(stream.ToArray());
then the output is this:
<?xml version="1.0"?>
<Foo xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://example.com">
<Bar>hello</Bar>
</Foo>
But it doesn't sit right with me that I have to do the additional step. When deserialising, similar code is required. Is there something wrong with the attribute, or is that just how things work and is it expected to do the additional step?
Upvotes: 4
Views: 7523
Reputation: 161821
[XmlType]
sets neither the name nor the namespace of the root element. It sets the type of the class it is placed on.
To set the name of the root element use [XmlRoot]
.
[XmlRoot(Name="FooElement", Namespace = "http://example.com")] // NS for root element
[XmlType(Name="FooType", Namespace = "http://example.com/foo")] // NS for the type itself
public class Foo
{
public string Bar { get; set; }
}
The name and namespace set by [XmlType]
would be seen in the XML Schema for your serialized type, possibly in a complexType
declaration. It might also be seen in an xsi:type
attribute if that were required.
The above declarations would generate the XML
<ns1:FooElement xmlns:ns1="http://example.com">
with the XSD
<xsd:element name="FooElement" type="ns2:FooType" xmlns:ns2="http://example.com/foo"/>
Upvotes: 8