2014-01-11 3 views
2

Я хочу сгруппировать все фильмы по жанрам, а затем перечислить все названия фильмов в этом жанре.Xquery FLWOR с группой

Моя база данных фильмов XML выглядит следующим образом:

<movies> 
    <movie> 
    <title>A History of Violence</title> 
    <year>2005</year> 
    <country>USA</country> 
    <genre>Crime</genre> 
    <summary>Tom Stall, a humble family man and owner of a 
    popular neighborhood restaurant, lives a quiet but 
    fulfilling existence in the Midwest. One night Tom 
    foils a crime at his place of business and, to his 
    chagrin, is plastered all over the news for his 
    heroics. Following this, mysterious people follow 
    the Stalls' every move, concerning Tom more than 
    anyone else. As this situation is confronted, more 
    lurks out over where all these occurrences have 
    stemmed from compromising his marriage, family 
    relationship and the main characters' former 
    relations in the process.</summary> 
<director>  
     <last_name>Cronenberg</last_name> 
     <first_name>David</first_name> 
     <birth_date>1943</birth_date> 
</director> 
<actor> 
     <first_name>Vigo</first_name> 
     <last_name>Mortensen</last_name> 
     <birth_date>1958</birth_date> 
     <role>Tom Stall</role> 
</actor> 
<actor> 
     <first_name>Maria</first_name> 
     <last_name>Bello</last_name> 
     <birth_date>1967</birth_date> 
     <role>Eddie Stall</role> 
</actor> 
<actor> 
     <first_name>Ed</first_name> 
     <last_name>Harris</last_name> 
     <birth_date>1950</birth_date> 
     <role>Carl Fogarty</role> 
</actor> 
<actor> 
     <first_name>William</first_name> 
     <last_name>Hurt</last_name> 
     <birth_date>1950</birth_date> 
     <role>Richie Cusack</role> 
</actor> 
</movie> 

вот мое выражение:

xquery version "3.0";

let $movie := collection ('/db/Movie/data')/movies/movie 

return 

<html> 
<head> 

    </head> 
    <body> 
     <h1>Movies grouped by genre:</h1> 

     <ol>{ 
       for $m in $movie 
       let $g := $m/genre 
       let $t := distinct-values($m/title/text()) 
       group by $g 
    return 
       <li>{$g} <p> <ol>Title: {$t}</ol> </p></li> 



     }</ol> 
    </body> 
</html> 

но результат даст мне все названия в одном ряду, но я хочу они также также перечислили точки списка.

Это фактический выход:

<li> 
<genre>Crime</genre> 
<p> 
<ol>Title: A History of Violence Heat Match Point</ol> 
</p> 
</li> 
<li> 

Должно выглядеть так:

<li> 
<genre>Crime</genre> 
<p> 
<ol>Title: A History of Violence 
      Heat 
      Match Point 
</ol> 
</p> 
</li> 
<li> 

Как мне нужно настроить запрос?

Заранее спасибо. Greets

+2

Пожалуйста, всегда указывайте пример ввода, если ваш код потребляет некоторые. Очень хорошие вопросы также дают реальный и ожидаемый результат для дальнейшего уточнения проблемы. –

+0

Спасибо за внимание. Я отредактировал вопрос и надеюсь, что он это разъяснил. – user3181473

+0

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

ответ

2

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

xquery version "3.0"; 

let $movies := collection ('/db/Movie/data')/movies/movie 
return 
    <html> 
    <head></head> 
    <body> 
     <h1>Movies grouped by genre:</h1> 
     <ol>{ 
     for $movie in $movies 
     let $genre := $movie/genre 
     group by $genre 
     let $titles := distinct-values($movie/title/data()) 
     return 
      <li> 
      <h2>{$genre} Titles</h2> 
      <ol>{ 
       for $title in $titles 
       return <li>{$title}</li> 
      }</ol> 
      </li> 
     }</ol> 
    </body> 
    </html> 

Вы можете использовать неявный цикл, используя конструктор элемента, как шаг оси, но это потребовало бы, чтобы удалить distinct-values вызов (вы действительно это нужно?) Я просто повторил $movie цикл:

for $movie in $movies 
let $genre := $movie/genre 
group by $genre 
return 
    <li> 
    <h2>{$genre} Titles</h2> 
    <ol>{ $movie/title/element li { data() } }</ol> 
    </li> 

Кстати, HTML не разрешает списки внутри абзацев. Это хорошо сформированный XML в любом случае, но не действительный HTML. Я тоже это исправил.

+0

Перфект, большое спасибо! – user3181473

Смежные вопросы