Mun
Mun

Reputation: 13

How to extract a certain sub-elements depend on the condition using Linq to XML

I have the XML (not exactly this simple but just enough for my question).

If I code like the following

    var xdoc = XDocument.Parse(@"
<Root>
    <Item>
        <Node1>Value 1</Node1>
        <Node2>Value 2</Node2>
        <Node3>Value 3</Node3>
        <Node4>Value 4</Node4>
        <Node5>Value 5</Node5>
        <Node6>Value 6</Node6>
    </Item>  
</Root>");

var results = xdoc.Root
    .Elements("Item")
    .Descendants()
    .Select(e => new { ElementName = e.Name, ElementValue = e.Value });

This will give me the result list of all descendants (node name and node value) of the "Item" element. What I want to ask is how do I get different set of data depending on the condition. For example, if Node1 or Node2 has a value (not empty), then I want the result list of Node1 and Node2 (node name and value) only, otherwise the result list should show the other nodes which is Node3, Node4, Node5 and Node6 (node name and value). Please help. Thank you.

Upvotes: 1

Views: 292

Answers (2)

Jeff Mercado
Jeff Mercado

Reputation: 134881

Your conditions are rather... odd.

var query =
    from item in doc.Root.Elements("Item")
    let elements = item.Elements()
    let firstTwo = elements.Take(2)
    let descendants = firstTwo.All(e => !String.IsNullOrWhiteSpace(e.Value))
      ? firstTwo.DescendantsAndSelf()
      : elements.Skip(2).DescendantsAndSelf()
    from e in descendants
    select new
    {
        ElementName = e.Name,
        ElementValue = e.Value,
    };

Upvotes: 0

CoderDennis
CoderDennis

Reputation: 13837

I'm not sure I completely understand your question. However, if I've got it right, then all you need to add is the condition like this:

if (condition)
    results = results.Take(2);
else
    results = results.Skip(2);

So, if condition is true, then you'll only have the first 2 nodes in your result sequence. And if condition is false, then you'll have only the remaining elements.

My first interpretation of your question was that you needed to add a call to Where in your query so that you would only have the elements that actually contain a value in your result set. That would look like this:

var results = xdoc.Root
    .Elements("Item")
    .Descendants()
    .Where(e => !string.IsNullOrEmpty(e.Value))
    .Select(e => new { ElementName = e.Name, ElementValue = e.Value }); 

Upvotes: 0

Related Questions