PHP 使用查询显示来自 xml 的数据
PHP display data from xml with the query
我有以下脚本显示来自 xml 的数据。
events.xml
<SchoolCalendar>
<CalendarEvent>
<StartTime>07:30</StartTime>
<Title>test Title 1</Title>
<Location>Room 1</Location>
</CalendarEvent>
<CalendarEvent>
<StartTime>01:10</StartTime>
<Title>test Title 2</Title>
<Location>Room 15</Location>
</CalendarEvent>
<CalendarEvent>
<StartTime>03:30</StartTime>
<Title>test Title 3</Title>
<Location>Room 18</Location>
</CalendarEvent>
<CalendarEvent>
<StartTime>14:30</StartTime>
<Title>test Title 4</Title>
<Location>Room 21</Location>
</CalendarEvent>
<CalendarEvent>
<StartTime>14:30</StartTime>
<Title>test Title 5</Title>
<Location>Room 12</Location>
</CalendarEvent>
<CalendarEvent>
<StartTime>15:30</StartTime>
<Title>test Title 6</Title>
<Location>Room 111</Location>
</CalendarEvent>
php代码:
$today = date("H:i");
$lib = simplexml_load_file("events.xml");
$query = $lib->xpath("/SchoolCalendar/CalendarEvent[StartTime = '14:30']");
if( $query ) {
foreach($query as $node){
echo "<tr>";
echo "<td>$node->StartTime</td>";
echo "<td>$node->Title</td>";
echo "<td>$node->Location</td>";
echo "</tr>";
}
}
else {
}
上面的代码只会显示StartTime为14:30的两个事件。我怎样才能显示所有未来的事件,试过以下但没有显示。
$query = $lib->xpath("/SchoolCalendar/CalendarEvent[StartTime >= '$today']");
非常感谢任何帮助,谢谢。
除了遍历所有事件并检查它 StartTime
理论上有一个使用 >=
operator 和 xs:time
类型的 XPath 解决方案,如下所示:
/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 参数:
$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: Never XQuery 版本也有fn:current-time()
。我不得不使用一个固定的 xs:time
来让它工作。
我有以下脚本显示来自 xml 的数据。
events.xml
<SchoolCalendar>
<CalendarEvent>
<StartTime>07:30</StartTime>
<Title>test Title 1</Title>
<Location>Room 1</Location>
</CalendarEvent>
<CalendarEvent>
<StartTime>01:10</StartTime>
<Title>test Title 2</Title>
<Location>Room 15</Location>
</CalendarEvent>
<CalendarEvent>
<StartTime>03:30</StartTime>
<Title>test Title 3</Title>
<Location>Room 18</Location>
</CalendarEvent>
<CalendarEvent>
<StartTime>14:30</StartTime>
<Title>test Title 4</Title>
<Location>Room 21</Location>
</CalendarEvent>
<CalendarEvent>
<StartTime>14:30</StartTime>
<Title>test Title 5</Title>
<Location>Room 12</Location>
</CalendarEvent>
<CalendarEvent>
<StartTime>15:30</StartTime>
<Title>test Title 6</Title>
<Location>Room 111</Location>
</CalendarEvent>
php代码:
$today = date("H:i");
$lib = simplexml_load_file("events.xml");
$query = $lib->xpath("/SchoolCalendar/CalendarEvent[StartTime = '14:30']");
if( $query ) {
foreach($query as $node){
echo "<tr>";
echo "<td>$node->StartTime</td>";
echo "<td>$node->Title</td>";
echo "<td>$node->Location</td>";
echo "</tr>";
}
}
else {
}
上面的代码只会显示StartTime为14:30的两个事件。我怎样才能显示所有未来的事件,试过以下但没有显示。
$query = $lib->xpath("/SchoolCalendar/CalendarEvent[StartTime >= '$today']");
非常感谢任何帮助,谢谢。
除了遍历所有事件并检查它 StartTime
理论上有一个使用 >=
operator 和 xs:time
类型的 XPath 解决方案,如下所示:
/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 参数:
$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: Never XQuery 版本也有fn:current-time()
。我不得不使用一个固定的 xs:time
来让它工作。