Группировка в Linq в не очень хорошо организованном XML - PullRequest
0 голосов
/ 13 декабря 2011

Я использую YQL для получения некоторых данных, и вот мой xml:

<?xml version="1.0" encoding="UTF-8"?>
<div id="content>
<div id="html">
<h3>City</h3>
<div id="movie">
    <h4>
        <a href="">movie 1</a>
    </h4>
<div>
<div id="movie>
    <h4>
        <a href="">movie 2</a>
    </h4>
</div>
    .
    .
    .

<h3>City 2</h3>
<div id="movie">
    <h4>
        <a href="">movie 1</a>
    </h4>
<div>
<div id="movie>
    <h4>
        <a href="">movie 2</a>
    </h4>
</div>

Я хочу заполнить список в моем приложении для Windows Phone названием города и его фильмами, например:this:

City 1
Movie1
Movie 2

City 2
Movie1
Movie 2

Однако я застреваю здесь, поскольку весь XML находится внутри div с содержимым идентификатора.

Как мог бы оператор LINQ решить эту проблему?

1 Ответ

1 голос
/ 13 декабря 2011

Я попытался преобразовать ваш опубликованный ввод в какой-то правильно сформированный XML:

<div id="content">
  <div id="html">
    <h3>City</h3>
    <div id="movie">
      <h4>
        <a href="">movie 1</a>
      </h4>
    </div>
    <div id="movie">
      <h4>
        <a href="">movie 2</a>
      </h4>
    </div>
    .
    .
    .

    <h3>City 2</h3>
    <div id="movie">
      <h4>
        <a href="">movie 1</a>
      </h4>
    </div>
    <div id="movie">
      <h4>
        <a href="">movie 2</a>
      </h4>
    </div>
  </div>
</div>

Затем вы можете получить список с кодом

    XDocument doc = XDocument.Load("input.xml");
    List<string> data =
        doc.Descendants("h3")
        .Union(
          doc.Descendants("div")
          .Where(d => (string)d.Attribute("id") == "movie")
          .Elements("h4")
          .Elements("a")
          ).InDocumentOrder()
        .Select(e => e.Value)
        .ToList();

[править] Ваш первоначальный запросПохоже, вы просили получить единый список результатов, ваш комментарий предполагает, что вы предпочитаете сгруппированную структуру, так что вот адаптированный пример:

    XDocument doc = XDocument.Load("input.xml");
    var groupedData =
        (from movie in doc.Root.Descendants("div")
         where (string)movie.Attribute("id") == "movie"
         group movie by movie.ElementsBeforeSelf("h3").Last() into g
         select new
         {
             city = g.Key.Value,
             movies = (from m in g
                       select (string)m.Element("h4").Element("a")).ToList()
         }).ToList();

    // now use above list for data binding or 
    // in the simplest case just consume it with foreach:
    foreach (var group in groupedData)
    {
        Console.WriteLine("city: {0}:", group.city);
        foreach (var movie in group.movies)
        {
            Console.WriteLine(movie);
        }
    }
...