【问题标题】:Parsing xml feed with cdata PHP SimpleXML [duplicate]使用 cdata PHP SimpleXML 解析 xml 提要 [重复]
【发布时间】:2014-06-01 15:12:25
【问题描述】:

我正在使用 php 将 rss 提要解析为 json。

使用下面的代码

我的 json 输出包含来自 item 元素的描述数据,但标题和链接数据未提取

  • 问题在于 CDATA 不正确或我的代码未正确解析它。

xml 是here

$blog_url = 'http://www.blogdogarotinho.com/rssfeedgenerator.ashx';

$rawFeed = file_get_contents($blog_url);
$xml=simplexml_load_string($rawFeed,'SimpleXMLElement', LIBXML_NOCDATA);

// step 2: extract the channel metadata
$articles = array();    

// step 3: extract the articles

foreach ($xml->channel->item as $item) {
    $article = array();

    $article['title'] = (string)trim($item->title);
    $article['link'] = $item->link;      
    $article['pubDate'] = $item->pubDate;
    $article['timestamp'] = strtotime($item->pubDate);
    $article['description'] = (string)trim($item->description);
    $article['isPermaLink'] = $item->guid['isPermaLink'];        

    $articles[$article['timestamp']] = $article;
}

echo json_encode($articles);

【问题讨论】:

  • 如果我运行您的示例,我的输出将包含一堆 <![CDATA[ 标签。但是我不确定你是否看到同样的东西?你想删除它们吗?或者您根本看不到他们的内容?
  • 我没有得到任何标题和链接。它什么也没给我
  • 我认为这可能是因为不同的 php/libxml 版本(我在这里运行 5.5.12),也在 php 5.4.29 和 5.3.23 上尝试过,但得到了相同的结果。你用的是什么 PHP 版本?
  • @my localhost 我什至在服务器上使用 5.5.6。将 xml 解析为 json 后,我在 localhost 和服务器上都获得了链接和标题的空白值......但是我尝试将 xml 下载到文件并解析得到相同的结果.....我尝试过的一件事是放 标签我能够成功完全解析....但仍然不能解决问题
  • 注意trim()总是返回一个字符串,所以(string)trim($item->title)中的(string)什么都不做;如果有的话,您需要转换它的 input,这将是 trim((string)$item->title),尽管它可能会隐含地这样做。但是,您应该转换其他值,例如$article['link'] = (string)$item->link; 在将它们传递给其他函数之前。

标签: php xml json simplexml


【解决方案1】:

我认为你只是浏览器隐藏标签的受害者。让我解释: 您的输入提要实际上并没有 <![CDATA[ ]]> 标签,< 和 >s 实际上是在 rss 流的原始源中编码的实体,点击 ctrl+ u 在浏览器的 rss 链接上,你会看到:

<?xml version="1.0" encoding="utf-16"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="2.0">
  <channel>
    <description>Blog do Garotinho</description>
    <item>
      <description>&lt;![CDATA[&lt;br&gt;
          Fico impressionado com a hipocrisia e a falsidade de certos políticos....]]&gt;
      </description>
      <link>&lt;![CDATA[http://www.blogdogarotinho.com.br/lartigo.aspx?id=16796]]&gt;</link>
...
      <title>&lt;![CDATA[A bancada dos caras de pau]]&gt;</title>
    </item>

如您所见,&lt;title&gt; 例如以 &amp;lt; 开头,当 simplexml 为您的 json 数据返回它时,它将变为 &amp;lt;。 现在,如果您在浏览器中查看打印的 json 数据,您的浏览器将看到以下内容:

"title":"<![CDATA[A bancada dos caras de pau]]>"

不会被渲染,因为它在标签内。描述似乎出现了,因为它在某个点上有一个 &lt;br&gt; 标记,该标记结束了第一个“标记”,因此您可以看到输出的其余部分。

如果您点击 ctrl+u,您应该会看到按预期打印的输出(我自己使用的是命令行 php 文件,并没有首先注意到这一点)。

试试这个演示:

您可以尝试通过在解析后用简单的preg_replace() 替换它们来摆脱它们:

function clean_cdata($str) {
    return preg_replace('#(^\s*<!\[CDATA\[|\]\]>\s*$)#sim', '', (string)$str);
}

如果 CDATA 块位于各个标签的开头或结尾,这应该注意它们。你可以像这样在foreach() 循环中调用这个:

// ....
$article['title'] = clean_cdata($item->title);
// ....

【讨论】:

  • 是的,任何生成 XML 的东西肯定是做错了。与号编码(&amp;gt; 等)和 CDATA 是替代转义机制,但它以某种方式同时使用两者。
  • 是的,我不确定包含 &lt;![CDATA[ 标签和 then 对包含的内容进行实体编码背后的想法是什么。然而,xml文件本身是有效的,只是有这些无意义的标签
  • 那么我怎样才能从中获得干净的 json,我需要一些字符串替换吗.. 基本上我是一个 java 开发人员,这个 php 的东西让我忘记了.. 我已经看到你的链接但是在客户端我应该发送干净的 json .. 我的意思是没有 CDATA 部分。
  • 好吧,恐怕是的,我可能也会尝试。您可以尝试联系您的 RSS 源并要求解释,也许我们遗漏了什么。
  • 我想标记你的答案,但我仍然很困惑,抱歉,但它仍然值得支持谢谢......如果你能建议我一些关于我在这个 CDATA 上花费了一整天的事情问题..谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多