PHP 使用查询显示来自 xml 的数据

Posted

技术标签:

【中文标题】PHP 使用查询显示来自 xml 的数据【英文标题】:PHP display data from xml with the query 【发布时间】:2019-07-29 12:32:17 【问题描述】:

我有以下显示来自 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 从***.com/questions/4466494/… 开始,您只能对数字执行 >=,因此您可能需要长时间执行并遍历它们。 【参考方案1】:

除了遍历所有事件并检查它是StartTime 理论上有一个使用&gt;= operator 和xs: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 才能使其工作。

【讨论】:

谢谢,我这边的相同更改显示“此页面无法正常工作 HTTP 错误 500”。这是服务器端的东西吗? $query = $lib-&gt;xpath("/SchoolCalendar/CalendarEvent[xs:time(concat(StartTime, ":00")) &gt;= xs:time('13:00:00')] 我在 Ubuntu 中运行脚本,它有 PHP 版本 5.5.9,我猜它有 xpath 1.0 @bickyz 我已经描述了一种适用于 PHP 5 和 XPath 1.0 的替代方法。 请注意,据我所知,所有版本的 PHP 仅支持 XPath 1.0,因为这就是它内部使用的 libxml 库实现的全部内容。 @wp78de,谢谢。我创建了一个新的 php 页面并粘贴了您的代码,但是该页面没有显示任何内容,它是空白的,没有错误。不知道我错过了什么?我已将第二行修改为$doc-&gt;loadXML(data.xml);

以上是关于PHP 使用查询显示来自 xml 的数据的主要内容,如果未能解决你的问题,请参考以下文章

PHP读取XML并写入数据库

使用来自子元素的数据在 php 中使用 simplexml 选择其他元素中的数据

使用 simplexml 在 html 网站中显示来自 xml 的图像

PHP:来自数据库的内容未正确显示

在 PHP 中查询服务器并接收 XML 响应

如何显示来自 mySQL 的正确数据?