2013-06-04 3 views
0

Как найти контакты с предстоящими днями рождения, скажем, в течение 10 дней, учитывая следующий XML?XPath - найти ближайшие дни рождения

<contacts> 
    <contact> 
    <name>bob</name> 
    <birthday>1978-05-06</birthday> 
    </contact> 
    <contact> 
    <name>mary</name> 
    <birthday>1955-06-06</birthday> 
    </contact> 
    <contact> 
    <name>john</name> 
    <birthday>1998-05-06</birthday> 
    </contact> 
</contacts> 

У меня есть следующий XPath, но она ломается, потому что месяц из-DATETIME возвращает целое число (5) вместо проложенной строки «0» (05). Есть ли способ построить дату в Xpath, которая будет принимать целочисленный параметр для дня, месяца, года вместо моих строк unqly hack concatenating?

/contacts/contact[days-from-duration(xs:dateTime(concat(year-from-dateTime(current-date()),'-',month-from-dateTime(xs:dateTime(birthday)),'-',day-from-dateTime(xs:dateTime(birthday)))) - current-date()) < 10] 
+0

Следующие обрабатывают левые отступы, но должен быть лучше: '/ контакты/контакты/хз: DATETIME (CONCAT (год из-DATETIME (по току даты(), '-', substring (concat ('00 ', month-to-dateTime (xs: dateTime (день рождения))), длина строки (месяц-от-dateTime (xs: dateTime (день рождения))) + 1, 2), '-', substring (concat ('00 ', day-to-dateTime (xs: dateTime (день рождения))), длина строки (day-to-dateTime (xs: dateTime (день рождения))) + 1, 2))) ' – GGGforce

ответ

1

Вы можете использовать yearMonthDuration добавить достаточно так лет, чтобы переместить дату в текущем году:

/contacts/contact[ 
    xs:dateTime(birthday) + xs:yearMonthDuration("P1Y") * (year-from-dateTime(current-date()) - year-from-dateTime(xs:dateTime(birthday))) < current-date() + xs:dayTimeDuration("P10D") 
] 

И проверить, что день рождения не в прошлом (для работ, как пусть не вводить все это здесь дважды):

/contacts/contact[ 
    for $thisYearBirthDay in xs:dateTime(birthday) + xs:yearMonthDuration("P1Y") * (year-from-dateTime(current-date()) - year-from-dateTime(xs:dateTime(birthday))) 
    return $thisYearBirthDay >= current-date() and $thisYearBirthDay < current-date() + xs:dayTimeDuration("P10D") 
] 

Однако, на самом деле заставить его работать, вы должны проверить текущий и следующий год, в случае Прев лор дата вокруг Рождества, например:

/contacts/contact[ 
    exists((for $delta in (0, 1) return xs:dateTime(birthday) + xs:yearMonthDuration("P1Y") * ($delta + year-from-dateTime(current-date()) - year-from-dateTime(xs:dateTime(birthday))))[. >= current-date() and . < current-date() + xs:dayTimeDuration("P10D")]) 
] 
Смежные вопросы