Кроме перебора всех событий и проверки его StartTime
теоретически есть решение XPath, использующее оператор >=
с xs:time
типами, подобными этому:
/SchoolCalendar/CalendarEvent[xs:time(concat(StartTime, ':00')) >= xs:time('14:00:00')]
Демоверсия
Однако для этого требуется XPath 2+, а с PHP у вас есть доступ только к XPath 1.0 (с некоторыми расширениями XPath 2).
Тем не менее, это может быть сделано в XPath с использованием PHP 5 DOMXPath::registerPhpFunctions
.
Пример кода:
$doc = new DOMDocument;
$doc->loadXML($xml); //from string
$xpath = new DOMXPath($doc);
// Register the php: namespace (required)
$xpath->registerNamespace("php", "http://php.net/xpath");
// Register PHP functions (time_greater_thanonly)
$xpath->registerPHPFunctions("time_greater_than");
function time_greater_than($nodes)
{
// Return true if time is greater or equal than now
return strtotime($nodes[0]->nodeValue) >= strtotime(date("H:i"));
}
// Call custom function on the CalendarEvent nodes instead of XQuery 2+ functions
$query = $xpath->query('/SchoolCalendar/CalendarEvent[php:function("time_greater_than", StartTime)]');
if ($query) {
foreach ($query as $node) {
echo "<tr>";
$values = explode("\n", trim($node->nodeValue));
foreach ($values as $str)
echo "<td>$str</td>";
echo "</tr>";
}
}
PS: для доступа к выводу time_greater_than
я просто использую explode()
, чтобы получить значения из текстового содержимого текущего узла. Чтобы углубиться в узел в цикле foreach
, используйте xquery с текущим $node
как contextnode param:
$xpath->query(".//Location", $node)[0]->nodeValue
, например
if ($query) {
foreach ($query as $node) {
echo "<tr>";
echo "<td>".$xpath->query('.//StartTime', $node)[0]->nodeValue."</td>";
echo "<td>".$xpath->query('.//Title', $node)[0]->nodeValue."</td>";
echo "<td>".$xpath->query('.//Location', $node)[0]->nodeValue."</td>";
echo "</tr>";
}
}
PPS: Никогда версии XQuery также не имеют fn:current-time()
. Мне пришлось использовать фиксированный xs:time
, чтобы заставить его работать.