【问题标题】:XmlSerializer & Paste XML as classesXmlSerializer & 将 XML 粘贴为类
【发布时间】:2018-10-03 18:35:54
【问题描述】:

我有一个返回一些 xml 的 Web 服务。没有对应的xsd。

我在 Visual Studio 中使用了选择性粘贴 -> 将 XML 粘贴为类功能来生成与 XmlSerializer 一起使用的类:

当代码执行该行时

--> XmlSerializer xmlSerialize = new XmlSerializer(typeof(table)); <--
    table t = (table)xmlSerialize.Deserialize(new StringReader(soapResult));

它抛出一个异常:

System.InvalidOperationException: 'Unable to generate a temporary class (result=1).
error CS0030: Cannot convert type 'string[]' to 'string'
error CS0029: Cannot implicitly convert type 'string' to 'string[]'

生成的类如下所示:

// NOTE: Generated code may require at least .NET Framework 4.5 or .NET Core/Standard 2.0.
    /// <remarks/>
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
    public partial class table
    {

        private string[] labelField;

        private string[] classnameField;

        private string[] datatypeField;

        private string[][] rowField;


        /// <remarks/>
        [System.Xml.Serialization.XmlArrayItemAttribute("d", IsNullable = false)]
        public string[] label
        {
            get
            {
                return this.labelField;
            }
            set
            {
                this.labelField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlArrayItemAttribute("d", IsNullable = false)]
        public string[] classname
        {
            get
            {
                return this.classnameField;
            }
            set
            {
                this.classnameField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlArrayItemAttribute("d", IsNullable = false)]
        public string[] datatype
        {
            get
            {
                return this.datatypeField;
            }
            set
            {
                this.datatypeField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlArrayItemAttribute("d", typeof(string), IsNullable = true)]
        public string[][] row
        {
            get
            {
                return this.rowField;
            }
            set
            {
                this.rowField = value;
            }
        }
    }

问题出在行字段上,因为其他字段工作正常。 如果我改变了

[System.Xml.Serialization.XmlArrayItemAttribute("d", typeof(string), IsNullable = true)]

[System.Xml.Serialization.XmlArrayItemAttribute("d", typeof(string[]), IsNullable = true)]

错误消失了,但我的对象只有一个空字符串数组。

被反序列化的 XML 数据(为简单起见进行了压缩)如下所示

<?xml version="1.0" encoding="UTF-8"?>
<table>
   <label>
      <d>JobDefinition.SearchName</d>
      <d>Job.JobDefinition</d>
   </label>
   <classname>
      <d>JobDefinition.SearchName</d>
      <d>Job.JobDefinition</d>
   </classname>
   <datatype>
      <d>String</d>
      <d>obj.JobDefinition</d>
   </datatype>
   <row>
      <d>AB_DEFG_QA_RUN</d>
      <d>A_JOB_Run</d>
   </row>
   <row>
      <d>AB_DEFG_QA_RUN</d>
      <d>B_JOB_Run</d>
   </row>
</table>

【问题讨论】:

标签: c# xml xmlserializer


【解决方案1】:

您的问题看起来与this answerHow to serialize List&lt;List&lt;object&gt;&gt;?最终更新 中描述的问题相同,即xsd.exe(因此将XML 粘贴为类 ) 无法为包含重复元素的 XML 推断正确的数据模型,该重复元素包含嵌套的重复元素,此处为 &lt;row&gt;&lt;d&gt;

<table>
   <row>
      <d>Value of repeating element inside a repeating element.</d>
      <d>Value of repeating element inside a repeating element.</d>
   </row>
   <row>
      <d>Value of repeating element inside a repeating element.</d>
      <d>Value of repeating element inside a repeating element.</d>
   </row>
</table>

该答案中的建议是使用不同的代码生成工具或手动构建类。我把你的XML上传到https://xmltocsharp.azurewebsites.net/,合并重复类后,得到如下数据模型:

[XmlRoot(ElementName = "row")]
public class Row
{
    [XmlElement(ElementName = "d")]
    public List<string> D { get; set; }
}

[XmlRoot(ElementName = "table")]
public class Table
{
    [XmlElement(ElementName = "label")]
    public Row Label { get; set; }
    [XmlElement(ElementName = "classname")]
    public Row Classname { get; set; }
    [XmlElement(ElementName = "datatype")]
    public Row Datatype { get; set; }

    [XmlElement(ElementName = "row")]
    public List<Row> Row { get; set; }
}

使用它,我能够成功地反序列化和重新序列化您的 XML,而不会丢失数据。备注:

  • 代码生成工具为LabelClassnameDatatypeRow 生成了不同但相同的类。我决定将它们全部合并为一个 Row 类型,并将其用于 Table 的所有相关成员。

小提琴样本here.

【讨论】:

  • 谢谢,我最终手动配置注释以使其正常工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-09
  • 2013-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多