Skip to main content
 首页 » 编程设计

php之PHP通过查询显示xml中的数据

2025年05月04日18Renyi-Fan

我有以下脚本显示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
理论上,存在使用>= operatorxs:time类型的XPath解决方案,如下所示:

/SchoolCalendar/CalendarEvent[xs:time(concat(StartTime, ':00')) >= xs:time('14:00:00')] 


Online Demo

但是,这需要XPath 2+,并且使用PHP,您只能访问XPath 1.0(带有某些XPath 2扩展名)。
但是,它可以使用PHP 5的 DOMXPath::registerPhpFunctions在XPath中完成。

样例代码:

$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:从不XQuery版本也具有 fn:current-time()。我必须使用固定的 xs:time使其起作用。