【问题标题】:Long Polling XML with PHP and JSON via AJAX通过 AJAX 使用 PHP 和 JSON 长轮询 XML
【发布时间】:2014-02-03 01:58:18
【问题描述】:

我有一个后端脚本 (getData.php),它与 ​​AJAX 脚本一起使用,以便在更改特定文件的时间戳时更新浏览器,作为长轮询的一种手段。在轮询 .txt 文件时,我已经让脚本工作了,因为它只是将文本逐字回显到浏览器。但是,现在我正在尝试轮询一个我不想逐字回显的 XML 文件;正如您在下面的脚本中看到的那样,我正在尝试识别父节点和子节点,并在合适的地方使用其他 HTML 元素来回显它们。

    <?php

    $filename = dirname(__FILE__).'/data.xml';

    $lastmodif = isset($_GET['timestamp']) ? $_GET['timestamp'] : 0;
    $currentmodif = filemtime($filename);

    while ($currentmodif <= $lastmodif) {
        usleep(10000);
        clearsatcache();
        $currentmodif = filemtime($filename);
    }

    $response = array();
    $response['msg']        = SimpleXMLElement(file_get_contents($filename));
    $response['timestamp']      = $currentmodif;
    $data = json_encode($response);

    // Print the text portions to extract
    foreach ($data['range']['item'] as $book)
    {
        echo "<div>Book: {$book['bookname']}<p>{$book['text']}</p></div>\n";
    }

    // Print the array
    echo "<pre>";
    print_r($data);
    echo "</pre>";

    ?>

请记住,当我只是 echo json_encode($response); 时,脚本正在处理文本文件,但现在我正在制作变量 $data = json_encode($response);,然后使用 print_r($data); 它不起作用。有什么想法吗?

这是我的示例 XML 文件:

    <library>
      <book>
        <bookname>Beowulf</bookname>
        <text>This is fake, enter real text here. </text>
      </book>
      <book>
        <bookname>Old Yeller</bookname>
        <text>This is fake, enter real text here. </text>
      </book>
      <book>
        <bookname>White Fang</bookname>
        <text>This is fake, enter real text here. </text>
      </book>
    </library>

【问题讨论】:

  • $data 后 json_encode 是一个对象,不再是一个数组,这就是为什么你的循环不起作用。
  • 您没有正确使用 simplexmlelement:php.net/manual/en/class.simplexmlelement.php
  • @zeflex 感谢您的输入,但这并不能说明根本原因或与问题相关。如何定位特定节点并回显它们?感谢您的反馈,尽管我会努力清理语法。

标签: php jquery ajax xml json


【解决方案1】:

您应该能够使用simplexml_load_file 并获取特定节点。

说这是一个示例 xml

<library>
    <range>
      <item>
        <book>
          <bookname>Beowolf</bookname>
          <text>This is fake, enter real text here. </text>
        </book>
      </item>
    </range>
  </library> 

一个例子

$xObj = simplexml_load_file($filename):
$response['bookname'] = $xObj->bookname;

或者也许在一个循环中。

$xObj = simplexml_load_file($filename);
foreach($xObj as $book){
  echo (string)$book->bookname;
  echo "<br />";
}

http://us1.php.net/simplexml_load_file

更新您的评论:

$response = array();
foreach($xObj as $book){  
  $val = array(); 
  $val["msg"] = "<p>" . (string)$book->bookname . "</p>";
  $response[] = $val; 
}
$response["timestamp"] = "1234";

print_r($response);exit;

【讨论】:

  • 杰克,这个 ^ 似乎可以工作,但是,无论出于何种原因,我都无法回显内部节点的内容。请你看看这个 sn-p:pastebin.com/Dxv94wr9 看看我在这里做错了什么?谢谢。
  • 杰克,我应该补充一下,您的带有 sn-p 的代码可用于打印“&lt;br /&gt;&lt;p&gt; 标签,但 $book-&gt;bookname; 似乎没有回显。
  • 那是因为$book-&gt;bookname 仍然是一个对象。将其转换为字符串。它应该呼应每个书名。查看我的更新。
  • 杰克,那个循环似乎可以用来回显,不幸的是它只打印最后一个节点。我认为我的脚本中的循环会覆盖先前的节点,直到它到达最后一个节点。我更新了我的 XML(上图)以获得更好的示例,这里是您修改后的脚本,具有所描述的症状:pastebin.com/iLrANWns
  • 那是因为在每次迭代中你都清除了变量$response["msg"],所以你最终得到了最后一个。如果您希望每个书名都有msg 键,您可以这样做。查看我的更新。
猜你喜欢
  • 2011-09-19
  • 1970-01-01
  • 1970-01-01
  • 2013-04-11
  • 1970-01-01
  • 2014-06-24
  • 2013-10-01
  • 2016-08-14
  • 1970-01-01
相关资源
最近更新 更多