IXmlSerializable. XmlWriter. Как изменить корневой элемент?

#c# #xml #ixmlserializable

#c# #xml #ixmlserializable

Вопрос:

Мне нужно сериализовать мою модель счета-фактуры в Xml 2 различными способами.

Первая сериализация должна иметь «FirsName» в качестве корневого элемента.

Второе «Второе имя».

Существуют разные способы реализации, но я не знаю, как их реализовать.

Либо избегать корневого элемента и добавлять его вручную, либо каким-то образом динамически настраивать его.

Вот моя модель:

 public class InvoiceInfo : IXmlSerializable
{
     public int InvoiceId { get; set; }
}
  

В зависимости от условия я хочу сериализовать его следующим образом:

 <firstRoot>
    <invoiceId value="123" />
</firstRoot>
  

или

 <secondRoot>
    <invoiceId value="123" />
</secondRoot>
  

Возможно, это можно решить, настроив XmlWriter.Настройки ?

Я нашел это приложение, но оно кажется уродливым. Потому что это своего рода постобработка…

 var duplicate =  XDocument.Parse(xmlDocument.InnerXml);
duplicate.Root.Name = "newRootName";
var res = duplicate.ToString();
  

Комментарии:

1. У вас должен быть один корневой базовый класс с двумя унаследованными классами firstRoot и secondRoot. Затем используйте XmlInclude . Смотрите : learn.microsoft.com/en-us/dotnet/api /…

Ответ №1:

Вы можете использовать класс XmlRootAttribute и наследование:

     public abstract class InvoiceInfo 
    {
        public int InvoiceId { get; set; }
    }

    [XmlRoot("firstRoot")]
    public class FirstInvoiceInfo : InvoiceInfo
    {
    }

    [XmlRoot("secondRoot")]
    public class SecondInvoiceInfo : InvoiceInfo
    {
    }
  

Комментарии:

1. Спасибо за ответ. Я думал об этом решении, но я получу эту модель из класса контроллера, и метод всегда должен принимать одну реализацию.

Ответ №2:

Вы можете динамически добавлять XmlRootAttribute :

 bool condition = true;

var xmlRoot = new XmlRootAttribute(condition ? "firstRoot" : "secondRoot");

var ser = new XmlSerializer(typeof(InvoiceInfo), xmlRoot);

var invoice = new InvoiceInfo { InvoiceId = 123 };

ser.Serialize(Console.Out, invoice);
  

Ваша модель

 public class InvoiceInfo : IXmlSerializable
{
    public int InvoiceId { get; set; }

    public XmlSchema GetSchema()
    {
        throw new NotImplementedException();
    }

    public void ReadXml(XmlReader reader)
    {
        throw new NotImplementedException();
    }

    public void WriteXml(XmlWriter writer)
    {
        writer.WriteStartElement("invoiceId");
        writer.WriteAttributeString("value", InvoiceId.ToString());
        writer.WriteEndElement();
    }
}
  

Смотрите Динамически генерируемые сборки — вы должны кэшировать сборки.