简体   繁体   中英

Why does XmlTypeAttribute.Namespace not set a namespace for the root element?

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?

[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"/>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM