As usual, I use this code below to getting Alexa VietNam Rank, the VietNam rank is in the element:

<COUNTRY CODE="VN" NAME="Vietnam" RANK="20"/>

There is just only one element <COUNTRY> here.

private int GetAlexaRank(string domain)
{
    var alexaRank = 0;
    try
    {
        var url = string.Format("http://data.alexa.com/data?cli=10&dat=snbamz&url={0}", domain);

        var doc = XDocument.Load(url);
         var vnrank = doc.Descendants("COUNTRY").Select(node => node.Attribute("RANK").Value).FirstOrDefault();// Vietnam Rank
        if (!int.TryParse(vnrank, out alexaRank))
            alexaRank = -1;

    }
    catch (Exception e)
    {
        return -1;
    }

    return alexaRank;
}

But in this situation, it has two element: The VietNam RANK is in the secound element , how can I get it?

有帮助吗?

解决方案

 alexaRank = doc.Descendants("COUNTRY")
                .Select(c => (int?)c.Attribute("RANK"))
                .Where(r => r.HasValue)
                .FirstOrDefault() ?? -1;

HOW IT WORKS: all COUNTRY descendants are selected from xml response (no matter where these elements sit in xml). Then from each country element we select attribute RANK and cast this attribute to nullable integer. That gives null if country do not have rank attribute or value of this attribute. Then we select first or default value from rank attributes values. If nothing is found, then it gives us a null. With null-coalescing operator ?? we assign -1 instead of null. If someting is found, then value of nullable integer will be assigned to alexaRank.

So, you will not get parsing exceptions here - if country node not found, or there is no country node with rank attribute (well, only if rank is not integer). But you still can get another exceptions, like errors if network is not available. So, you can keep try catch here. But do not swallow exception! You should log it.

Also you can use XPath:

private int GetAlexaRank(string domain)
{
    try
    {        
        var doc = XDocument.Load(url);
        var country = xdoc.XPathSelectElement("//COUNTRY[@RANK]");
        if (country == null)
            return 0;

        return (int)country.Attribute("RANK");
    }
    catch (Exception e)
    {
        // Log exception here!    
        return -1;
    }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top