【问题标题】:SimpleXML can't get CDATA with ns prefixesSimpleXML 无法获取带有 ns 前缀的 CDATA
【发布时间】:2015-06-26 15:58:03
【问题描述】:

在过去的几个小时里,我一直在努力从 xml 文件中获取 CDATA,尽管我尝试了不同的方法,如 hereherehere

我的困境与通过 xenForo 的 RSS 提要检索线程数据有关。这是我尝试检索的 RSS 数据示例,除了检索 <content:encoded> 之外,一切正常。

示例文件:

<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>News &amp; Announcements</title>
    <description>All of our important news and announcements will be here.</description>
    <pubDate>Fri, 26 Jun 2015 14:54:20 +0000</pubDate>
    <lastBuildDate>Fri, 26 Jun 2015 14:54:20 +0000</lastBuildDate>
    <generator>********* ****</generator>
    <link>https://***.****.****/forum/news/</link>
    <atom:link rel="self" type="application/rss+xml" href="https://***.****.****/forum/news/index.rss"/>
    <item>
      <title>Site under development.</title>
      <pubDate>Thu, 25 Jun 2015 05:49:43 +0000</pubDate>
      <link>https://***.****.****/threads/site-under-development.3/</link>
      <guid>https://***.****.****/threads/site-under-development.3/</guid>
      <author>invalid@example.com (*****)</author>
      <dc:creator>ShortCut Central</dc:creator>
      <content:encoded><![CDATA[Content to retrieve. <br /> Some more content a part of the same section]]></content:encoded>
    </item>
  </channel>
</rss>

我当前的代码看起来像

<?php
class SCC_Main_miscFuncs {
    public static function printMostRecentPost() {
        // Re-enable the below once we're ready to release
        //$rssUrl = func_get_arg(1);
        $rssUrl = 'https://www.shortcutcentral.org/indev.rss';
        $xml = simplexml_load_string(self::returnContents($rssUrl));
        $rawData = self::returnContents($rssUrl); // Properly contains the CDATA
        echo '<pre>';
        //echo (string) $xml->channel->item->encoded;
        //echo (string) $xml->channel->item->content;
        //var_dump($xml);
        echo '</pre>';
        //echo (string) $xml->channel->item;
        //echo $array[@attributes]['item']['link'];
        //echo $xml->message;
    }

    public static function returnContents($url){
        $curl_handle=curl_init();
        curl_setopt($curl_handle, CURLOPT_URL,$url);
        curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 2);
        curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl_handle, CURLOPT_USERAGENT, 'ShortCut Central');
        $query = curl_exec($curl_handle);
        curl_close($curl_handle);
        return $query;
    }
} 

除了未解析的 $rawData 之外,似乎没有任何内容显示所述 CDATA。我觉得这可能是因为我没有正确调用它(对 XML 和命名空间和命名空间前缀来说是全新的),但它没有通过 var_dump 显示给我......地狱。我看到了一些关于使用 XML 子级的较早帖子,但我并不完全理解这个概念,这就是为什么如果我的解决方案需要 XML 子级,我们将不胜感激。

谢谢!

另外可能值得一提的是,我的 php 代码是按照它的方式组织的(类和公共、静态函数),因此我可以将它用作 xenForo 的附加组件。

【问题讨论】:

  • 你的数据是什么样的?
  • @GordonM 示例链接不适合您吗? (点击上面的示例)
  • @Adam 您应该包含所有相关代码作为有效的最小示例。如果有人想从您的问题及其答案中学习,外部网站可能会更改,链接会损坏,那么您的问题在未来将不再有意义
  • @Michi 我会包含它,但我曾经看到有人因为过去在他们的帖子中包含代码墙而受到抨击,所以....
  • @Adam 做得好,有效的最小示例是关键,没有代码墙。

标签: php xml cdata xenforo


【解决方案1】:

您是正确的,在 SimpleXML 中返回命名空间节点的一种方法是使用 SimpleXMLElement::children(),但您必须将命名空间作为其第一个参数传递。您可以传递完整的命名空间字符串"http://purl.org/rss/1.0/modules/content/",但传递其前缀"content" 更容易,然后提供TRUE 作为第二个参数以通知children() 您传递的是前缀而不是完整字符串.

所以在你的 $xml 对象上使用一个表达式,比如:

echo (string)$xml->channel->item->children('content', TRUE)->encoded;
// Prints:
// Content to retrieve. <br /> Some more content a part of the same section

使用在代码上下文中最有意义的任何方法来检索循环中的所有相关节点。

从命名空间节点检索属性并没有太大的不同。以获取&lt;atom:link href&gt; 为例:

echo (string)$xml->channel->children('atom', true)->link->attributes()['href'];
// Prints
// https://***.****.****/forum/news/index.rss

【讨论】:

  • 谢谢!我将在今天晚些时候尝试此操作,并在完成后将您的答案标记为有效的答案。
猜你喜欢
  • 2016-09-18
  • 2014-11-22
  • 1970-01-01
  • 2013-06-19
  • 1970-01-01
  • 2016-07-03
  • 2012-10-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多