Как исправить нулевые значения при десериализации XML - PullRequest
1 голос
/ 31 марта 2019

У меня есть XML, который я хочу десериализовать в соответствии с моими собственными классами. Он десериализуется должным образом, но некоторые значения становятся нулевыми. Это не дает ошибок, и я не уверен, где лежит ошибка.

Я пытался изменить классы, сериализовать модель памяти и затем проверить вывод, но ни один из них мне не подошел. Он должен следовать предоставленному XML.

Моя модель:

[XmlRoot(ElementName = "model", Namespace = "http://www.archimatetool.com/archimate")]
public class Model
{
    [XmlElement(ElementName = "folder")]
    public List<Folder> Folders { get; set; }
    [XmlElement(ElementName = "purpose")]
    public string Purpose { get; set; }
    [XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2000/xmlns/")]
    public string Xsi { get; set; }
    [XmlAttribute(AttributeName = "archimate", Namespace = "http://www.w3.org/2000/xmlns/")]
    public string Archimate { get; set; }
    [XmlAttribute(AttributeName = "name")]
    public string Name { get; set; }
    [XmlAttribute(AttributeName = "id")]
    public string Id { get; set; }
    [XmlAttribute(AttributeName = "version")]
    public string Version { get; set; }
}

Мой XML

<?xml version="1.0" encoding="UTF-8"?>
<archimate:model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:archimate="http://www.archimatetool.com/archimate" name="Archisurance" id="11f5304f" version="3.1.1"> 
   <folder name="Business" id="8c90fdfa" type="business">
     <folder name="Actors" id="fa63373b">
       <element xsi:type="archimate:BusinessInterface" id="1544" name="mail"/>
     </folder>
   </folder>
   <purpose>An example of a fictional Insurance company.</purpose>
</archimate:model>

Это результат, который я получаю после десериализации. Я не могу публиковать фотографии (из-за своей репутации), поэтому я просто публикую ссылку.

результат

Я ожидал бы, что в поле назначения указано «Пример вымышленной страховой компании», но оно пустое.

1 Ответ

0 голосов
/ 01 апреля 2019

Вы можете десериализовать ваш XML со следующей моделью данных:

[XmlRoot(ElementName = "model", Namespace = "http://www.archimatetool.com/archimate")]
[XmlType(Namespace = "http://www.archimatetool.com/archimate")]
public class Model
{
    [XmlElement(ElementName = "folder", Form = XmlSchemaForm.Unqualified)]
    public List<Folder> Folders { get; set; }

    [XmlElement(ElementName = "purpose", Form = XmlSchemaForm.Unqualified)]
    public string Purpose { get; set; }

    [XmlAttribute(AttributeName = "name")]
    public string Name { get; set; }

    [XmlAttribute(AttributeName = "id")]
    public string Id { get; set; }

    [XmlAttribute(AttributeName = "version")]
    public string Version { get; set; }
}

[XmlType(Namespace = "http://www.archimatetool.com/archimate")]
public class Folder
{
    [XmlAttribute(AttributeName = "name")]
    public string Name { get; set; }

    [XmlAttribute(AttributeName = "id")]
    public string Id { get; set; }

    [XmlAttribute(AttributeName = "type")]
    public string Type { get; set; }

    [XmlElement(ElementName = "folder", Form = XmlSchemaForm.Unqualified)]
    public List<Folder> Folders { get; set; }

    [XmlElement(ElementName = "element", Form = XmlSchemaForm.Unqualified)]
    public List<Element> Element { get; set; }
}

[XmlType(Namespace = "http://www.archimatetool.com/archimate")]
[XmlInclude(typeof(BusinessInterface))]
public abstract class Element
{
    [XmlAttribute(AttributeName = "name")]
    public string Name { get; set; }

    [XmlAttribute(AttributeName = "id")]
    public string Id { get; set; }
}

[XmlType(TypeName = "BusinessInterface", Namespace = "http://www.archimatetool.com/archimate")]
public class BusinessInterface : Element
{
}

Примечания:

  • Корневой элемент <archimate:model> находится в пространстве имен archimate:, но его дочерние элементы не находятся ни в одном пространстве имен, поскольку пространство имен archimate: не является пространством имен по умолчанию.Таким образом, необходимо указать XmlSerializer, что эти дочерние элементы находятся в другом пространстве имен, чем их родительские элементы.Настройка XmlElementAttribute.Form = XmlSchemaForm.Unqualified выполняет это.

    (Нет необходимости указывать, что атрибуты находятся в пространстве имен по умолчанию, поскольку все атрибуты XML считаются неквалифицированными, если не указано иное.)

  • Наличие атрибута xsi:type="archimate:BusinessInterface" указывает на то, что атрибут <element> является частью иерархии полиморфных типов.Атрибут xsi:type - это стандартный атрибут w3c , который позволяет элементу явно утверждать свой тип.XmlSerializer поддерживает этот атрибут и фактически требует наличия подтипа, соответствующего xsi:type и объявленного через атрибут [XmlInclude].

    Подробнее см. Как: управлять сериализацией производных классов .

    Здесь я сделал произвольный выбор свойств для включения в базовый классElement и производный класс BusinessInterface.Возможно, вам придется изменить этот выбор, учитывая более полный пример XML.

Пример скрипта здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...