2017-05-31 33 views
3

我的問題似乎很微不足道,但無法弄清楚如何解析包含由逗號分隔的日期列表的字符串。單個日期的解析部分不是問題,而是空值。麻煩的是日期的順序很重要,有些日期可以省略。預期的具體日期,YYYY-MM-DD進行格式化解析XQuery中的日期數組(MarkLogic v8 flavor)

所以,以下是有效的投入和預期回報值:

,2000-12-12,2012-05-03, ➔ (NULL, 2000-12-12, 2012-05-03, NULL) 
    2000-12-12,,2012-05-03 ➔ (2000-12-12, NULL, 2012-05-03) 

這裏是我的函數簽名

declare function local:assert-date-array-param( 
      $input as xs:string 
     , $accept-nulls as xs:boolean? 
) as xs:date* 

我在意識到這個問題之後,如果你想返回一個序列,那麼在XQuery中返回的值看起來與佔位符的省略日期似乎沒有相同的地方。因爲序列中包含的空序列被夷爲平地。

我想,我的回退將使用日期1900-01-01一樣的佔位符或返回一個地圖,而不是一個序列,但我肯定希望找到一個更優雅的方式

謝謝
K.

PS。我正在與MarkLogic v8(和即將發佈的v9)合作,任何解決方案都應該使用他們的XQuery處理器來執行。

更新:謝謝你的兩個答案,最後我選擇了佔位符日期,因爲XQuery和序列很好地工作,其他任何東西都需要在其他地方進行一些更改。但問題仍然存在於所需返回值爲數字的情況下。在這種情況下,使用佔位符值可能不可行。對於xs:anyAtomicType的null文字將很好地解決了這個問題,但唉。

回答

2

您可以考慮返回json:array()array-node{}null-node{}的內部。但是也許一個空的日期佔位符並不像聽起來那樣糟糕:

declare variable $null-date := xs:date("0001-01-01"); 

declare function local:assert-date-array-param( 
    $input as xs:string, 
    $accept-nulls as xs:boolean? 
) as xs:date* 
{ 
    for $d in fn:tokenize($input, "\s*,\s*") 
    return 
    if ($d eq "") then 
     if ($accept-nulls) then 
     $null-date 
     else 
     fn:error(xs:QName("NULL-NOT-ALLOWED"), "Date is required") 
    else 
     if ($d castable as xs:date) then 
     xs:date($d) 
     else if ($d castable as xs:dateTime) then 
     xs:date(xs:dateTime($d)) 
     else 
     fn:error(xs:QName("INVALID-DATE"), "Invalid date format: " || $d) 
}; 

declare function local:print-date-array($dates) { 
    string-join(for $d in $dates return if ($d eq $null-date) then "NULL" else fn:string($d), ", ") 
}; 

local:print-date-array(
    local:assert-date-array-param(",2000-12-12,2012-05-03,", fn:true()) 
), 
local:print-date-array(
    local:assert-date-array-param("2000-12-12,,2012-05-03", fn:true()) 
) 

HTH!

1

多個選項..除了上面的。

  1. 回報,當調用的返回日期

    for $i in string-tokenize-to-sequence-of-strings() 
    let $dt := my-parse-date($i) 
    return function() { $dt ;} 
    

    return function() { return my-parse-date($i) ; 
    
  2. 回報記號化和驗證,但不會解析字符串的函數序列。用 「」 來 '無效',如:

    ("2014-01-22","","2017-03-30","") 
    
  3. 再有就是陣列,地圖,地圖的陣列,並... XML parseFunction()爲XS:元素()*:

    for ... return <date>{ parse-and-validate($value) } </date> 
    
+0

另一種方法是返回一些原子值序列,其中一些值是xs:date和「nulls」由不是日期的任何東西表示,例如「」或false()。例如'tokenize($ in,',')!(if(。castable as xs:date)then xs:date(。)else false())'。 –