LINQ 4 XML - What is the proper way to query deep in the tree structure?
- by Keith Barrows
I have an XML structure that is 4 deep:
<?xml version="1.0" encoding="utf-8"?>
<EmailRuleList xmlns:xsd="EmailRules.xsd">
<TargetPST name="Tech Communities">
<Parse emailAsList="true" useJustDomain="false" fromAddress="false" toAddress="true">
<EmailRule address="@aspadvice.com" folder="Lists, ASP" saveAttachments="false" />
<EmailRule address="@sqladvice.com" folder="Lists, SQL" saveAttachments="false" />
<EmailRule address="@xmladvice.com" folder="Lists, XML" saveAttachments="false" />
</Parse>
<Parse emailAsList="false" useJustDomain="false" fromAddress="false" toAddress="true">
<EmailRule address="northcoloradoarchitects@googlegroups.com" folder="Special Interest Groups|Northern Colorado Architects Group" saveAttachments="false" />
<EmailRule address="[email protected]" folder="Support|SpamBayes" saveAttachments="false" />
</Parse>
<Parse emailAsList="false" useJustDomain="false" fromAddress="true" toAddress="false">
<EmailRule address="support@godaddy.com" folder="Support|GoDaddy" saveAttachments="false" />
<EmailRule address="renew@no-ip.com" folder="Support|No-IP.com" saveAttachments="false" />
<EmailRule address="[email protected]" folder="Discussions|Orchard Project" saveAttachments="false" />
</Parse>
<Parse emailAsList="false" useJustDomain="true" fromAddress="true" toAddress="false">
<EmailRule address="@agilejournal.com" folder="Newsletters|Agile Journal" saveAttachments="false"/>
<EmailRule address="@axosoft.ccsend.com" folder="Newsletters|Axosoft Newsletter" saveAttachments="false"/>
<EmailRule address="@axosoft.com" folder="Newsletters|Axosoft Newsletter" saveAttachments="false"/>
<EmailRule address="@cmcrossroads.com" folder="Newsletters|CM Crossroads" saveAttachments="false" />
<EmailRule address="@urbancode.com" folder="Newsletters|Urbancode" saveAttachments="false" />
<EmailRule address="@urbancode.ccsend.com" folder="Newsletters|Urbancode" saveAttachments="false" />
<EmailRule address="@Infragistics.com" folder="Newsletters|Infragistics" saveAttachments="false" />
<EmailRule address="@zdnet.online.com" folder="Newsletters|ZDNet Tech Update Today" saveAttachments="false" />
<EmailRule address="@sqlservercentral.com" folder="Newsletters|SQLServerCentral.com" saveAttachments="false" />
<EmailRule address="@simple-talk.com" folder="Newsletters|Simple-Talk Newsletter" saveAttachments="false" />
</Parse>
</TargetPST>
<TargetPST name="[Sharpen the Saw]">
<Parse emailAsList="false" useJustDomain="false" fromAddress="false" toAddress="true">
<EmailRule address="rmiug-jobs@yahoogroups.com" folder="Head Geek|Job Alerts" saveAttachments="false" />
<EmailRule address="inkedinusmc@yahoogroups.com" folder="Social|LinkedIn USMC" saveAttachments="false"/>
</Parse>
<Parse emailAsList="false" useJustDomain="false" fromAddress="true" toAddress="false">
<EmailRule address="JobAlerts@CyberCoders.com" folder="Head Geek|Job Alerts" saveAttachments="false" />
<EmailRule address="jobs@dice.com" folder="Head Geek|Job Alerts" saveAttachments="false" />
<EmailRule address="news@cruisecritic.com" folder="Social|Cruise Critic" saveAttachments="false"/>
</Parse>
<Parse emailAsList="false" useJustDomain="true" fromAddress="true" toAddress="false">
<EmailRule address="@moody.edu" folder="Social|5 Love Languages" saveAttachments="false" />
<EmailRule address="@postmaster.twitter.com" folder="Social|Twitter" saveAttachments="false"/>
<EmailRule address="@diabetes.org" folder="Physical|American Diabetes Association" saveAttachments="false"/>
<EmailRule address="@membership.webshots.com" folder="Social|Webshots" saveAttachments="false"/>
</Parse>
</TargetPST>
</EmailRuleList>
Now, I have both an FromAddress and a ToAddress that is parsed from an incoming email. I would like to do a LINQ query against a class set that was deserialized from this XML. For instance:
ToAddress = asp@aspadvice.com
FromAddress = [email protected]
Query:
Get EmailRule.Include(Parse).Include(TargetPST) where address == ToAddress AND Parse.ToAddress==true AND Parse.useJustDomain==false
Get EmailRule.Include(Parse).Include(TargetPST) where address == [ToAddress Domain Only] AND Parse.ToAddress==true AND Parse.useJustDomain==true
Get EmailRule.Include(Parse).Include(TargetPST) where address == FromAddress AND Parse.FromAddress==true AND Parse.useJustDomain==false
Get EmailRule.Include(Parse).Include(TargetPST) where address == [FromAddress Domain Only] AND Parse.FromAddress==true AND Parse.useJustDomain==true
I am having a hard time figuring this LINQ query out. I can, of course, loop on all the bits in the XML like so (includes deserialization into objects):
XmlSerializer s = new XmlSerializer(typeof(EmailRuleList));
TextReader r = new StreamReader(path);
_emailRuleList = (EmailRuleList)s.Deserialize(r);
TargetPST[] PSTList = _emailRuleList.Items;
foreach (TargetPST targetPST in PSTList)
{
olRoot = GetRootFolder(targetPST.name);
if (olRoot != null)
{
Parse[] ParseList = targetPST.Items;
foreach (Parse parseRules in ParseList)
{
EmailRule[] EmailRuleList = parseRules.Items;
foreach (EmailRule targetFolders in EmailRuleList)
{
}
}
}
}
However, this means going through all these loops for each and every address. It makes more sense to me to query against the Objects. Any tips appreciated!