views:

104

answers:

2

I am trying to extract data from XML file and save it my C# class/object. My problem is

I have an XMl file like this

<personal_auto xmlns = "http://cp.com/rules/client"&gt; 
 <claim id = "s1" type = "Subject Section">
    <report > 
    </report> 
    <policy>
    </policy>
 </claim>
 <claim id = "s2" type = "Vehichle Section">
    <report >
    </report>
    <policy>
    </policy>
  </claim>
  <claim id = "s3" type = "Agent Section">>
    <report 
    </report>
    <policy>
    </policy>
  </claim>
</personal_auto> 

I have an enum like this

    public enum typesectionEnum
    {
        [Description("Subject Section")]
        subjectSection,
        [Description("Vehicle Section")]
        vehicleSection,
        [Description("Possible Related Section")]
        possibleRelatedSection,
        [Description("Agent (Summary) Section")]
        AgentSection
    }

I am trying to extract data from the XML file and save to my C# class/object.

List<claim> = ( from d in query.Descendants(xmlns + "claim")
                 select new Claim 
                   {
                    id = d.Attribute("id").value,
                    type = ????                    
                    }
                 ).ToList (),

What I am wondering is, I want to set the value in my application that will access the value in the xml file.

+2  A: 
List<claim> claims = ( 
    from d in query.Descendants(xmlns + "claim") 
    let t = d.Attribute("type").Value
    select new Claim  
    { 
        id = d.Attribute("id").value, 
        type =  t == "Subject Section" ? typesectionEnum.subjectSection :
                (t == "Vehicle Section" ? typesectionEnum.vehicleSection :
                 (t == "Possible Related Section" ? typesectionEnum.possibleRelatedSection :
                                                    typesectionenum.AgentSection))
     }
 ).ToList ();
John Saunders
@Chaos: I'm consistent with the posted code.
John Saunders
Thank you John that works. Is there a generic way for doing this. Say my typesectionEnum has 20 fields then?
BumbleBee
@Madhu: use Albin's technique below :-)
John Saunders
+4  A: 

If the DescriptionAttributes matches exactly with the type attribute strings in the XML you can use reflection.

Edit: convert to generic

public TEnum GetEnum<TEnum>(string input) where TEnum : struct
{
    if (!typeof(TEnum).IsEnum)
        throw new Exception(typeof(TEnum).GetType() + " is not en enum");
    Type dataType = Enum.GetUnderlyingType(typeof(typesectionEnum));
    foreach (FieldInfo field in
        typeof(typesectionEnum).GetFields(BindingFlags.Static | BindingFlags.GetField |
        BindingFlags.Public))
    {
        object value = field.GetValue(null);
        foreach (DescriptionAttribute attrib in field.GetCustomAttributes(true).OfType<DescriptionAttribute>())
        {
            if (attrib.Description == input)
            {
                return (TEnum)value;
            }
        }
    }
    return default(TEnum);
}

and then call it like this:

select new Claim 
{
    id = d.Attribute("id").value,
    type = GetEnum<typesectionEnum>(d.Attribute("type").value),
}
Albin Sunnanbo
@Albin. Thats wonderful. I would like to have the GetEnum method as a Generic one. Thanks M
BumbleBee
@Madhu Kiran: Like that?
Albin Sunnanbo
Works like Charm. Thank you very much.
BumbleBee
Hi Albin, I would like to return DescriptionAttribute instead of the value.How can i achieve that? Thanks in Advance.
BumbleBee
@Madhu Kiran: Change "return (TEnum)value;" to "return attrib;" and "return default(TEnum);" to "return null;", update the method signature to return DescriptionAttribute.
Albin Sunnanbo
Hi Albin,Thank you. I get "Type of conditional expression cannot be determined because there is no impicit conversion between 'System.ComponentModel.DescriptionAttribute' and 'typesectionEnum'" at the below line of code (Marked with ***) select new Claim { id = d.Attribute("id").value, *** type = GetEnum<typesectionEnum>(d.Attribute("type").value), }
BumbleBee
My C# object looks like : public class Claim { public typesectionEnum type { get; set; } }
BumbleBee
@Madhu Kiran, of course you need to change the type of the type field/attribute in the Claim type too.
Albin Sunnanbo