LINQ to XML множественный выбор - PullRequest
0 голосов
/ 18 марта 2011

Редактировать : Вот пример XML-документа, который я пытаюсь проанализировать: http://us.battle.net/wow/en/forum/1011699/ (просмотреть исходный код).

Вот элементы, которые я пытаюсь получить:

  • Заголовок (tbody / tr / td / a)
  • Автор (tbody / tr / td)
  • Url (также хранится в узле автора)
  • Дата (tbody / tr / td / div / div)
  • Ответы (tbody / tr / td)
  • Просмотры (также хранятся в вышеуказанном узле)

Я делаю «предварительный запрос», поэтому мне не нужно проходить как можно дальше для каждого следующего запроса:

var threads =
    from allThreads in xmlThreadList.Descendants(ns + "tbody")
                                    .Descendants(ns + "tr")
                                    .Descendants(ns + "td")
    select allThreads;

У меня есть документ XML, представляющий список тем форума,В каждом потоке есть разные дочерние элементы, которые содержат разную информацию, которую я хотел бы получить.В настоящее время я делаю это, запрашивая документ XML несколько раз.Есть ли способ извлечь эту информацию в одном запросе и сохранить ее в IEnumerable?То, как я делаю это сейчас, кажется неэффективным.

    // array of xelements that contain the title and url
    var threadTitles =
        (from allThreads in threads.Descendants(ns + "a")
        where allThreads.Parent.Attribute("class").Value.Equals("post-title")
        select allThreads).ToArray();

    // array of strings of author names
    var threadAuthors =
        (from allThreads in threads
        where allThreads.Attribute("class").Value.Equals("post-author")
        select allThreads.Value.Trim()).ToArray();

    // ...
    // there are several more queries like this
    // ...

    // for loop to populate a list with all the extracted data
    for (int i = 0, j = 0; i < threadTitles.Length; i++, j++)
    {
        ThreadItem threadItem = new ThreadItem();

        threadItem.Title = threadTitles[i].Value.Trim();
        threadItem.Author = threadAuthors[i];
        threadItem.Url = Path.Combine(_url, threadTitles[i].Attribute("href").Value);
        threadItem.Date = threadDates[i];
        threadItem.Replies = threadRepliesAndViews[j++];
        threadItem.Views = threadRepliesAndViews[j];
        _threads.Add(threadItem);
    }

Любой совет будет оценен.Я новичок на всей сцене LINQ to XML.

Ответы [ 2 ]

2 голосов
/ 18 марта 2011

Надеюсь, это поможет:

string ns = "{http://www.w3.org/1999/xhtml}";

var doc = XDocument.Load("http://us.battle.net/wow/en/forum/1011699/");
var threads = from tr in doc.Descendants(ns + "tbody").Elements(ns + "tr")
              let elements = tr.Elements(ns + "td")
              let title = elements.First(a => a.Attribute("class").Value == "post-title").Element(ns + "a")
              let author = elements.First(a => a.Attribute("class").Value == "post-author")
              let replies = elements.First(a => a.Attribute("class").Value == "post-replies")
              let views = elements.First(a => a.Attribute("class").Value == "post-views")
              select new
              {
                  Title = title.Value.Trim(),
                  Url = title.Attribute("href").Value.Trim(),
                  Author = author.Value.Trim(),
                  Replies = int.Parse(replies.Value),
                  Views = int.Parse(views.Value)
              };

foreach (var item in threads)
{
    Console.WriteLine(item);
}

Console.ReadLine();
1 голос
/ 18 марта 2011

попробуйте что-то вроде

from thread in threads
select new ThreadItem() {
   Title = thread.Descendants(ns + "a").First( title => title.Parent.Attribute("class").Value.Equals("post-title")),
  Date = date query part

  ect.... 
}

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

Мне было бы интересно узнать, что получается быстрее, поскольку вы эффективно торгуете, надеясь, что весь элемент помещается в кэш и, таким образом, дает вам быстрый доступ к нему, когда вы выполняете все небольшие запросы к нему.с надеждой (в вашем старом коде) на то, что предиктор веток в вашем процессоре будет настроен на выполнение каждого длинного запроса, обеспечивая лучшую скорость.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...