From bee7cf32f7b6c8f89d5d3188d1a560f82a5bc229 Mon Sep 17 00:00:00 2001 From: Ken Brazier Date: Mon, 9 Dec 2024 21:25:19 -0700 Subject: [PATCH] Handle items at root, not under channel. Feeds like Slashdot have items outside the tags. This commit brings them inside the channel tags. This handles "rdf syntax", though sub-optimally; there are rdf tag links inside the channel tags that are ignored. --- src/Feed.php | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/Feed.php b/src/Feed.php index 3a59c27..ac89f7d 100644 --- a/src/Feed.php +++ b/src/Feed.php @@ -77,7 +77,23 @@ private static function fromRss(SimpleXMLElement $xml) self::adjustNamespaces($xml); - foreach ($xml->channel->item as $item) { + $channel = $xml->channel; + + if(isset($xml->item)) { + // Some feeds have items at root, not under channel. Add them under channel. + // Basic procedure from https://stackoverflow.com/questions/5735857/php-domdocument-move-nodes-from-a-document-to-another + $xml_dom = dom_import_simplexml($channel); + while(count($xml->item) > 0) { + // It makes no sense, but this has the side effect of popping the item as off a stack. + $item = $xml->item[0]; + $item_dom = dom_import_simplexml($item); + $item_dom_adopted = $xml_dom->ownerDocument->importNode($item_dom, true); + $xml_dom->appendChild($item_dom_adopted); + } + $channel = simplexml_import_dom($xml_dom); + } + + foreach ($channel->item as $item) { // converts namespaces to dotted tags self::adjustNamespaces($item); @@ -90,7 +106,7 @@ private static function fromRss(SimpleXMLElement $xml) } } $feed = new self; - $feed->xml = $xml->channel; + $feed->xml = $channel; return $feed; }