为什么在 XML 序列化期间将名称空间添加到子节点?
Why is the namespace being added to a child node during XML serialization?
我有一个 class 为 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 无参数构造函数这一事实,我 怀疑 你实际拥有的是这样的:
public class FooXxx : Xxx<Foo> {
public FooXxx() : base("abc") { }
}
并且您正在序列化 FooXxx
实例,并在创建 XmlSerializer
时使用 typeof(FooXxx)
。那是......好吧,我猜,理论上 XmlRootAttribute
是可继承的,但我怀疑属性检查代码在检查属性时明确使用 "only on the declared type, not inherited" 选项。因此,您似乎需要在 FooXxx
:
上再次添加属性
[XmlRoot(ElementName = "XXX", Namespace = "http://www.example.com/Schemas/xxx/2011/11")]
public class FooXxx : Xxx<Foo> {
public FooXxx() : base("abc") { }
}
注意:我不得不在这里推断很多;如果这没有帮助,请 post 您用于序列化 的实际代码,包括您的 XmlSerializer
初始化,并显示您创建的对象传入序列化器。
我有一个 class 为 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 无参数构造函数这一事实,我 怀疑 你实际拥有的是这样的:
public class FooXxx : Xxx<Foo> {
public FooXxx() : base("abc") { }
}
并且您正在序列化 FooXxx
实例,并在创建 XmlSerializer
时使用 typeof(FooXxx)
。那是......好吧,我猜,理论上 XmlRootAttribute
是可继承的,但我怀疑属性检查代码在检查属性时明确使用 "only on the declared type, not inherited" 选项。因此,您似乎需要在 FooXxx
:
[XmlRoot(ElementName = "XXX", Namespace = "http://www.example.com/Schemas/xxx/2011/11")]
public class FooXxx : Xxx<Foo> {
public FooXxx() : base("abc") { }
}
注意:我不得不在这里推断很多;如果这没有帮助,请 post 您用于序列化 的实际代码,包括您的 XmlSerializer
初始化,并显示您创建的对象传入序列化器。