LINQ 4 XML - What is the proper way to query deep in the tree structure?

Posted by Keith Barrows on Stack Overflow See other posts from Stack Overflow or by Keith Barrows
Published on 2010-03-25T17:46:06Z Indexed on 2010/03/26 13:33 UTC
Read the original article Hit count: 680

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="[email protected]" 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="[email protected]" folder="Support|GoDaddy" saveAttachments="false" />
      <EmailRule address="[email protected]" 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="[email protected]" folder="Head Geek|Job Alerts" saveAttachments="false" />
      <EmailRule address="[email protected]" folder="Social|LinkedIn USMC" saveAttachments="false"/>
    </Parse>
    <Parse emailAsList="false" useJustDomain="false" fromAddress="true" toAddress="false">
      <EmailRule address="[email protected]" folder="Head Geek|Job Alerts" saveAttachments="false" />
      <EmailRule address="[email protected]" folder="Head Geek|Job Alerts" saveAttachments="false" />
      <EmailRule address="[email protected]" 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 = [email protected] 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!

© Stack Overflow or respective owner

Related posts about linq-to-xml

Related posts about linq-to-objects