0

I have a piece of XML that I need to serialize/deserialize but I'm having a lot of difficulty in getting it to work exactly as needed. The code I have works for 98% of the structure but I'm unable to get attributes serialized/deserialized on the root node.

Sample XML;

<rootNode date="2000-01-01" time="07:00">
    <detail>
        <reference>12345</reference>
    </detail>
</rootNode>

Classes currently being used to deserialize to;

[XmlType("detail")]
public class Detail
{
    [XmlElement("reference")]
    public string Reference { get; set; }
}

[XmlRoot("rootNode")]
public class Root : List<Detail>
{
    [XmlAttribute("date")]
    public string Date { get; set; }

    [XmlAttribute("time")]
    public string Time { get; set; }
}

The specifics of each element being renamed from the actual XML is important and necessary in my implementation. If I don't inherit from List<Detail> and have a collection property (assume Details of same type) then I can get the attributes but end up with XML like;

<rootNode date="2000-01-01" time="07:00">
    <Details>
        <detail>
            <reference>12345</reference>
        </detail>
    </Details>
</rootNode>

But that isn't what I'm trying to deserialize. Controlling the way it's serialized via XmlArray and XmlArrayItem allows me to rename the collection node and the item nodes but not get rid of the collection node itself. Any suggestions?

DiskJunky
  • 4,750
  • 3
  • 37
  • 66

3 Answers3

3

I think you should remove inheritance from Root to List, and add the Details attribute to Root:

[XmlType("detail")]
public class Detail
{
    [XmlElement("reference")]
    public string Reference { get; set; }
}

[XmlRoot("rootNode")]
public class Root
{
    [XmlAttribute("date")]
    public string Date { get; set; }

    [XmlAttribute("time")]
    public string Time { get; set; }

    [XmlElement("detail")]
    List<Detail> Details  { get; set; }

}
Oscar
  • 13,594
  • 8
  • 47
  • 75
1
[XmlType("detail")]
public class Detail
{    
    [XmlElement("reference")]
    public string Reference { get; set; }}   
}
[XmlRoot("rootNode")]
public class Root
{
    [XmlAttribute("date")]
    public string Date { get; set; }

    [XmlAttribute("time")]
    public string Time { get; set; }

    [XmlElement("detail")]
    public Detail detail{ get; set; }
}

or you use "customized" serialization with IXmlSerializable Override XML Serialization Method

Community
  • 1
  • 1
Mat
  • 1,960
  • 5
  • 25
  • 38
  • close but you forgot your closing `}` for the `Detail` object. Bumped up as very close to Oscar's solution – DiskJunky Aug 10 '16 at 10:20
  • 1
    I'm not sure nesting the classes like that is the way to go. Apart from which,you have the detail object outside the root which is the inverse of what's needed structurally – DiskJunky Aug 10 '16 at 10:33
  • 1
    fixed it again -> I still struggle with the stackoverflow "code editor" ;-) – Mat Aug 12 '16 at 06:21
1

This is just an additional background for what @Oscar mentions in his answer.

As often: favor composition over inheritance. Basically you should ask yourself if your Root-element is a list of Details, or if it has one. If in doubt consider the following:

Your Root-element should be an instance having some properties. It also has a list of elements within it, the Details. If you were after overriding the list, you say basically a Root is a list, however I want to override how that list works behind (for example you want to modify the Add-method to do something different). However In your case all you want to do is to extend the list instead of override it, don´t you?

MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111
  • agreed and that is indeed what I started with. It'd be my preference but frankly, I need something working over design principles :) – DiskJunky Aug 10 '16 at 10:12