MH175
MH175

Reputation: 2334

C# Linq Get XML Value On Condition

I'm having problems finding the correct syntax to use.

I hope the code below will demonstrate the problem better than I can explain it in words. I am trying to retrieve an anonymous type based on matching conditions. I have to first check the Attribute for a match, and return the value only if the condition is met. If the element has an attribute named "value1" I get back the value for the attribute named "value" on the same element.

I put arrows <--- to show pseudocode where the problem is.

Thanks in advance to anyone that can help.

<item name="DataStore" >
    <int name="item1" value="895"/>
    <int name="item2" value="245"/>
</item>
<item name="DataStore" >
    <int name="item1" value="540"/>
    <int name="item2" value="97"/>
</item>


var result = from items in doc.Descendants()
             where (string)items.Attribute("name") == "DataStore"
             select new {
                item1Value = items.Attribute("value").Value, <--- where items.Attribute("name") == "item1" ???
                item2Value = items.Attribute("value").Value <--- where items.Attribute("name") == "item2" ???
             }

To be more clear I need to return a "Tuple" result that has result.value1 and result.value2

So in the end I want to say something like:

foreach (var item in result) {
     Console.WriteLine(item.value1); //Prints 895 on first iteration
     Console.WroteLine(item.value2); //Prints 245 on first iteration
}

Upvotes: 0

Views: 275

Answers (1)

John Koerner
John Koerner

Reputation: 38077

You need to select the child items from the items that you found that matched the DataStore and filter those based on your criteria.

var xml = @"<root><item name=""DataStore"" >
         <int name=""item1"" value=""895""/>
         <int name=""item2"" value=""245""/>
    </item>
    <item name=""DataStore"" >
        <int name=""item1"" value=""540""/>
        <int name=""item2"" value=""97""/>
    </item></root>";

var doc = XDocument.Parse(xml);
var result = from items in doc.Descendants()
             where (string)items.Attribute("name") == "DataStore"
             select new
             {
                 item1Value = (from d in items.Descendants() where d.Attributes("name").FirstOrDefault().Value.Equals("item1") select d.Attributes("value").FirstOrDefault().Value).FirstOrDefault(),
                 item2Value = (from d in items.Descendants() where d.Attributes("name").FirstOrDefault().Value.Equals("item2") select d.Attributes("value").FirstOrDefault().Value).FirstOrDefault()
             };


foreach (var r in result)
{
    Console.WriteLine($"Result {r.item1Value} {r.item2Value}");
}
Console.ReadLine();

Upvotes: 2

Related Questions