LINQ to XML using joins
I have an XML file 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 doesn't seem to work. Is there 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?
XML
<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>
<ActionType Type="2">
<Field Id="Label2" Name="EndDate" ComparePreviousYear="True" CompareCurrentYear="True"></Field>
</ActionType>
</ActionTypes>
Code
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;
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.
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();
}
}
精彩评论