2014-03-28 36 views
0
<?xml version="1.0" encoding="UTF-8"?> 
<library> 
    <books> 
     <book> 
      <title>The Story of my Life </title> 
      <accessionNumber val="1"/> 
     </book> 
     <book> 
      <title>XML Schema </title> 
      <accessionNumber val="2"/> 
     </book> 
     <book> 
      <title>C++ for Image processing</title> 
      <accessionNumber val="3"/> 
     </book> 
    </books> 
    <loans> 
     <loan book="1" user="35" dueDate="25-April-2010"/> 
    </loans> 
    <loans> 
     <loan book="3" user="400" dueDate="05-Jan-2010"/> 
    </loans> 
    <loans> 
     <loan book="2" user="02" dueDate="25-Feb-2010"/> 
    </loans> 
    <users> 
     <user> 
      <name>Fred Jame</name> 
      <id val="35"/> 
     </user> 
     <user> 
      <name>Ashley</name> 
      <id val="400"/> 
     </user> 
     <user> 
      <name>Patrick</name> 
      <id val="02"/> 
     </user> 
    </users> 
</library> 

我的任務是編寫XQuery Expression,列出所有貸款過期的用戶。xquery fn:當前日期()合成

我必須使用fn:current-date()函數dueDate比較,找出所有逾期用戶,但這裏的問題是fn:current-date()格式和XML文檔格式dueDate是完全不同的。

我該如何格式化以獲得我的願望結果?

for $x in doc("library.xml")/library 
where $x/@dueDate > fn:current-date() 
return $x/@name 

我試過以上,但fn:current-date()給人日期輸出2014-03-30Z

但我需要與當前日期進行比較的dueDate如果是的dueDate當前最新以上,則顯示所有用戶。

+0

再次看看我在答案中描述的解決方案草圖。您不能直接比較XML中提供的日期和當前日期。 –

回答

0

由於這顯然是一個練習,我不會提供一個完整的答案,但草圖的解決方案。

  1. XML文檔中使用的日期格式很難進行比較。這可能是合理的創建執行下列步驟的功能(不過這當然也沒有一個來完成):
    • 你將不得不tokenize(...)它,解決一個月的數字並串連它作爲YYYY-mm-dd
    • 現在您可以使用xs:date($string)將其轉換爲日期對象。
  2. 現在遍歷所有<loan/>元素,並篩選它們的到期貸款在那裏where條款,要麼叫你寫的函數或將代碼放在這裏。
  3. 作爲最後一步,您必須將<loan/>對象解析爲相應的用戶。

這應該會幫助您編寫代碼。如果您有任何進一步的具體問題或遇到問題,請隨時發佈後續問題(使用您的嘗試)!


更新:這是我的代碼,使用index-of來查找月份。 resolveDate函數在代碼中被註釋掉,其餘的查詢是微不足道的。

declare function local:resolveDate($date as xs:string) as xs:date { 
    (: Month index, so we can look it up :) 
    let $months := ("Jan", "Feb", "March", "April", "May", "June", "July", "Aug", "Sep", "Oct", "Nov", "Dec") 
    (: Split up the date :) 
    let $date := tokenize($date, '-') 
    (: Resolve the month to its two digit number :) 
    let $month := index-of($months, $date[2]) cast as xs:string 
    let $month := if (string-length($month) < 2) 
       then concat('0', $month) 
       else $month 
    (: Construct an xs:date object from the reordered date :) 
    let $date := string-join(($date[3], $month , $date[1]), '-') 
    return xs:date($date) 
}; 

for $user in //user 
for $loan in //loan[@user=$user/id/@val] 
where local:resolveDate($loan/@dueDate) < current-date() 
return $user 
+0

該函數被稱爲'tokenize',而不是'tokenise'。此外,我會去標記一個破折號,而不是空格:'標記大小(「2010年4月25日」,' - ')'。 –

+0

我想使用tokenize()將dueDate分解爲數字,但錯誤。 – Arshad

+0

請閱讀如何發佈[SSCCE](http://www.sscce.org),所以有人可以真正回答你的問題。由於你的問題是一個新的,單獨的問題,最好是實際發佈一個,而不是評論。 –

0

您可以創建類似的功能:

declare function local:xml_month 

($monthId as xs:string) as xs:string 
{ 
if (tokenize($monthId,"-")[2] = 'January') 
then 
concat( tokenize($monthId,"-")[1],"-", 
replace(tokenize($monthId,"-")[2],'January','01'),"-", 
tokenize($monthId,"-")[3]) 
else if (tokenize($monthId,"-")[2] = 'February') 
then 
concat( tokenize($monthId,"-")[1],"-", 
replace(tokenize($monthId,"-")[2],'February','02'),"-", 
tokenize($monthId,"-")[3]) 
else if (tokenize($monthId,"-")[2] = 'March') 
then 
concat( tokenize($monthId,"-")[1],"-", 
replace(tokenize($monthId,"-")[2],'March','03'),"-", 
tokenize($monthId,"-")[3]) 
else if (tokenize($monthId,"-")[2] = 'April') 
then 
concat( tokenize($monthId,"-")[1],"-", 
replace(tokenize($monthId,"-")[2],'April','04'),"-", 
tokenize($monthId,"-")[3]) 
else if (tokenize($monthId,"-")[2] = 'May') 
then 
concat( tokenize($monthId,"-")[1],"-", 
replace(tokenize($monthId,"-")[2],'May','05'),"-", 
tokenize($monthId,"-")[3]) 
else if (tokenize($monthId,"-")[2] = 'June') 
then 
concat( tokenize($monthId,"-")[1],"-", 
replace(tokenize($monthId,"-")[2],'June','06'),"-", 
tokenize($monthId,"-")[3]) 
else if (tokenize($monthId,"-")[2] = 'July') 
then 
concat( tokenize($monthId,"-")[1],"-", 
replace(tokenize($monthId,"-")[2],'July','07'),"-", 
tokenize($monthId,"-")[3]) 
else if (tokenize($monthId,"-")[2] = 'August') 
then 
concat( tokenize($monthId,"-")[1],"-", 
replace(tokenize($monthId,"-")[2],'August','08'),"-", 
tokenize($monthId,"-")[3]) 
else if (tokenize($monthId,"-")[2] = 'September') 
then 
concat( tokenize($monthId,"-")[1],"-", 
replace(tokenize($monthId,"-")[2],'Sempter','09'),"-", 
tokenize($monthId,"-")[3]) 
else if (tokenize($monthId,"-")[2] = 'October') 
then 
concat( tokenize($monthId,"-")[1],"-", 
replace(tokenize($monthId,"-")[2],'October','10'),"-", 
tokenize($monthId,"-")[3]) 
else if (tokenize($monthId,"-")[2] = 'November') 
then 
concat( tokenize($monthId,"-")[1],"-", 
replace(tokenize($monthId,"-")[2],'November','11'),"-", 
tokenize($monthId,"-")[3]) 
else if (tokenize($monthId,"-")[2] = 'December') 
then 
concat( tokenize($monthId,"-")[1],"-", 
replace(tokenize($monthId,"-")[2],'December','12'),"-", 
tokenize($monthId,"-")[3])  
else "NA" 
}; 

for $u in doc("ques2010.xml")//user 
for $l in doc("ques2010.xml")//loan  
where fn:current-date() > xs:date(local:xml_month($l/data(@dueDate))) 
and $u/id/@val = $l/@user 
return $u/name 

它應該爲你工作。

+0

我想知道我可以使功能更短! – Nusrat

+0

你可以做,與我在顯示自己的努力後添加的代碼版本進行比較。 –