Question

My Classes:

public class SectionDto
{
    [XmlAttribute]
    public int Id { get; set; }

    [XmlElement("subSection1", typeof(departmentDto)),
     XmlElement("subSection2", typeof(divisionDto))]
    public List<CommonSubSectionDto> SubSection { get; set; }
}

public class CommonSubSectionDto
{
}

public class DepartmentDto : CommonSubSectionDto
{
    [XmlAttribute]
    public int Id { get; set; }

    [XmlElement]
    public string Summary { get; set; }
}

public class DivisionDto : CommonSubSectionDto
{
    [XmlAttribute]
    public int Id { get; set; }

    [XmlElement]
    public string Name { get; set; }
}

The XML looks like the following:

<root>
    <Section>
        <SubSection1 Id="123">
            <Summary> Summary 123 </Summary>
        <SubSection1 />
        <SubSection1 Id="124">
            <Summary> Summary 124 </Summary>
        <SubSection1 />

        <SubSection2 Id="987">
            <Name> Division Name </Name>
        <SubSection2 />
    <section>
    ...
</root>

So i would like it so instead of the inherited classed being given individual names such as "SubSection1" and "SubSection2", i would like it to be that its called "SubSection".

Is this possible? If so please could someone advise? Else is there an alternative ??

I was also thinking to remove my inherting classes and replace it with a single class called SubSection and it has both the elements, however one of the elements Summary or Name will be an empty xml element, but i wanted to see what the practices are for this scenario, and to find alternative solution.

Thank you for your help.

Kush

Was it helpful?

Solution

By design, there must be a way for the runtime to know to which type an xml element should be deserialized. If the xml tag is the same for both DTO, when deserializing, the system can't infer the appropriate target type. But you can change a little bit of it. The following definitions :

public class SectionDto
{
    [XmlAttribute]
    public int Id { get; set; }

    public List<SubSection> SubSections { get; set; }
}

[XmlInclude(typeof(DepartmentDto))]
[XmlInclude(typeof(DivisionDto))]
public abstract class SubSection
{
    [XmlAttribute]
    public int Id { get; set; }
}

public class DepartmentDto : SubSection
{
    [XmlElement]
    public string Summary { get; set; }
}

public class DivisionDto : SubSection
{
    [XmlElement]
    public string Name { get; set; }
}

Give this xml :

<SectionDto xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Id="0">
  <SubSections>
    <SubSection xsi:type="DepartmentDto" Id="123">
      <Summary>Summary 123</Summary>
    </SubSection>
    <SubSection xsi:type="DepartmentDto" Id="124">
      <Summary>Summary 124</Summary>
    </SubSection>
    <SubSection xsi:type="DivisionDto" Id="987">
      <Name>Division Name</Name>
    </SubSection>
  </SubSections>
</SectionDto>

But it's pretty much the same problem that was moved to the xsi:type attribute.

With this :

public class SubSection
{
    [XmlAttribute]
    public int Id { get; set; }

    [XmlElement]
    public string Summary { get; set; }

    [XmlElement]
    public string Name { get; set; }
}

You get this xml :

<SectionDto xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Id="0">
  <SubSections>
    <SubSection Id="123">
      <Summary>Summary 123</Summary>
    </SubSection>
    <SubSection Id="124">
      <Summary>Summary 124</Summary>
    </SubSection>
    <SubSection Id="987">
      <Name>Division Name</Name>
    </SubSection>
  </SubSections>
</SectionDto>

Which was one of your suggestion but you might need to write more code when deserializing to infer by yourself the appropriate type of your objects according to which properties are set. I would personally choose the last version only if I have to produce xml for another system (so I would never have to deserialize in my application) but the strongly typed version might get my vote if I had to load the xml data afterwards.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top