为什么在 XML 序列化期间将命名空间添加到子节点?



我有一个为XML序列化装饰的类,如下所示:

[XmlRoot(ElementName = "XXX", Namespace = "http://www.example.com/Schemas/xxx/2011/11")]
public class Xxx<T> where T: Shipment
{
[XmlAttribute("version")]
public string Version = "1.1";
public T Shipment { get; set; }
public Xxx(string dataTargetType)
{
Shipment = (T)Activator.CreateInstance(typeof(T));
Shipment.DataContext = new DataContext
{
DataTargetCollection = new DataTargetCollection
{
DataTarget = new DataTarget
{
Type = dataTargetType
}
}
};
}
}
[XmlType("Shipment")]
public class Shipment
{
public DataContext DataContext { get; set; }
}

序列化时,它将输出以下 XML:

<?xml version="1.0" encoding="utf-8"?>
<XXX xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Shipment xmlns="http://www.example.com/Schemas/xxx/2011/11">
<DataContext>
<DataTargetCollection>
<DataTarget>
<Type>WarehouseOrder</Type>
</DataTarget>
</DataTargetCollection>
</DataContext>
</Shipment>
</XXX>

为什么将 xmlns 命名空间属性添加到Shipment节点而不是根XXX节点?

使用中它被继承和序列化的示例:(在解决序列化问题时人为的示例(

public class XxxVariation: Xxx<Shipment>
{
public const string DataTargetType = "Something";
public XxxVariation() : base(DataTargetType) {}
}
public async Task<string> CreateXxxVariationAsync(string todo)
{
var request = new XxxVariation();
string xmlRequest = SerializeRequest(request);
return await PostRequestAsync(xmlRequest);
}
private static string SerializeRequest<T>(T request)
{
using (var stream = new MemoryStream())
{
var serializer = new XmlSerializer(typeof(T));
serializer.Serialize(XmlWriter.Create(stream), request);
using (var reader = new StreamReader(stream))
{
stream.Seek(0, SeekOrigin.Begin);
string xml = reader.ReadToEnd();
return xml;
}
}
}

> 基于Xxx<T>没有公共无参数构造函数的事实,我怀疑您实际拥有的是这样的:

public class FooXxx : Xxx<Foo> {
public FooXxx() : base("abc") { }
}

并且您正在序列化FooXxx实例,并在创建XmlSerializer时使用typeof(FooXxx)。那是。。。好吧,我猜,理论上XmlRootAttribute是可继承的,但我怀疑属性检查代码在检查属性时显式使用"仅在声明的类型上,不继承"选项。因此,您似乎需要在FooXxx再次添加该属性:

[XmlRoot(ElementName = "XXX", Namespace = "http://www.example.com/Schemas/xxx/2011/11")]
public class FooXxx : Xxx<Foo> {
public FooXxx() : base("abc") { }
}

注意:我不得不在这里推断很多;如果这没有帮助,请发布您用于序列化的实际代码,包括您的XmlSerializer初始化,并显示您传递给序列化程序的对象的创建。

最新更新