Linq to Xml:复杂的查询帮助

时间:2023-01-09 01:31:20

Assume i have the following XML data:

假设我有以下XML数据:

<?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.

在给定帐户和远程广告系列名称时,我需要确定广告系列名称。在Linq to Xml中有一个简单的方法吗?可以假设所有值都是唯一的。

3 个解决方案

#1


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;

#2


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.

上面的函数假定每个Campaign都有一个名称,否则将抛出NullReferenceException;因此,如果您认为并非所有广告系列都有名称,请将其拆分并检查是否为空。

#3


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();

#1


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;

#2


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.

上面的函数假定每个Campaign都有一个名称,否则将抛出NullReferenceException;因此,如果您认为并非所有广告系列都有名称,请将其拆分并检查是否为空。

#3


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();