Jason Miesionczek
Jason Miesionczek

Reputation: 14448

Linq to Xml: Complex query help

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

Answers (3)

Dan Diplo
Dan Diplo

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

Andreas Grech
Andreas Grech

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

user7116
user7116

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

Related Questions