2017-01-20 5 views
0

В моем файле XQuery 1.0 у меня есть строка как входная с тем же форматом, что и элемент xsd: duration: PnYnMnDTnHnMnS. Где P является обязательным, n - число Y (уши), M (onths) и т. Д., А T - разделитель H (наш), M (inutes) и т. Д.Как объявить цикл XQuery 1.0 while для генерации строки, добавляя символы

Мои входные данные как строка и может быть неполной, я имею в виду, что поле year, month ... minutes не может появиться. Тогда мой вывод должен быть полным элементом продолжительности, когда недостающие поля должны быть заполнены 0.

Пример:

P1YT1H2M50S ---> P1Y0M0DT1H2M50S

Моя проблема в том, что я не знаю синтаксис правильно написать время цикла с локальными переменными.

Примечание: ЭТОТ КОД НЕ СОСТАВЛЯЕТСЯ. Это просто PSEUDOCODE

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

<typ:validityPeriod> 
       { 
       let $input := 'P1YT1H2M50S' 
       let $index := 2 
       let $result := 'P' 
       let $Y_read := false 
       let $Months_read := false 
       let $D_read := false 
       let $T_read := false 
       let $H_read := false 
       let $Minutes_read := false 
       let $S_read := false 
       let $acu := '' 

       while (not($S_read)){ 
        let $char := xs:substring($input, $index,$index) 

        if ($char = 'Y') then 
         $Y_read := true 
         $result := fn:concat($result, $acu, 'Y') 
         $acu := ''      
        else if ($char = 'M') then       
         if (not($T_read)) then 
          $Months_read := true 
          if ($Y_read) then 
           $result := fn:concat($result, $acu, 'M') 
          else 
           $result := fn:concat($result, '0Y', $acu, 'M') 
         else 
          $Minutes_read := true 
          if (not($H_read)) then 
           $result := fn:concat($result, 'T0H') 

          $result := fn:concat($result, $acu, 'M') 
         $acu := ''      
        else if ($char = 'D') 
         $D_read := true      
         if (not($Y_read)) then 
           $result := fn:concat($result, '0Y') 
         if (not($Months_read)) then 
           $result := fn:concat($result, '0M') 
         $result := fn:concat($result, $acu, 'D') 
         $acu := ''      
        else if ($char = 'T') then 
         $acu := ''      
         if (not($Y_read)) then 
          $result := fn:concat($result, '0Y') 
         if (not($Months_read)) then 
          $result := fn:concat($result, '0M') 
         if (not($D_read)) then 
          $result := fn:concat($result, '0D') 
         $T_read = true 
         $acu := ''      
        else if ($char = 'H') 
         $H_read := true 
         $acu := '' 
         <the same logic> 
        else if ($char = 'S') 
         <the same logic> 
         $S_read := true 
        else 
         $acu := fn:concat($acu, $char) 

        $index := $index + 1 
       } 

       return xs:duration($result) 


       } 
     </typ:validityPeriod> 
+2

XQuery не имеет 'while' заявление. Не изменяемые переменные. Вам нужно будет написать отдельный оператор let для каждой буквы или рекурсивную функцию. Однако, что вы на самом деле хотите сделать? Длительности работают отлично с отсутствующими буквами. 'xs: duration (" P1YT1H2M50S ")' возвращает продолжительность. Такая же продолжительность. 'xs: duration (" P1Y0M0DT1H2M50S ") = xs: duration (" P1YT1H2M50S ")' вы не можете рассказать им обособленно – BeniBela

+0

Спецификация выхода говорит, что вывод должен отображать все буквы. Но я нашел лучший способ использования регулярных выражений. (([0-9] +) M)? (([0-9] +) D)? (T (([0-9] +) H)? (([0-9] +) M)? (([0-9] +) S)?)? "," P $ 2Y $ 4M $ 6DT $ 9H $ 11 ([A-Za-z]) ([A-SU-Za-su-z]) "," $ 10 $ 2 ")," ([A-Za-z]) ([A -SU-Za-su-z]) "," $ 10 $ 2 ") – ycesar

+1

Вы записали его как очень процедурный псевдокод. Нелегко переделать процедурный код на декларативный код; вам действительно нужно попробовать и подумать более декларативно. –

ответ

1

Я думаю, что это должно дать правильный ответ:

let $d := xs:duration('P1YT1H2M50S') 
return concat('P', 
    years-from-duration($d), 'Y', 
    months-from-duration($d), 'M', 
    days-from-duration($d), 'D', 
    'T', 
    hours-from-duration($d), 'H', 
    minutes-from-duration($d), 'M', 
    seconds-from-duration($d), 'S') 
Смежные вопросы