Nolemonpledge
Nolemonpledge

Reputation: 139

Deserialize XML nested items

Hello I am trying to get the values of each option as indicated below.

<Mailbox>
  <Menus>
    <Specs>
      <Section>Message</Section>
        <Options>
          <Option>&amp;New</Option>
          <Option>&amp;Inbox</Option>
          <Option>&amp;Outbox</Option>
          <Option>&amp;Sent Items</Option>
          <Option>S&amp;ettings</Option>
        </Options>
    </Specs>
  </Menus>
</Mailbox>

But when I run the code below:

[XmlRoot("Mailbox")]
public class Mailbox
{
    [XmlArray(ElementName = "Menus"), XmlArrayItem("Specs")]
    public Specs[] Menus { get; set; }
}

[XmlRoot("Specs")]
public class Specs
{
    [XmlElement("Section")]
    public string Section { get; set; }
    [XmlArray(ElementName = "Options"), XmlArrayItem("Option")]
    public Options[] OptionsList { get; set; }
}

[XmlRoot("Options")]
public class Options
{
    [XmlElement("Option")]
    public string Option { get; set; }
}

var deserializer = new XmlSerializer(typeof(Mailbox));
var textReader = new StreamReader(filename);
try
{
      var storage = (Mailbox)deserializer.Deserialize(textReader);
      for (int i = 0; i < storage.Menus.Length; i++)
      {
           MainMenu.Section = storage.Menus[i].Section;
           MainMenu.Options.Add(storage.Menus[i].Options[i]);
      }
}
catch (Exception e)
{
      MessageBox.Show(e.Message);
}
textReader.Close();

I am not getting the options; they all just come out as null. The OptionsList isn't coming out correctly and I don't know why.

Thanks.

Upvotes: 0

Views: 387

Answers (2)

dbc
dbc

Reputation: 117283

Your problem is that your types specify too many levels of <Option> element:

[XmlArray(ElementName = "Options"), XmlArrayItem("Option")]
public Options[] OptionsList { get; set; }

Indicates that the XML for the array should have an outer container element <Options> with inner elements <Option>. But your Options type specifies an additional nested <Option> element for its value:

[XmlRoot("Options")]
public class Options
{
    [XmlElement("Option")] // <-- This introduces an additional nested <Option> element.
    public string Option { get; set; }
}

For this to work, your XML would need to look like:

    <Options>
      <Option>
        <Option>&amp;New</Option>
      </Option>
    </Options>

Which it does not.

You can eliminate this extra level nesting by marking Options.Option with [XmlText]:

[XmlRoot("Options")]
public class Options
{
    [XmlText]
    public string Option { get; set; }
}

Upvotes: 1

Maddy
Maddy

Reputation: 774

Hi as per your xml file your serializable classes would like below

[XmlRoot(ElementName = "Options")]
public class Options
{
    [XmlElement(ElementName = "Option")]
    public List<string> Option { get; set; }
}

[XmlRoot(ElementName = "Specs")]
public class Specs
{
    [XmlElement(ElementName = "Section")]
    public string Section { get; set; }
    [XmlElement(ElementName = "Options")]
    public Options Options { get; set; }
}

[XmlRoot(ElementName = "Menus")]
public class Menus
{
    [XmlElement(ElementName = "Specs")]
    public Specs Specs { get; set; }
}

[XmlRoot(ElementName = "Mailbox")]
public class Mailbox
{
    [XmlElement(ElementName = "Menus")]
    public Menus Menus { get; set; }
}

Upvotes: 0

Related Questions