1

リンクから RSS フィードを解析しようとしています。これが私のコードです:

            $content = file_get_contents($this->feed);     
            print_r($content);   
            $rss = new SimpleXmlElement($content);
            print_r($rss);
            $rss_split = array();
           /* foreach ($rss->channel->item as $item) {
                $title = (string) $item->title; // Title
                $link = (string) $item->link; // Url Link
                $description = (string) $item->description; //Description               
                $rss_split[] = '<div><a href="' . $link . '" target="_blank" title="" >' . $title . ' </a><hr></div>';
            }*/

完全な XML はここからダウンロードされています: http://devilsworkshop.org/feed/

構造を説明するための抜粋を次に示します。

<item>
    <title>Windows 8 Appstore resembles a ghost town</title>
    <link>http://devilsworkshop.org/windows-appstore-resembles-ghost-town/</link>
    <comments>http://devilsworkshop.org/windows-appstore-resembles-ghost-town/#comments</comments>
    <pubDate>Tue, 18 Sep 2012 05:30:22 +0000</pubDate>
    <dc:creator>Vibin</dc:creator>
    <category><![CDATA[Analysis]]></category>
    <category><![CDATA[Windows 8]]></category>

    <guid isPermaLink="false">http://devilsworkshop.org/?p=62284</guid>
    <description><![CDATA[<p>Microsoft is all set to release Windows 8 for public in the coming weeks. Apparently, the biggest change in Windows 8 seems to be the Metro UI (I know it&#8217;s no more called Metro, but let&#8217;s keep it like that [...]</p><p>--
            This Post <a href="http://devilsworkshop.org/windows-appstore-resembles-ghost-town/">Windows 8 Appstore resembles a ghost town</a> is Published on <a href="http://devilsworkshop.org">Devils Workshop</a> .
        </p><h3>Related posts:</h3><ul>
            <li><a href='http://devilsworkshop.org/googles-new-look-resembles-yahoo-search/' rel='bookmark' title='Google&#8217;s new look resembles Yahoo Search'>Google&#8217;s new look resembles Yahoo Search</a></li>
        </ul>]]></description>
    <content:encoded><![CDATA[<p>Microsoft is all set to release Windows 8 for public in the coming weeks. Apparently, the biggest change in Windows 8 seems to be the Metro UI (I know it&#8217;s no more called Metro, but let&#8217;s keep it like that for simplicity) and apps.</p>
        <ul>
        <h2>Apps are less advanced</h2>
        <p>Metro is great on tablets, but on desktop, it looks like an OS with dumbed down apps. Take Skitch for example, it is an app for taking and editing screenshots and was previously a Mac-only app but recently came to Windows 8. Just compare these two apps and you&#8217;ll know what I meant.</p>
        <p>Here&#8217;s how Skitch looks in Windows 8:</p>
        <p><a href="http://devilsworkshop.org/files/2012/09/SkitchinWindows8.png"><img style=' display: block; margin-right: auto; margin-left: auto;'  class="aligncenter size-full wp-image-62302" title="SkitchinWindows8" src="http://devilsworkshop.org/files/2012/09/SkitchinWindows8.png" alt="" width="740" height="570" /></a></p>
        <p>And now, this is the Mac version of Skitch:</p>
        <p><a href="http://devilsworkshop.org/files/2012/09/SkitchinMac.png"><img style=' display: block; margin-right: auto; margin-left: auto;'  class="aligncenter size-full wp-image-62301" title="SkitchinMac" src="http://devilsworkshop.org/files/2012/09/SkitchinMac.png" alt="" width="671" height="575" /></a></p>
        <p>Another example can be Newsmix, an app which will let you read stuff that matters to you &#8211; in a Magazine layout. Apparently, this app is a fail for someone like me who subscribe to 50+ blogs.</p>
        <p><a href="http://devilsworkshop.org/files/2012/09/NewsmixinWindows8.png"><img style=' display: block; margin-right: auto; margin-left: auto;'  class="aligncenter size-large wp-image-62305" title="NewsMix in Windows 8" src="http://devilsworkshop.org/files/2012/09/NewsmixinWindows8-1024x640.png" alt="news-mix-windows-8" width="620" height="387" /></a><br />
            Sure, it will be great on a Windows slate, but not really on a PC/laptop.</p>
        <li><a href='http://devilsworkshop.org/how-to-enable-hibernate-option-in-windows-vistawindows-7/' rel='bookmark' title='How to enable Hibernate Option in Windows Vista/Windows 7'>How to enable Hibernate Option in Windows Vista/Windows 7</a></li>
        <li><a href='http://devilsworkshop.org/windows-store/' rel='bookmark' title='Microsoft to Introduce Windows Store with Windows 8 Platform'>Microsoft to Introduce Windows Store with Windows 8 Platform</a></li>
        </ul>]]>
    </content:encoded>          
    <wfw:commentRss>http://devilsworkshop.org/windows-appstore-resembles-ghost-town/feed/</wfw:commentRss>
    <slash:comments>0</slash:comments>
</item>

印刷すると、タグ$contentの画像が表示されます。content:encodedしかし、印刷$rssではそのタグがまったく表示されず、説明タグも表示されSimpleXMLElement Object()ます。

両方のタグを解析したい。私はどこで間違っていますか?

4

3 に答える 3

2

まず、print_r()SimpleXML オブジェクトは「通常の」PHP オブジェクトではないため、SimpleXML オブジェクトがどのように動作するかを予測するのには適していません。特定のノードまたはノードのリストのコンテンツ、子、および属性を一覧表示するmy simplexml_dump()functionを試すことができます。

次に、content:encoded要素は名前空間にあるため、メソッドcontentを使用してデフォルトではなく、その名前空間のノードにアクセスするよう SimpleXML に指示する必要があります。例えば->children()echo $item->children('content', true)->encoded;

于 2012-09-18T12:21:53.420 に答える
1

もちろん、印刷$rssはデータを表示していません..それ自体が実際にSimpleXMLElement Object.

ただし、それはさておき、私が知る限り、あなたの xml ドキュメントは有効ではないため、解析に失敗していますUTF-8。それをクライアントにコピーして調べてみると、たくさんのxA0x92文字が見つかりました。

それらをそれぞれ対応する文字(スペースとアポストロフィ)に置き換えてドキュメントを保存すると、正常に解析されました。

これは間違いなくあなたの問題です。

この問題の解決策は次のとおりです。

$char_arr = array('/\xa0/','/\x92/','/\x96/');
$rep_arr = array('&nbsp;','\'','-');
$content = preg_replace($char_arr, $rep_arr, $content);

simpleXML オブジェクトの宣言の前に、次のコードを配置してください。

$content = file_get_contents($this->feed);     
print_r($content);
$char_arr = array('/\xa0/','/\x92/','/\x96/');
$rep_arr = array('&nbsp;','\'','-');
$content = preg_replace($char_arr, $rep_arr, $content);
$rss = new SimpleXmlElement($content);

これで問題は解決するはずです。自分でテストしましたが、私の側ではうまくいきました。

于 2012-09-18T07:28:11.987 に答える
0

IMSoP の回答のおかげで、同じ問題を解決するために、代わりに xaviered_at gmail_dot_com の xmlObjToArr($obj) 関数が見つかり、使用されたhttp://php.net/simplexmlに直接たどりました。

content:encoded の間にタグ付けされたコンテンツを取得する簡単な方法をまだ探している人のための短くて明白なスクリプトを次に示します。

<?php

echo "<pre>";

$url = "http://devilsworkshop.org/feed/";
$rss = simplexml_load_file($url);

if($rss){

    $items = $rss->channel->item;

    foreach($items as $item){

        $title = $item->title;
        $image = $item->image;
        $link = $item->link;
        $published_on = $item->pubDate;
        $description = $item->description;

        // bringing in to array <content:encoded> items from SimpleXMLElement Object()
        $content = xmlObjToArr($item->children('content', true)->encoded);


        echo "

        title: $title
        image: $image
        link: $link
        published on: $published_on
        description: $description
        content: 
        ";

        print_r($content);

    }
}


function xmlObjToArr($obj) {
        $namespace = $obj->getDocNamespaces(true);
        $namespace[NULL] = NULL;

        $children = array();
        $attributes = array();
        $name = strtolower((string)$obj->getName());

        $text = trim((string)$obj);
        if( strlen($text) <= 0 ) {
            $text = NULL;
        }

        // get info for all namespaces
        if(is_object($obj)) {
            foreach( $namespace as $ns=>$nsUrl ) {
                // atributes
                $objAttributes = $obj->attributes($ns, true);
                foreach( $objAttributes as $attributeName => $attributeValue ) {
                    $attribName = strtolower(trim((string)$attributeName));
                    $attribVal = trim((string)$attributeValue);
                    if (!empty($ns)) {
                        $attribName = $ns . ':' . $attribName;
                    }
                    $attributes[$attribName] = $attribVal;
                }

                // children
                $objChildren = $obj->children($ns, true);
                foreach( $objChildren as $childName=>$child ) {
                    $childName = strtolower((string)$childName);
                    if( !empty($ns) ) {
                        $childName = $ns.':'.$childName;
                    }
                    $children[$childName][] = xmlObjToArr($child);
                }
            }
        }

        return array(
            'name'=>$name,
            'text'=>$text,
            'attributes'=>$attributes,
            'children'=>$children
        );
    }


?>
于 2013-04-23T14:16:41.257 に答える