1

像往常一样,我使用下面的代码来获取 Alexa VietNam Rank,VietNam rank 在元素中:

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

这里只有一个元素<COUNTRY>

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;
}

但是在这种情况下,它有两个元素:VietNam RANK 在第二个元素中,我怎样才能得到它?

4

1 回答 1

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

它是如何工作的:所有COUNTRY后代都是从 xml 响应中选择的(无论这些元素位于 xml 中的什么位置)。然后从每个国家元素中选择属性RANK并将该属性转换为可为空的整数。null如果国家没有排名属性或此属性的值,则给出。然后我们从排名属性值中选择第一个或默认值。如果什么也没找到,那么它会给我们一个null. 使用空合并运算符??,我们分配-1而不是null. 如果找到了一些东西,那么可以为空的整数的值将被分配给alexaRank

所以,你不会在这里得到解析异常——如果没有找到国家节点,或者没有国家节点具有等级属性(好吧,只有等级不是整数时)。但是您仍然可以获得其他异常,例如网络不可用时的错误。所以,你可以try catch留在这里。但不要吞下异常!你应该记录它。

您也可以使用 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;
    }
}
于 2013-09-26T15:17:46.653 回答