2013-07-27 2 views
1

Прежде всего, да, это домашнее задание - пожалуйста, предложите, где я ошибаюсь, но, пожалуйста, не делайте домашнее задание для меня.Как я могу найти продолжительность песни, когда ее ID с помощью XQuery?

Я учу XQuery, и одна из моих задач - взять список идентификаторов песен для производительности и определить общую продолжительность исполнения. Учитывая приведенные ниже фрагменты, может ли кто-нибудь указать мне, где я могу определить, как перекрестно ссылаться на songID от исполнения до продолжительности песни?

Я перечислил свои попытки в конце вопроса.

мой текущий код XQuery выглядит следующим образом:

let $songIDs := doc("C:/Users/rob/Downloads/A4_FLOWR.xml") 
        //SongSet/Song 
    for $performance in doc("C:/Users/rob/Downloads/A4_FLOWR.xml") 
         //ContestantSet/Contestant/Performance 
     return if($performance/SongRef[. =$songIDs/@SongID]) 
     then <performanceDuration>{ 
      data($performance/SongRef) 
      }</performanceDuration> 
     else() 

Какие выходы:

<performanceDuration>S005 S003 S004</performanceDuration> 
    <performanceDuration>S001 S007 S002</performanceDuration> 
    <performanceDuration>S008 S009 S006</performanceDuration> 
    <performanceDuration>S002 S004 S007</performanceDuration> 

Каждый S00x это идентификатор песни, которые мы нашли в указанной XML-документа (частичный документ):

<SongSet> 
    <Song SongID="S001"> 
     <Title>Bah Bah Black Sheep</Title> 
     <Composer>Mother Goose</Composer> 
     <Duration>2.99</Duration> 
    </Song>  
    <Song SongID="S005"> 
     <Title>Thank You Baby</Title> 
     <Composer>Shania Twain</Composer> 
     <Duration>3.02</Duration> 
    </Song> 
    </SongSet> 

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

<Contestant Name="Fletcher Gee" Hometown="Toronto"> 
    <Repertoire> 
     <SongRef>S001</SongRef> 
     <SongRef>S002</SongRef> 
     <SongRef>S007</SongRef> 
     <SongRef>S010</SongRef> 
    </Repertoire> 
    <Performance> 
     <SongRef>S001</SongRef> 
     <SongRef>S007</SongRef> 
     <SongRef>S002</SongRef> 
    </Performance> 
    </Contestant> 

Мои попытки

Я думал, что я хотел бы использовать вложенные циклы, но это не удается:

let $songs := doc("C:/Users/rob/Downloads/A4_FLOWR.xml") 
       //SongSet/Song 
    for $performance in doc("C:/Users/rob/Downloads/A4_FLOWR.xml") 
         //ContestantSet/Contestant/Performance 
    return if($performance/SongRef[. =$songs/@SongID]) 
    for $song in $songIDs 
      (: gives an error in BaseX about incomplete if :) 
    then <performanceDuration>{ 
      data($performance/SongRef) 
     }</performanceDuration> 
    else() 

--Edit--

Я установил внутренний цикл, однако я получаю все длительности песен, а не только те, которые соответствуют идентификаторам. У меня есть ощущение, что это связанно с переменным объемом, но я не уверен:

let $songs := doc("C:/Users/rob/Downloads/A4_FLOWR.xml")//SongSet/Song 
    for $performance in doc("C:/Users/rob/Downloads/A4_FLOWR.xml")//ContestantSet/Contestant/Performance 
    return if($performance/SongRef[. =$songs/@SongID]) 

    then <performanceDuration>{ 
    for $song in $songs 
    return if($performance/SongRef[. =$songs/@SongID]) 
    then  
     sum($song/Duration) 
    else() 
    }</performanceDuration> 
    else() 

} 

Выход:

<performanceDuration>2.99 1.15 3.15 2.2 3.02 2.25 3.45 1.29 2.33 3.1</performanceDuration> 

ответ

1

Вашей ближайшая задача синтаксическая: вы вставили свою внутреннюю петлю между условие и ключевое слово 'then' в условном выражении. Fix, что первая:

return if ($performance/SongRef = $songs/@SongID) then 
      <performanceDuration>{ 
      (: put your inner loop HERE :) 
      }</performanceDuration> 
else() 

Теперь подумаем себя в ситуации оценивающего запроса внутри элемента performanceDuration. У вас есть переменная $ performance, вы можете найти все ссылки на песни, используя $ performance/SongRef, и для каждой ссылки на песню в элементе производительности вы можете найти соответствующий элемент песни, сопоставив значение SongRef с $ songs/@ SongID.

Мой следующий шаг в этом месте было бы спросить себя:

  • Для данной ссылки песни, как мне найти элемент песни для этой песни, а затем продолжительность для этой песни?
  • Есть ли способ получить сумму некоторого набора длительностей? Есть, например, функция sum()? (Я уверен, что есть, но в этот момент я всегда подтягиваю спецификацию функций и операторов и просматриваю ее, чтобы быть уверенным в сигнатуре.)
  • Какой тип информации о длительности?Я ожидаю, что это будет минуты и секунды, и я буду беспокоиться о продолжительности арифметики, но ваш образец делает его похожим на десятичные числа, что будет легко.
Смежные вопросы