XmlSerializer & Paste XML как классы - PullRequest
       10

XmlSerializer & Paste XML как классы

0 голосов
/ 03 октября 2018

У меня есть веб-сервис, который возвращает XML.Нет соответствующего xsd.

Я использовал Paste Special -> Paste XML как функциональность классов в Visual Studio, чтобы сгенерировать классы для использования с 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>

1 Ответ

0 голосов
/ 10 октября 2018

Ваша проблема выглядит идентично той, которая описана в Окончательном обновлении из этого ответа до Как сериализовать List<List<object>>? , а именно, что xsd.exe(и, таким образом, Вставить XML как классы ) возникают проблемы с выводом правильной модели данных для XML, содержащей повторяющийся элемент, который содержит вложенные повторяющиеся элементы, здесь <row> и <d>:

<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 без потери данных,Примечания:

  • Инструмент генерирования кода генерировал различные, но идентичные классы для Label, Classname, Datatype и Row.Я решил объединить их все в один тип Row и использовать его для всех соответствующих членов Table.

Образец скрипки здесь .

...