0

This is my 3 sample xml files:

<?xml version = '1.0' encoding = 'UTF-8'?>
<ABC>
  <Header>
    <Date>2020-03-20T09:08:29Z</Date>
    <Code>A101</Code>    
  </Header>
  <Document>
    <AAA>Test Data 123</AAA>
    <BBB>Test Date 456</BBB>
  </Document>
</ABC>

<?xml version = '1.0' encoding = 'UTF-8'?>
<ABC>
  <Header>
    <Date>2020-03-20T09:08:29Z</Date>
    <Code>A106</Code>    
  </Header>
  <Document>
    <MMM>Test Data 123</MMM>
    <ZZZ>Test Data 456</ZZZ>
    <CCC>Test Data 888</CCC>    
  </Document>
</ABC>

<?xml version = '1.0' encoding = 'UTF-8'?>
<ABC>
  <Header>
    <Date>2020-03-20T09:08:29Z</Date>
    <Code>A100</Code>    
  </Header>
  <Document>
    <QQQ>Test Data 999</QQQ>
    <LLL>Test Data 000</LLL>
  </Document>
</ABC>

Notice that the Header schema is the same but the schema inside Document tag are different based on the Code tag

And here are my classes. Since the Header is the same, I move the Header to another class.

namespace Model.A100
{
    [XmlRoot(ElementName = "Document")]
    public class Document
    {
        [XmlElement(ElementName = "QQQ")]
        public string QQQ { get; set; }
        [XmlElement(ElementName = "LLL")]
        public string LLL { get; set; }
    }

    [XmlRoot(ElementName = "ABC")]
    public class ABC
    {
        [XmlElement(ElementName = "Header")]
        public Header Header { get; set; }
        [XmlElement(ElementName = "Document")]
        public Document Document { get; set; }
    }

}

namespace Model.A101
{
    [XmlRoot(ElementName = "Document")]
    public class Document
    {
        [XmlElement(ElementName = "AAA")]
        public string AAA { get; set; }
        [XmlElement(ElementName = "BBB")]
        public string BBB { get; set; }
    }

    [XmlRoot(ElementName = "ABC")]
    public class ABC
    {
        [XmlElement(ElementName = "Header")]
        public Header Header { get; set; }
        [XmlElement(ElementName = "Document")]
        public Document Document { get; set; }
    }
}

namespace Model.A106
{
    [XmlRoot(ElementName = "Document")]
    public class Document
    {
        [XmlElement(ElementName = "MMM")]
        public string MMM { get; set; }
        [XmlElement(ElementName = "ZZZ")]
        public string ZZZ { get; set; }
        [XmlElement(ElementName = "CCC")]
        public string CCC { get; set; }
    }

    [XmlRoot(ElementName = "ABC")]
    public class ABC
    {
        [XmlElement(ElementName = "Header")]
        public Header Header { get; set; }
        [XmlElement(ElementName = "Document")]
        public Document Document { get; set; }
    }
}

namespace Model
{
    [XmlRoot(ElementName = "Header")]
    public class Header
    {
        [XmlElement(ElementName = "Date")]
        public string Date { get; set; }
        [XmlElement(ElementName = "Code")]
        public string Code { get; set; }
    }
}

To deserialize to Xml to C# object,

var serializer = new XmlSerializer(typeof(Model.Header));

using (TextReader reader = new StreamReader(new FileStream(filePath, FileMode.Open)))
{
    var obj = (Model.Header)serializer.Deserialize(reader);

   // do something
}

Now that I can extract out the Header, how do I do the same for the Document tag which is based on Code tag? Surely, I can't be writing if statement or switch case.

Steve
  • 2,963
  • 15
  • 61
  • 133
  • 3
    Write custom serializer. – T.S. Mar 12 '21 at 22:48
  • 1
    `XmlSerializer` supports two mechanisms for deserializing polymorphic subtypes. The type can be specified by an `xsi:type` attribute, or by using different element names. See [Using XmlSerializer to serialize derived classes](https://stackoverflow.com/q/1643139/3744182) for details. Your case doesn't match either of these patterns, so manual deserialization looks necessary. – dbc Mar 13 '21 at 01:11
  • 1
    Why do you care when you are deseriailizing? Make one class with all the properties and then handle the different cases after you parse the xml. – jdweng Mar 13 '21 at 11:57

0 Answers0