它在 Alexa XML 文件中有 2 个元素 <COUNTRY>

问题描述 投票:0回答:1

像往常一样,我使用下面的代码来获取 Alexa 越南排名,越南排名位于元素中:

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

但在这种情况下,它有两个要素: 越南排名在第二个元素,我怎样才能得到它?

c# xml linq-to-xml alexa-internet
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;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.