tags:

views:

38

answers:

2

I have an xml in the following format where action type=0 is the default settings. Actiontype 1 and 2 are override settings. So whenever Type 1 or Type 2 settings are available in the xml they should override the default settings. To override the field id's of the default type=0 I am trying to do a join with the field id of override type=1 so that I can get the type=1 values and use them within my application. Howvever the join doesnt seem to work.

Can someone suggest a better way to override the default values? Type=0 is always available but either Type=1 or Type=2 will be passed.

Is there another way to do this with reflection?

<ActionTypes>
     <ActionType Type="0">
      <Field Id="Label1" Name="StartDate" ComparePreviousYear="False" CompareCurrentYear="True"></Field>
      <Field Id="Label2" Name="EndDate" ComparePreviousYear="False" CompareCurrentYear="True"></Field>
      <Field Id="Label3" Name="Cost" ComparePreviousYear="True" CompareCurrentYear="False"></Field>
      <Field Id="Label4" Name="Total" ComparePreviousYear="False" CompareCurrentYear="False"></Field>
     </ActionType>
     <ActionType Type="1">
      <Field Id="Label3" Name="Cost" ComparePreviousYear="True" CompareCurrentYear="True"></Field>
     </ActionType>

IEnumerable<XElement> defaultFields = from test in defaultElements.Elements()
                                        where test.Attribute("Type").Value == "0"
                                      select test;

        IEnumerable<XElement> overrideFields = from test in defaultElements.Elements()
                                              where test.Attribute("Type").Value == "1"
                                              select test;

var overrideFields = from dflt in dftElements.Elements("Field")
                             join ovrd in ovrElements.Elements("Field") on dflt.Attributes("Id") equals ovrd.Attributes("Id")
                             select dflt,ovrd;
A: 

You should use Attribute here rather than Attributes:

join ovrd in ovrElements.Elements("Field")
    on dflt.Attributes("Id") equals ovrd.Attributes("Id")

As it is, you're comparing two IEnumerable<XAttribute> for equality, which will use a simple reference comaprison - which will never be true.

Pavel Minaev
@Pavel - Thank you for your tips and explanation.
Totti
A: 

This seems to work if I have understood your requirement correctly

   class Program
    {
        static void Main(string[] args)
        {
            XDocument xd = XDocument.Load("Test.xml");
            var defaultElements = xd.Document.Element("ActionTypes");


            IEnumerable<XElement> defaultFields = from test in defaultElements.Elements()
                                                  where test.Attribute("Type").Value == "0"
                                                  select test;

            IEnumerable<XElement> overrideFields = from test in defaultElements.Elements()
                                                   where test.Attribute("Type").Value == "1"
                                                   select test;

            var ovFields = from dflt in defaultFields.Elements("Field")
                           join x in overrideFields.Elements("Field") on dflt.Attribute("Id").Value equals x.Attribute("Id").Value
                           into g
                           from ovrd in g.DefaultIfEmpty()
                           select (ovrd == null ? dflt : ovrd);
            foreach (var x in ovFields.SelectMany(y=>y.Attributes()))
                Console.WriteLine("{0}           {1}", x.Name, x.Value);

            Console.ReadLine();

        }



    }
josephj1989
@josephj1989 - Thanks, your suggestion using the left join worked perfectly!
Totti