XMLReader + SimpleXML со строкой результата curl не может быть проанализирован как xml - PullRequest
0 голосов
/ 06 октября 2019

Я хочу проанализировать некоторые RSS-каналы XML, полученные из curl, с помощью XMLReader и SimpleXML по причине "ускорения".

Однако это не может быть проанализировано в xml из-за того, что результатом curl является строка:

$element = new SimpleXMLElement($xml->readOuterXML()); //String could not be parsed as XML

Вот мой код:

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, get_post_meta($post_id->ID, 'feed', true)); //https://wordpress.org/news/feed/
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_ENCODING , 'gzip, deflate');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$rss = curl_exec($ch);
curl_close($ch);
$xml->xml($rss);

while ($xml->read()){
    if ($xml->nodeType == XMLReader::ELEMENT){
        $element = new SimpleXMLElement($xml->readOuterXML()); //String could not be parsed as XML

        foreach ($element as $channel){
        foreach ($channel->item as $item){
                //Loop Process
        }
        }

Я что-то упустил или что-то не так?

1 Ответ

0 голосов
/ 12 октября 2019

Ошибка, которую вы видите, в основном означает, что строка, возвращаемая $xml->readOuterXml(), является недопустимым XML.

Вполне вероятно, что вы видите ошибку в этой строке первой, потому что XMLReader начинает читать XML без проверкидокумент - это не синтаксический анализатор XML, а программа чтения XML.

Однако конструктору SimpleXMLElement s требуется правильная строка XML. Так что это первое место проверки XML.

Кроме того, я должен сказать, что не смог воспроизвести вашу ошибку с примером URL фидов wordpress.org. Для меня ваш код работал без ошибок.

Кроме того, в примере SimpleXMLElement создается из первого элемента, который предлагает читатель, который является элементом документа - всего файла XML. Для этого вам действительно не нужен XMLReader, вместо этого просто создайте элемент:

<?php
$ch = curl_init('https://wordpress.org/news/feed/');
# ...
$rss = curl_exec($ch);
curl_close($ch);
$xml = new SimpleXMLElement($rss);
foreach ($xml->channel as $channel) {
    # ...
}

В противном случае, если вы захотите использовать XMLReader независимо от этого, что-то в этом направлении фактически переместит XMLReader из элемента channel в channelelement:

<?php
$ch = curl_init('https://wordpress.org/news/feed/');
# ...
$rss = curl_exec($ch);
curl_close($ch);
$xml = XMLReader::xml($rss);
if ($xml->next() && $xml->read()) { # in document element
    while ($xml->next('channel')) {
        $channel = new SimpleXMLElement($xml->readOuterXml());
        # ...
    }
}

Оба примера работают без ошибок для меня.

С этими двумя примерами вы также можете легко проверить "более быстрое" обещание.

...