1

I need to serialize my Invoice model to Xml in 2 different ways.

First serialization should have "FirsName" as root element.

Second "SecondName".

There is different ways to implement, but i don't know how to implement them.

Either to avoid root element and add it manualy, or somehow dynamically preset it.

Here is my model:

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

Depending on condition I want to serialize it like:

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

or

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

Maybe it can solved by adjusting XmlWriter.Settings ?

I've found this approuch, but it seems ugly. Because it's kinda post processing...

var duplicate =  XDocument.Parse(xmlDocument.InnerXml);
duplicate.Root.Name = "newRootName";
var res = duplicate.ToString();
Andrew
  • 591
  • 2
  • 12
  • 33
  • You should have one base class root with two inherited classes firstRoot and secondRoot. Then use XmlInclude. See : https://learn.microsoft.com/en-us/dotnet/api/system.xml.serialization.xmlincludeattribute?view=netcore-3.1 – jdweng Sep 26 '20 at 11:52

2 Answers2

1

You can use XmlRootAttribute Class and inheritance:

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

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

    [XmlRoot("secondRoot")]
    public class SecondInvoiceInfo : InvoiceInfo
    {
    }
Markus Meyer
  • 3,327
  • 10
  • 22
  • 35
  • Thanks for the answer. I thought about that solution, but I'll get this model from controller class and method should always accept one implementation. – Andrew Sep 26 '20 at 11:09
1

You can dynamically add 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);

Your model

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();
    }
}

See Dynamically Generated Assemblies - you must cache the assemblies.

Alexander Petrov
  • 13,457
  • 2
  • 20
  • 49