【问题标题】:Why is the namespace being added to a child node during XML serialization?为什么在 XML 序列化期间将命名空间添加到子节点?
【发布时间】:2020-09-04 02:57:45
【问题描述】:

我有一个为 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;
        }
    }
}

【问题讨论】:

  • 我们可以在这里看到你用来序列化的代码吗?你在序列化什么对象 are,因为Xxx&lt;T&gt; 没有公共的无参数构造函数,所以我不认为它是 那个
  • @MarcGravell 我添加了一些代码来展示我如何序列化和继承类。无参构造函数没有区别,可能是因为继承自它的类已经有了无参构造函数。
  • 编辑非常接近我的猜测,然后:)

标签: c# xml xml-serialization xmlserializer


【解决方案1】:

基于Xxx&lt;T&gt; 没有公共无参数构造函数这一事实,我怀疑您实际拥有的类似于:

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 初始化,并显示您传递给序列化程序的对象的创建。

【讨论】:

  • 是的,非常令人印象深刻的推断你在那里做了!非常感谢您的帮助 :) 是一个深夜编码会议,所以忘了说谢谢。
猜你喜欢
  • 1970-01-01
  • 2016-07-08
  • 1970-01-01
  • 1970-01-01
  • 2020-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多