tags:

views:

335

answers:

3

Assume i have the following XML data:

<?xml version="1.0" encoding="utf-8" ?>
<Accounts>
    <Account name="Account1">
     <Campaign name="Camp1">
      <RemoteCampaign>RC1</RemoteCampaign>
      <RemoteCampaign>RC2</RemoteCampaign>
     </Campaign>
     <Campaign name="Camp2">
      <RemoteCampaign>RC3</RemoteCampaign>
     </Campaign>

    </Account>
    <Account name="Account2">
     <Campaign name="Camp3">
      <RemoteCampaign>RC4</RemoteCampaign>
     </Campaign>
     <Campaign name="Camp4">
      <RemoteCampaign>RC5</RemoteCampaign>
     </Campaign>

    </Account>
</Accounts>

I need to determine the Campaign name when given the account and the remote campaign name. Is there an easy way to do this in Linq to Xml? It can be assumed that all values are unique.

+2  A: 

The following could work:

var query = from aa in xdoc.Descendants("Account")
            where    aa.Attribute("name") != null
                  && aa.Attribute("name").Value == accountName
            from cc in aa.Descendants("Campaign")
            where    cc.Attribute("name") != null
                  && cc.Descendants("RemoteCampaign").Any(elt => elt.Value == remoteName)
            select cc.Attribute("name").Value;
sixlettervariables
A: 
public static string GetCampaignName(string xml, string accountName, string rcName)
{
 return XDocument.Parse(xml).Descendants("Account")
  .Where(a => string.Equals(a.Attribute("name").Value,accountName)).Descendants("Campaign")
  .Where(c => c.Descendants("RemoteCampaign").Select(rc => rc.Value).Contains(rcName))
  .First().Attribute("name").Value;
}

The above function assumes that each Campaign will have a name though, or else a NullReferenceException will be thrown; so if you think that not all Campaigns will have names, split it and check for nulls.

Andreas Grech
A: 

This works, but might not be most efficient:

     XDocument xml = XDocument.Load(Server.MapPath("XMLFile.xml"));
 string account = "Account1";
 string remoteCampaign = "RC1";
 string campaign = xml.Descendants()
  .Where(rc => rc.Value == remoteCampaign && rc.Ancestors("Account").Any(a => a.Attribute("name").Value == account))
  .Where(n => n.Parent.Name == "Campaign")
  .Select(c => c.Parent.Attribute("name").Value).FirstOrDefault();
Dan Diplo