如何序列化List<List<object>>?

How to serialize List<List<object>>?

框架是 c# .net 4.6.2

我正在从 XML 代码

生成自动 XML classes

当我自动生成时,它会自动转换为Array[][]

但我想将其用作 List<List<>>

而且我确信我从 Array 到 List 的对话会导致一些序列化错误。我认为这是关于获取和设置功能。所以我需要你的帮助来解决这个问题

这里是当我 编辑 > 选择性粘贴 > 粘贴 XML 为 classes

时自动生成的代码片段
    /// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class OxFordDefinition_perGroup
{

    private string _GroupDescField;

    private string _GroupSenseField;

    private string _GroupGrammerField;

    private OxFordDefinition_perGroup_perMainExample_perSubExample[][] _perMainExampleField;

    /// <remarks/>
    public string _GroupDesc
    {
        get
        {
            return this._GroupDescField;
        }
        set
        {
            this._GroupDescField = value;
        }
    }

    /// <remarks/>
    public string _GroupSense
    {
        get
        {
            return this._GroupSenseField;
        }
        set
        {
            this._GroupSenseField = value;
        }
    }

    /// <remarks/>
    public string _GroupGrammer
    {
        get
        {
            return this._GroupGrammerField;
        }
        set
        {
            this._GroupGrammerField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlArrayItemAttribute("_perSubExample", typeof(OxFordDefinition_perGroup_perMainExample_perSubExample), IsNullable = false)]
    public OxFordDefinition_perGroup_perMainExample_perSubExample[][] _perMainExample
    {
        get
        {
            return this._perMainExampleField;
        }
        set
        {
            this._perMainExampleField = value;
        }
    }
}

但是我想使用 List<List<>>

而不是数组

所以我做成下面这样

        /// <remarks/>
    [System.SerializableAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    public partial class OxFordDefinition_perGroup
    {

        private string _GroupDescField;

        private string _GroupSenseField;

        private string _GroupGrammerField;

        private  List<List<OxFordDefinition_perGroup_perMainExample_perSubExample>> _perMainExampleField;

        /// <remarks/>
        public string _GroupDesc
        {
            get
            {
                return this._GroupDescField;
            }
            set
            {
                this._GroupDescField = value;
            }
        }

        /// <remarks/>
        public string _GroupSense
        {
            get
            {
                return this._GroupSenseField;
            }
            set
            {
                this._GroupSenseField = value;
            }
        }

        /// <remarks/>
        public string _GroupGrammer
        {
            get
            {
                return this._GroupGrammerField;
            }
            set
            {
                this._GroupGrammerField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlArrayItemAttribute("_perSubExample", typeof(OxFordDefinition_perGroup_perMainExample_perSubExample), IsNullable = false)]
        public List<List<OxFordDefinition_perGroup_perMainExample_perSubExample>> _perMainExample
        {
            get
            {
                return this._perMainExampleField;
            }
            set
            {
                this._perMainExampleField = value;
            }
        }
    }

但是这次当我尝试像下面这样序列化时它给出了序列化错误

       public static string SerializeXML<T>(this T toSerialize)
    {
        XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
        StringWriter textWriter = new StringWriter();
        xmlSerializer.Serialize(textWriter, toSerialize);
        return textWriter.ToString();
    }

这里是 XML class

的完整代码

http://pastebin.com/y5B8ENM3

这是它给出的错误

其实你的原版和修改后的OxFordDefinition_perGroup都无法序列化成功。问题是 XmlArrayItem.Type, which is the second argument to the constructor:

的值
[System.Xml.Serialization.XmlArrayItemAttribute("_perSubExample", typeof(OxFordDefinition_perGroup_perMainExample_perSubExample), IsNullable = false)]
public OxFordDefinition_perGroup_perMainExample_perSubExample[][] { get; set; }

根据 docs

Use the Type property to specify an overridden type for a public field or public read/write property value.

If a field or property returns an array of type Object, apply multiple instances of the XmlArrayItemAttribute to the field or property. For each instance, set the Type property to a type of object that can be inserted into the array.

typeof(OxFordDefinition_perGroup_perMainExample_perSubExample) 表示 最外层 集合中的项目将属于 typeof(OxFordDefinition_perGroup_perMainExample_perSubExample) 类型。然而,实际上数组或列表中的项分别是 OxFordDefinition_perGroup_perMainExample_perSubExample[]List<OxFordDefinition_perGroup_perMainExample_perSubExample> 类型,当然不能分配给此类型。 XmlSerializer 代码生成失败。

如果您从 [XmlArrayItem] 属性中完全删除类型设置,那么您的类型的两个版本都将可序列化为 XML:

[System.Xml.Serialization.XmlArrayItemAttribute("_perSubExample", IsNullable = false)]
public List<List<OxFordDefinition_perGroup_perMainExample_perSubExample>> _perMainExample
{
    get
    {
        return this._perMainExampleField;
    }
    set
    {
        this._perMainExampleField = value;
    }
}

示例 fiddle.

更新

你问,它添加了不应该存在的额外层。有什么想法吗?

这是因为您正在使用嵌套列表或交错数组。将其更改为简单列表或一维数组:

private List<OxFordDefinition_perGroup_perMainExample_perSubExample> _perMainExampleField;

/// <remarks/>
[System.Xml.Serialization.XmlArrayItemAttribute("_perSubExample", IsNullable = false)]
public List<OxFordDefinition_perGroup_perMainExample_perSubExample> _perMainExample
{
    get
    {
        return this._perMainExampleField;
    }
    set
    {
        this._perMainExampleField = value;
    }
}

样本fiddle #2.

然后我从 http://pastebin.com/raw/BJhRfFNf 和 运行 xsd.exe 下载了整个 XML 来生成一个模式,然后 classes,从 XML,并且我能够重现您的问题 - 生成了不正确的 classes。然后我手动将锯齿状数组更改为平面数组(List<T> 也可以正常工作)并且能够序列化和反序列化 XML 而不会抛出异常:

样本fiddle #3.

不幸的是,似乎只有 first </_perMainExample> 节点使用这些调整后的 classes 成功反序列化,所以此时这个自动生成的代码似乎不可行。

我不确定为什么 xsd.exe 会在此处生成错误代码,您可能想问另一个问题或向 Microsoft 提出问题。

最终更新

看起来 xsd.exe(因此 将 XML 粘贴为 类)在处理包含嵌套的重复元素时遇到了问题重复元素:

<_perMainExample>
  <_perSubExample>
  </_perSubExample>

  <_perSubExample>
  </_perSubExample>
</_perMainExample>

<_perMainExample>
  <_perSubExample>
  </_perSubExample>

  <_perSubExample>
  </_perSubExample>
</_perMainExample>

我不确定问题出在哪里,但此时我建议切换到其他代码生成工具,例如 https://xmltocsharp.azurewebsites.net/,它会生成以下 classes:

[XmlRoot(ElementName="_Example")]
public class _Example {
    [XmlElement(ElementName="_SenseNot")]
    public string _SenseNot { get; set; }
    [XmlElement(ElementName="_GrammaticNot")]
    public string _GrammaticNot { get; set; }
    [XmlElement(ElementName="_Desc")]
    public string _Desc { get; set; }
}

[XmlRoot(ElementName="_perSubExample")]
public class _perSubExample {
    [XmlElement(ElementName="_UpperTitle")]
    public string _UpperTitle { get; set; }
    [XmlElement(ElementName="_FormGroup")]
    public string _FormGroup { get; set; }
    [XmlElement(ElementName="_SenseNot")]
    public string _SenseNot { get; set; }
    [XmlElement(ElementName="_GrammaticNot")]
    public string _GrammaticNot { get; set; }
    [XmlElement(ElementName="_Desc")]
    public string _Desc { get; set; }
    [XmlElement(ElementName="_Example")]
    public List<_Example> _Example { get; set; }
    [XmlElement(ElementName="_Synonyms")]
    public string _Synonyms { get; set; }
}

[XmlRoot(ElementName="_perMainExample")]
public class _perMainExample {
    [XmlElement(ElementName="_perSubExample")]
    public List<_perSubExample> _perSubExample { get; set; }
}

[XmlRoot(ElementName="_perGroup")]
public class _perGroup {
    [XmlElement(ElementName="_GroupDesc")]
    public string _GroupDesc { get; set; }
    [XmlElement(ElementName="_GroupSense")]
    public string _GroupSense { get; set; }
    [XmlElement(ElementName="_GroupGrammer")]
    public string _GroupGrammer { get; set; }
    [XmlElement(ElementName="_perMainExample")]
    public List<_perMainExample> _perMainExample { get; set; }
}

[XmlRoot(ElementName="OxFordDefinition")]
public class OxFordDefinition {
    [XmlElement(ElementName="sourceURL")]
    public string SourceURL { get; set; }
    [XmlElement(ElementName="originDesc")]
    public string OriginDesc { get; set; }
    [XmlElement(ElementName="_perGroup")]
    public List<_perGroup> _perGroup { get; set; }
}

注意:

  1. 生成的代码非常干净。

  2. 增加了一层class_perMainExample来封装内部_perSubExample列表。

示例 fiddle #4 显示原始和重新序列化的 XML 通过调用 XNode.DeepEquals().

相同