Click here to Skip to main content
16,008,183 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have not been able to get a two-level filter to work using Linq.

Pasted up are

1) xml excerpt and
2) code fragment with two data objects, LineItem and LineList and a query.

The objective of firstQuery is to create a List<> of LineList objects each of which has a sublist comprising one or more LineItem objects.

I want to begin by filtering for the section (section) level Attribute (lvl) to narrow my search. Secondly, I want to select a subsection (subSec) based on the Element("subSec").Attribute (“ssn”).

The concatenated ‘where’ statement shows the intent of my filter.

It only tests the first occurrence of lvl and ssn and does not drill down into the section to test the next value of ssn if the first one doesn’t match.

I have tried various ways of adding in an additional level of ‘from’ and ‘where’ clauses but I can’t quite work out the order and syntax to get it to work. I’d appreciate any constructive comments or hints to get a two-level Linq query to work.

Thanks

HTML
<mainxml>
<section lvl="0">
	<subsec ssn="a">
		<item>with</item>
		<item>a little</item>	
		<item>help</item>	
	</subsec>
	<subsec ssn="b">
		<item>from</item>
		<item>my</item>	
		<item>friends</item>
	</subsec>	
</section>
<section lvl="1">
	<subsec ssn="y">
		<item>Ive</item>
		<item>got</item>	
		<item>the</item>
	</subsec>		
	<subsec ssn="z">
		<item>music</item>
		<item>in</item>	
		<item>me</item>
	</subsec>
</section>
</mainxml>


What I have tried:

C#
//===============================================================
public class LineItem() //----------------------------------
{
	public int WdCtr {get; set;}
	public string Word {get; set;}
} // eo class LineItem -------------------------------------

public class LineList() // ---------------------------------
{
	public List<lineitem> Includes {get; set;}
} // eo class lineList -------------------------------------

void firstQuery() // ------------------------------------------
{
	int ctr = -1;

	var mainList = (from sect in XLineDoc.Descendents("section")
		where sect.Attirbute("lvl").Value=="1" && sect.Element("subSec").Attribute("ssn").Value ="z"			
                  select new LineList
                       {
                          Includes=(from wd in sect.Elements("subSec").Element("item") 
                                select new LineItem
				{
				 WdCtr=ctr++,
				 Word = wd.Value
				}).ToList()        
					                                          
			}).ToList();

} // eo firstQuery ----------------------------------------------</lineitem>
Posted
Updated 11-Aug-16 3:09am
v2

1 solution

Assuming you only want the subsections with a matching ssn, something like this should work:
C#
from sect in XLineDoc.Descendants("section")
where (int?)sect.Attribute("lvl") == 1
let list = new LineList
{
    Includes = (from ss in sect.Elements("subSec")
                where (string)ss.Attribute("ssn") == "z"
                from wd in ss.Elements("item")
                select new LineItem
                {
                    WdCtr = ctr++,
                    Word = wd.Value
                }).ToList()
}
where list.Includes.Count != 0
select list;
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900