Преобразуйте версию Linq до нормальной версии C # .NET 2.0 для кодов анализатора имен доменов, которые используют publicsuffix.org. - PullRequest
2 голосов
/ 09 октября 2009

Основываясь на этом ответе Получите поддомен с URL , я пытаюсь использовать code.google.com/p/domainname-parser/, который будет использовать Public Suffix List из publicsuffix.org для получения поддоменов. и домен для управления моей коллекцией файлов cookie.

В настоящий момент, Domainname-parser - единственный код .NET, который я нашел в интернете, который реализует список из publicsuffix.org.

Чтобы использовать Domainname-parser, я хочу внести изменения в исходный код, чтобы он мог:

  1. Использовать в .NET 2.0
  2. Примите объект Uri для разбора хоста на поддомен, домен и TLD.
  3. Будет автоматически загружать последний список с publicsuffix.org с помощью WebRequest и WebResponse, если LastModified изменен.

Так он станет более удобным и всегда обновляется. (2) и (3) не будет проблемой, но (1) сейчас я в фокусе.

Текущий Domainname-parser v1.0, сборка для использования .NET 3.5, которая использует Linq в коде. Чтобы сделать его совместимым с .NET 2.0, мне нужно преобразовать коды Linq в не-Linq, и это заставляет меня понимать правила Public Suffix List. Это правило Normal, Wildcard и Exception. Однако у меня нет знаний о Linq и о том, как его можно преобразовать обратно обычным способом.

Инструменты конвертера могут быть полезны, но лучше я пересматриваю и изменяю их построчно.

Теперь мой вопрос: как я могу его конвертировать? Например, коды из метода FindMatchingTLDRule в классе DomainNames:

//  Try to match an wildcard rule:
var wildcardresults = from test in TLDRulesCache.Instance.TLDRuleList
                      where
                        test.Name.Equals(checkAgainst, StringComparison.InvariantCultureIgnoreCase)
                        &&
                        test.Type == TLDRule.RuleType.Wildcard
                      select
                        test;

, а также это:

        var results = from match in ruleMatches
                      orderby match.Name.Length descending
                      select match;

Какой простой руководящей линии следовать? или любые бесплатные инструменты для преобразования этого предложения выше в обычные коды C # в .NET 2.0 .?

Я считаю, что база данных не задействована, просто в том, как они работают с коллекциями.

Я также пытаюсь связаться с владельцем доменного имени-парсера, чтобы улучшить коды и помочь мне решить эту проблему.

Спасибо

CallMeLaNN

Ответы [ 2 ]

1 голос
/ 09 октября 2009

Спасибо Джону Скиту, который действительно помогает мне. Он работает очень хорошо, и все UnitTest успешно пройдены.

Здесь я хочу поделиться ответом всем, кто хочет использовать Domainname-parser в .NET 2.0

1 Изменить эти коды (DomainName.cs)

            //  Try to match an exception rule:
            var exceptionresults = from test in TLDRulesCache.Instance.TLDRuleList
                                   where
                                     test.Name.Equals(checkAgainst, StringComparison.InvariantCultureIgnoreCase)
                                     &&
                                     test.Type == TLDRule.RuleType.Exception
                                   select
                                     test;

            //  Try to match an wildcard rule:
            var wildcardresults = from test in TLDRulesCache.Instance.TLDRuleList
                                  where
                                    test.Name.Equals(checkAgainst, StringComparison.InvariantCultureIgnoreCase)
                                    &&
                                    test.Type == TLDRule.RuleType.Wildcard
                                  select
                                    test;

            //  Try to match a normal rule:
            var normalresults = from test in TLDRulesCache.Instance.TLDRuleList
                                where
                                  test.Name.Equals(checkAgainst, StringComparison.InvariantCultureIgnoreCase)
                                  &&
                                  test.Type == TLDRule.RuleType.Normal
                                select
                                  test;

в это:

List<TLDRule> exceptionresults = MatchRule(TLDRulesCache.Instance.TLDRuleList, checkAgainst, TLDRule.RuleType.Exception);
List<TLDRule> wildcardresults = MatchRule(TLDRulesCache.Instance.TLDRuleList, checkAgainst, TLDRule.RuleType.Wildcard);
List<TLDRule> normalresults = MatchRule(TLDRulesCache.Instance.TLDRuleList, checkAgainst, TLDRule.RuleType.Normal);

    private static List<TLDRule> MatchRule(List<TLDRule> rules, string checkAgainst, TLDRule.RuleType ruleType)
    {
        List<TLDRule> matchedResult = new List<TLDRule>();
        foreach (TLDRule rule in rules)
        {
            if (rule.Name.Equals(checkAgainst, StringComparison.InvariantCultureIgnoreCase)
                && rule.Type == ruleType)
            {
                matchedResult.Add(rule);
            }
        }
        return matchedResult;
    }

2 Изменить это:

        //  Sort our matches list (longest rule wins, according to :
        var results = from match in ruleMatches
                      orderby match.Name.Length descending
                      select match;

        //  Take the top result (our primary match):
        TLDRule primaryMatch = results.Take(1).SingleOrDefault();

в это

        TLDRule primaryMatch = null;
        if (ruleMatches.Count > 0)
        {
            // match2 CompareTo match1 (reverse order) to make the descending
            ruleMatches.Sort(delegate(TLDRule match1, TLDRule match2) { return match2.Name.Length.CompareTo(match1.Name.Length); });
            primaryMatch = ruleMatches[0];
        }

3 изменить это (TLDRulesCache.cs)

            IEnumerable<TLDRule> lstTLDRules = from ruleString in lstTLDRuleStrings
                                               where
                                               !ruleString.StartsWith("//", StringComparison.InvariantCultureIgnoreCase)
                                               &&
                                               !(ruleString.Trim().Length == 0)
                                               select new TLDRule(ruleString);

в это

List<TLDRule> lstTLDRules = ListTLDRule(lstTLDRuleStrings);

    private static List<TLDRule> ListTLDRule(List<string> lstTLDRuleStrings)
    {
        List<TLDRule> lstTLDRule = new List<TLDRule>();
        foreach (string ruleString in lstTLDRuleStrings)
        {
            if (!ruleString.StartsWith("//", StringComparison.InvariantCultureIgnoreCase)
                &&
                !(ruleString.Trim().Length == 0))
            {
                lstTLDRule.Add(new TLDRule(ruleString));
            }
        }
        return lstTLDRule;
    }

Некоторые другие мелочи, такие как:

List<string> lstDomainParts = domainString.Split('.').ToList<string>();

изменить на:

List<string> lstDomainParts = new List<string>(domainString.Split('.'));

и удаление .ToList () как в

"var exceptionresults" будет использовать exceptionresults.ToList (), чтобы получить список. Поскольку «var exceptionresults» изменяется на «Список исключений», необходимо удалить ToList ().

CallMeLaNN

1 голос
/ 09 октября 2009

Хорошо, в ответ на комментарии, вот версия, возвращающая список.

public List<TLDRule> MatchWildcards(IEnumerable<TLDRule> rules,
                                    string checkAgainst)
{
    List<TLDRule> ret = new List<TLDRule>();
    foreach (TLDRule rule in rules)
    {
        if (rule.Name.Equals(checkAgainst, 
                             StringComparison.InvariantCultureIgnoreCase)
            && rule.Type == TLDRule.RuleType.Wildcard)
        {
            ret.Add(rule);
        }
    }
    return ret;
}

Then:

List<TLDRule> wildcardresults = MatchWildcards(
    TLDRulesCache.Instance.TLDRuleList, checkAgainst);

Однако, если вы конвертируете много кода (и если у вас действительно есть для его преобразования - см. Ниже), вам действительно нужно больше узнать о LINQ. В конце концов, вы наверняка будете использовать его, и если вы поймете, как это работает, вы будете в гораздо лучшем положении, чтобы понять, как выполнить преобразование. Самые последние книги по C # охватывают LINQ; если у вас есть моя собственная книга (C # in Depth), главы 8-11 будут охватывать все, что вам нужно знать для LINQ to Objects.

Другая альтернатива, если вы можете использовать VS2008, но просто target .NET 2.0 - это использовать LINQBridge , который является переопределением LINQ to Objects для .NET 2.0 ... и теперь с открытым исходным кодом :)

...