Как десериализовать два разных типа XML в один класс - PullRequest
0 голосов
/ 28 мая 2019

У меня есть два разных XML-документа.Их структура почти идентична, но у них есть несколько разных элементов.

Я бы хотел десериализовать входящие документы в один класс , который является надмножеством обоих классов.Нет необходимости когда-либо сериализовывать класс, мне нужно только десериализовать документы.

Типы документов XML имеют другой корневой элемент, скажем, корнем первого является <CLASSA>, а другим - <CLASSB>.Я ищу что-то вроде этого, где и <CLASSA>, и <CLASSB> XML-документы сопоставляются с ClassAandB:

[XmlRoot(ElementName="CLASSA,CLASSB")]
public class ClassAandB {
    [XmlElement(ElementName="syntaxid")]
    public Syntaxid Syntaxid{ get; set; }
    [XmlElement(ElementName="email")]
    public Email Email { get; set; }
    [XmlElement(ElementName="envelope")]
    public Envelope Envelope { get; set; }
    [XmlElement(ElementName="header")]
    public Header Header { get; set; }
}

. Затем я могу узнать, какой из двух типов это, читаяСвойство синтаксиса.Это помогает мне, потому что большая часть обработки одинакова для обоих типов.Любые предложения, как это сделать?

Ответы [ 2 ]

0 голосов
/ 29 мая 2019

Поскольку имя корневого элемента xml может зависеть от содержимого документа xml, вам придется настроить XmlSerializer во время выполнения с использованием этого имени корневого элемента xml.
В этом случае больше нет необходимости применять XmlRootAttribute.

Это можно сделать через перегрузку конструктора , приняв аргумент XmlRootAttribute, через который вы передаете имя корневого элемента.

public XmlSerializer (Type type, System.Xml.Serialization.XmlRootAttribute root);

Возможно, вы знаете имя корневого элемента впереди, например. в зависимости от источника XML-документа, или вы можете обнаружить его во время выполнения из самого XML-документа.

В следующем примере показано, как устанавливается имя корневого элемента xml.

String rootName = "CLASSA"; // "CLASSB"
var serializer = new XmlSerializer(typeof(ClassAandB), new XmlRootAttribute(rootName));

Упрощенный пример использования XmlReader в качестве источника и получения имени корневого элемента xml из содержимого.

public class ClassAandB 
{
    [XmlElement(ElementName="syntaxid")]
    public String Syntaxid{ get; set; }

    [XmlElement(ElementName="email")]
    public String Email { get; set; }

    [XmlElement(ElementName="header")]
    public String Header { get; set; }
}

var classA = Deserialize(XmlReader.Create(
    new StringReader("<CLASSA><syntaxid>A</syntaxid></CLASSA>"))
    );
Console.WriteLine(classA.Syntaxid); // A

var classB = Deserialize(
    XmlReader.Create(new StringReader("<CLASSB><syntaxid>B</syntaxid></CLASSB>"))
    );
Console.WriteLine(classB.Syntaxid); // B

public static ClassAandB Deserialize(XmlReader reader)
{
    reader.MoveToContent();
    string rootName = reader.Name;
    var serializer  = new XmlSerializer(typeof(ClassAandB), 
        new XmlRootAttribute(rootName)
        );
    var deserialized = serializer.Deserialize(reader) as ClassAandB;
    return deserialized;
}
0 голосов
/ 28 мая 2019

Я предлагаю вам удалить атрибут XmlRoot и использовать:

var doc = new XmlDocument();
doc.Load("file.xml");
XmlElement root = xmlDoc.DocumentElement;
var serializer = new XmlSerializer(typeof(ClassAandB), new XmlRootAttribute(root.ToString()));
...