0

I have an XML document:

<Preferences>
    <Section Name="PREF_SECTION_NAME_1">
        <Preference Name="PREF_NOTIFY" Type="radio">
            <Options>
                <Option Name="PREF_OPT_YES" Value="true"/>
                <Option Name="PREF_OPT_NO" Value="false"/>
            </Options>
            <Default>true</Default>
       </Preference>
       <Preference Name="PREF_EXAMPLE" Type="textarea" >
           <Default>lots and lots of lines of text"</Default>
       </Preference> 
   </Section>
</Preferences>

This my Model:

[XmlRoot("Preferences")]
public class PreferencesModel
{
    [XmlElement(ElementName = "Section")]
    public List<Section> Section { get; set; }
}

public class Section
{
    [XmlAttribute("Name")]
    public string Name { get; set; }

    [XmlElement("Preference")]
    public List<PreferenceModel> PreferenceModel { get; set; }
}

[XmlType("Preference")]
public class PreferenceModel
{
    [XmlAttribute("Type")]
    public string Type { get; set; }

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

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

    [XmlElement("Options")]
    public List<Option> Options { get; set; }
}

[XmlAttribute("Name")]
[XmlType("Option")]
public class Option
{
    public string Name { get; set; }

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

I use XDocument to make this XML data accessible via Linq:

My Method to XML to Model:

public PreferencesModel GetDefaults(XmlDocument userDoc)
{
    XDocument xDocUser = userDoc.ToXDocument();

    return new PreferencesModel()
    {
        Section = xDocUser.Root.Elements("Section").Select(x => new Section()
        {
            Name = x.Attribute("Name").Value,
            PreferenceModel = x.Elements("Preference").Select(
            y => new PreferenceModel()
            {
                Name = y.Attribute("Name").Value,
                Default = (string)y.Element("Default").Value,
                Type = y.Attribute("Type").Value,
                Options = y.Elements("Options").Select(z => new Option()
                {
                    Name = z.Attribute("Name").Value,
                    Value = z.Attribute("Value").Value
                }).ToList(),
            }).ToList(),
        }).ToList()
    };
}

and when i run I get this:

enter image description here

3
  • I'd suggest to use XmlSerialization/deserialization. Commented May 25, 2016 at 10:59
  • @MaciejLos Not option for me here Commented May 25, 2016 at 10:59
  • Change "Options" to "Option". Options does not have any attributes. Commented May 25, 2016 at 11:12

2 Answers 2

2

In your context, y is the element Preference. You then select all its child Options elements and get their Name and Value attributes.

Options doesn't have any attributes, it only has child Option elements.

Your Options selector should be:

y.Descendants("Option").Select(z => new Option
{
    Name = (string)z.Attribute("Name"),
    Value = (string)z.Attribute("Value")
}

Note that I've also used the explicit conversions from XAttribute to string here. This has the advantage of returning null if the attribute doesn't exist rather than throwing a NullReferenceException.

However... why not use the XmlSerializer given you've marked everything up with attributes already?

Sign up to request clarification or add additional context in comments.

1 Comment

Charles, thanks for your answer. I keep forgetting about Descendants! The code I am working on is just a small part of a huge process. Just picking up stuff here :)
0

Simply deserializing your XML will give you expected result:

using (var reader = new StringReader(xml))
{
    var xmlSerializer = new XmlSerializer(typeof(PreferencesModel));
    var data = xmlSerializer.Deserialize(reader);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.