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"> 
 <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.

1
  • It bothers me that AgentSection is pascal-case. If you are going to break convention at least be consistent. Commented Sep 21, 2010 at 20:17

2 Answers 2

5

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),
}
Sign up to request clarification or add additional context in comments.

6 Comments

@Albin. Thats wonderful. I would like to have the GetEnum method as a Generic one. Thanks M
Hi Albin, I would like to return DescriptionAttribute instead of the value.How can i achieve that? Thanks in Advance.
@Madhu Kiran: Change "return (TEnum)value;" to "return attrib;" and "return default(TEnum);" to "return null;", update the method signature to return DescriptionAttribute.
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), }
@Madhu Kiran, of course you need to change the type of the type field/attribute in the Claim type too.
|
3
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 ();

2 Comments

Thank you John that works. Is there a generic way for doing this. Say my typesectionEnum has 20 fields then?
@Madhu: use Albin's technique below :-)

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.