Reputation: 14448
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.
Upvotes: 1
Views: 1704
Reputation: 25339
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();
Upvotes: 0
Reputation: 107950
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.
Upvotes: 0
Reputation: 64068
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;
Upvotes: 2