Mehrfach-Elemente in RSS item ?
lima-city → Forum → Programmiersprachen → PHP, MySQL & .htaccess
array
artikel
ausgabe
auslese
bedingung
bekommen
bericht
code
datum
einzelne objekte
element
funktion
http
index
internet
lesestoff
objekt
page
string
struktur
-
Hallo
Beim Auslesen einer RSS hatte ich Probleme bei mehrfachen Elementen innerhalb <item>
vereinfachtes Beispiel:
... <item> <title>Irgend ein Artikel</title> <link>http://example.org/index.php?page=116</link> <pubDate>Fri, 05 Apr 2013 11:51:37 +0000</pubDate> <category><![CDATA[Artikel]]></category> <category><![CDATA[Internet]]></category> <category><![CDATA[Sonstiges]]></category> <category><![CDATA[Lesestoff]]></category> <guid>116</guid> <description><![CDATA[Bla blabla blablabla bla blabla blablabla]]></description> </item> ...
ich hole die RSS Daten per simplexml in ein PHP Object
und gehe dann mit einer foreach() Schleife durch die Daten
$sourceurl = 'feed.rss'; $xmlobject = simplexml_load_file($sourceurl, 'SimpleXMLElement', LIBXML_NOCDATA);
DEBUG mit
egibt folgende Ausgabe:print_r($xmlobject);
SimpleXMLElement Object ( [@attributes] => Array ( [version] => 2.0 ) [channel] => SimpleXMLElement Object ( [title] => Name der Seite [link] => http://example.org [description] => Berichte und Artikel [lastBuildDate] => Fri, 05 Apr 2013 11:51:37 +0000 [language] => de-DE [item] => Array ( [0] => SimpleXMLElement Object ( [title] => Irgend ein Artikel [link] => http://example.org/index.php?page=116 [pubDate] => Fri, 05 Apr 2013 11:51:37 +0000 [category] => Array ( [0] => Artikel [1] => Internet [2] => Sonstiges [3] => Lesestoff ) [guid] => 116 [description] => Bla blabla blablabla bla blabla blablabla ) [1] => SimpleXMLElement Object ( [title] => Noch so ein Bericht [link] => http://example.org/index.php?page=115 [pubDate] => Fri, 04 Apr 2013 16:21:47 +0000 [category] => Array ( [0] => Berichte [1] => Real-Life [2] => Allgemein [3] => Laberzeug ) [guid] => 115 [description] => Blubber blubb blubbblubb blubb blubber blubb ) ) ) )
also ist jeweils das Element [category] ein Array innerhalb $xmlobject->channel->item
ABER ... wenn ich mit foreach() durchgehe,
dann kommt jedes Elemet von [category] einzeln als SimpleXMLElement Object
und nicht (wie erwartet) als ein Array
$nr = 1; foreach ($xmlobject->channel->item as $item) { print "<br />--------- Item: ".$nr." --------- \n"; foreach ($item as $key => $val) { print "<br />".$key." --- ".print_r($val,true)."\n"; } print "<br />\n"; $nr++; }
macht als Ausgabe:
--------- Item: 1 --------- title --- SimpleXMLElement Object ( [0] => Irgend ein Artikel ) link --- SimpleXMLElement Object ( [0] => http://example.org/index.php?page=116 ) pubDate --- SimpleXMLElement Object ( [0] => Fri, 05 Apr 2013 11:51:37 +0000 ) category --- SimpleXMLElement Object ( [0] => Artikel ) category --- SimpleXMLElement Object ( [0] => Internet ) category --- SimpleXMLElement Object ( [0] => Sonstiges ) category --- SimpleXMLElement Object ( [0] => Lesestoff ) guid --- SimpleXMLElement Object ( [0] => 116 ) description --- SimpleXMLElement Object ( [0] => Bla blabla blablabla bla blabla blablabla ) --------- Item: 2 --------- title --- SimpleXMLElement Object ( [0] => Noch so ein Bericht ) link --- SimpleXMLElement Object ( [0] => http://example.org/index.php?page=115 ) pubDate --- SimpleXMLElement Object ( [0] => Fri, 04 Apr 2013 16:21:47 +0000 ) category --- SimpleXMLElement Object ( [0] => Berichte ) category --- SimpleXMLElement Object ( [0] => Real-Life ) category --- SimpleXMLElement Object ( [0] => Allgemein ) category --- SimpleXMLElement Object ( [0] => Laberzeug ) guid --- SimpleXMLElement Object ( [0] => 115 ) description --- SimpleXMLElement Object ( [0] => Blubber blubb blubbblubb blubb blubber blubb )
aber im DEBUG mit print_r ist category doch als Array drin ?!?
also hätte ich auch in der foreach für category ein Array erwartet, ... aber ... Pustekuchen !
dann habe ich eine if-Bediungng eingeführt, die wenn $key == 'category' daraus ein Array macht
$i=0; foreach ($xmlobject->channel->item as $item) { $nr = ($i+1); print "<br />--------- Item: ".$nr." --------- \n"; foreach ($item as $key => $val) { if ($key == 'category') { $catarr = array(); foreach($item->category as $catval) { $catarr[] = (string)$catval; } $valdata = $catarr; } else { $valdata = (string)$val; } $articles[$i][$key] = $valdata; } print "<br />\n"; print "<pre>".print_r($articles[$i],true)."</pre>\n"; print "<br />\n"; $i++; }
das ist schonmal besser, damit bekomme ich die Ausgabe:
--------- Item: 1 --------- Array ( [title] => Irgend ein Artikel [link] => http://example.org/index.php?page=116 [pubDate] => Fri, 05 Apr 2013 11:51:37 +0000 [category] => Array ( [0] => Artikel [1] => Internet [2] => Sonstiges [3] => Lesestoff ) [guid] => 116 [description] => Bla blabla blablabla bla blabla blablabla ) --------- Item: 2 --------- Array ( [title] => Noch so ein Bericht [link] => http://example.org/index.php?page=115 [pubDate] => Fri, 04 Apr 2013 16:21:47 +0000 [category] => Array ( [0] => Berichte [1] => Real-Life [2] => Allgemein [3] => Laberzeug ) [guid] => 115 [description] => Blubber blubb blubbblubb blubb blubber blubb )
gut, so funtioniert das für das "bekannte" Sub-Element = [category]
Aber es könnte ja auch ein anderes Sub-Element mehrfach vorkommen
dessen $key Wert (Element-Name) man nicht vorher kennt ...
.... damit jetzt zur eigentlichen Frage:
Wie kann ich mehrfach vorkommende (gleichnamige) Sub-Elemente von <item> im $xmlobject
immer als Array bekommen ... gibt es da eine bessere Lösung als meine if-Bedingung
Warum bekomme ich mit print_r bei [category] die Daten als Array
aber bei Durchlauf mit foreach() dann wieder einzelne Objekte ???
... spinnt simplexml ?
... spinnt print_r ?
... spinnt foreach ?
... oder spinn ich ?!?
:)
-
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
Hallo keyrank,
ich denke print_r spinnt, bzw. ist das mal wieder eine typische PHP-Verwechslung.
Was print_r dir als Array anzeigt ist ja in Wirklichkeit ein Objekt, bzw. untergeordnete Objekte und kein Array im eigentlichen Sinne.
Die Frage ist, wie man mit PHP so etwas durchlaufen kann, dafür gibt es sicherlich eine Funktion, die ich dir aber gerade nicht nennen kann, da ich mich schon länger nicht mehr mit Objektorientierung in PHP befasst habe. Vielleicht ist es auch nicht möglich, und es gibt aber einen Workaround.
Hast du schonmal bei php.net bei der simpleXML Doku geschaut, ob es zu der Frage bereits eine Antwort gibt?
In den Kommentaren zu Funktionen dort gibt es sehr oft Lösungen für die unmöglichsten Probleme, vielleicht findest du ja etwas passendes.
Gruß
aliendwarf -
ich würde da 2 unterschiedliche lösungsansätze vermuten:
1.:<?xml version="1.0"?> <item> <title>Irgend ein Artikel</title> <link>http://example.org/index.php?page=116</link> <pubDate>Fri, 05 Apr 2013 11:51:37 +0000</pubDate> <category category="Artikel"><![CDATA[Artikel]]></category> <category category="Internet"><![CDATA[Internet]]></category> <category category="Sonstiges"><![CDATA[Sonstiges]]></category> <category category="Lesestoff"><![CDATA[Lesestoff]]></category> <guid>116</guid> <description><![CDATA[Bla blabla blablabla bla blabla blablabla]]></description> </item>
oder 2.:
<?xml version="1.0"?> <item> <title>Irgend ein Artikel</title> <link>http://example.org/index.php?page=116</link> <pubDate>Fri, 05 Apr 2013 11:51:37 +0000</pubDate> <categories> <article><![CDATA[Artikel]]></artivle> <internet><![CDATA[Internet]]></internet> <sonstiges><![CDATA[Sonstiges]]></sonstiges> <lesestoff><![CDATA[Lesestoff]]></lesestoff> </categories> <guid>116</guid> <description><![CDATA[Bla blabla blablabla bla blabla blablabla]]></description> </item>
Beitrag zuletzt geändert: 6.4.2013 2:19:16 von czibere -
naja ... andere (bessere) XML Struktur wäre gut,
aber wenn man externe RSS-Quellen auslesen will,
dann kann man ja nicht die XML-Struktur ändern, da muss man nehmen was ankommt.
... zumal auch Wordpress RSS diese mehrfachen <category> Elemente in <item> leifert.
Idee wäre zu Prüfen, ob ein Element mind. ein zweites mal vorkommt,
und wenn ja, dann diese zweite foreach() darauf anwenden.
Hier mal mein Workaround mit dem Beispiel:
(1) Der Inhalt der Datei: test1.rss
<?xml version="1.0" encoding="UTF-8"?> <rss version="2.0"> <channel> <title>Name der Seite</title> <link>http://example.org</link> <description>Berichte und Artikel</description> <lastBuildDate>Fri, 05 Apr 2013 11:51:37 +0000</lastBuildDate> <language>de-DE</language> <item> <title>Irgend ein Artikel</title> <link>http://example.org/index.php?page=116</link> <pubDate>Fri, 05 Apr 2013 11:51:37 +0000</pubDate> <category><![CDATA[Artikel]]></category> <category><![CDATA[Internet]]></category> <category><![CDATA[Sonstiges]]></category> <category><![CDATA[Lesestoff]]></category> <guid>116</guid> <description><![CDATA[Bla blabla blablabla bla blabla blablabla]]></description> </item> <item> <title>Noch so ein Bericht</title> <link>http://example.org/index.php?page=115</link> <pubDate>Fri, 04 Apr 2013 16:21:47 +0000</pubDate> <keywrd><![CDATA[Berichte]]></keywrd> <keywrd><![CDATA[Unbekannt]]></keywrd> <keywrd><![CDATA[Allgemein]]></keywrd> <keywrd><![CDATA[Laberzeug]]></keywrd> <guid>115</guid> <description><![CDATA[Blubber blubb blubbblubb blubb blubber blubb]]></description> </item> <item> <title>Noch Mehr davon</title> <link>http://example.org/index.php?page=114</link> <pubDate>Fri, 04 Apr 2013 15:31:42 +0000</pubDate> <category><![CDATA[Ganz Alleine]]></category> <guid>114</guid> <description><![CDATA[Lalelu lalla la lalelu la lalala Lalelu la]]></description> </item> </channel> </rss>
(2) Der PHP-Code (Workaround)
<?php // ------------------------------------------------------- header("Content-Type: text/html; charset=utf-8"); // ------------------------------------------------------- $sourceurl = 'test1.rss'; $xmlobject = simplexml_load_file($sourceurl, 'SimpleXMLElement', LIBXML_NOCDATA); $resultarr = array(); // ------------------------------------------------------- $i=0; foreach ($xmlobject->channel->item as $item) { foreach ($item as $key => $val) { if (isset($resultarr[$i][$key]) && !is_array($resultarr[$i][$key])) { $subarr = array(); foreach($item->$key as $subval) { $subarr[] = (string)$subval; } $resultarr[$i][$key] = (array)$subarr; } else { $resultarr[$i][$key] = (string)$val; } } $i++; } // ------------------------------------------------------- print "<br />\n"; print "<br />\n"; print "<br /> --------- DEBUG --- \$resultarr --------- \n"; print "<br />\n"; print "<br />\n"; print "<pre style=\"background:#DEDEDE;\">\n"; print_r($resultarr); print "</pre>\n"; print "<br />\n"; print "<br />\n"; print "<br />\n"; // ------------------------------------------------------- ?>
(3) Die Ausgabe --------- DEBUG --- $resultarr ---------
Array ( [0] => Array ( [title] => Irgend ein Artikel [link] => http://example.org/index.php?page=116 [pubDate] => Fri, 05 Apr 2013 11:51:37 +0000 [category] => Array ( [0] => Artikel [1] => Internet [2] => Sonstiges [3] => Lesestoff ) [guid] => 116 [description] => Bla blabla blablabla bla blabla blablabla ) [1] => Array ( [title] => Noch so ein Bericht [link] => http://example.org/index.php?page=115 [pubDate] => Fri, 04 Apr 2013 16:21:47 +0000 [keywrd] => Array ( [0] => Berichte [1] => Unbekannt [2] => Allgemein [3] => Laberzeug ) [guid] => 115 [description] => Blubber blubb blubbblubb blubb blubber blubb ) [2] => Array ( [title] => Noch Mehr davon [link] => http://example.org/index.php?page=114 [pubDate] => Fri, 04 Apr 2013 15:32:42 +0000 [category] => Ganz Alleine [guid] => 114 [description] => Lalelu lalla la lalelu la lalala Lalelu la ) )
sieht doch ganz gut aus ... :=) ...
das $resultarr liefert die Mehrfach-Elemente als Array, wie gewünscht
und wenn doch nur einzeln, dann direkt als String (siehe $resultarr[2] )
Beitrag zuletzt geändert: 6.4.2013 15:28:19 von incdesign -
Mit der Funktion print_r() wird eine Variable in lesbarer Form dargestellt.
Mit der Funktion foreach() iterierst du Arrays und Objekte.
In deinem Fall wird mitprint_r($xmlobject);
die Variable $xmlobject komplett, d.h. mit allen darin befindlichen Arrays dargestellt.
Wie kann ich mehrfach vorkommende (gleichnamige) Sub-Elemente von <item> im $xmlobject
immer als Array bekommen ... gibt es da eine bessere Lösung als meine if-Bedingung
Da bietet sich Rekursion an.
Ein Beispiel
und die dazugehörige Funktion:
function my_array($var) {if(is_array($var)) { foreach($var as $key) { echo "<ul><li>"."KEY:".array_search($key,$var)."----------WERT:".$key; my_array($key); // Rekursion } }echo "</li></ul>"; } my_array($arr); // Funktionsaufruf
Beitrag zuletzt geändert: 6.4.2013 15:40:37 von timebandit -
Danke
naja, wenn ich in der foreach aber kein Array habe, sondern alles als einzelne Objekte,
dann bringt mir das auch wenig, eine Rekursion zu machen wenn is_array()
... das Array muss ich dann also doch selber anlegen wenn nötig (mehrfach Sub-Elemente in item)
ich finde die Lösung von incdesing schn ganz gut.
Wenn item-Element schon existiert, dann als Array of Strings, sonst direkt als String.
Hier nochmal als Funktion: RSS Items aus simplexml Object in Array ablegen
<?php // ------------------------------------------------------- function get_rss_items($xmlobject) { $resdata = array(); $i=0; foreach($xmlobject->channel->item as $item) { foreach($item as $key => $val) { if (isset($resdata[$i][$key]) && !is_array($resdata[$i][$key])) { $resdata[$i][$key] = array(); foreach($item->$key as $subval) { $resdata[$i][$key][] = (string)$subval; } } else { $resdata[$i][$key] = (string)$val; } } $i++; } return $resdata; } // ------------------------------------------------------- $sourceurl = 'test1.rss'; $xmlobject = simplexml_load_file($sourceurl, 'SimpleXMLElement', LIBXML_NOCDATA); $rssitems = get_rss_items($xmlobject); print "<pre>\n"; print_r($rssitems); print "</pre>\n"; // ------------------------------------------------------- ?>
das funktioniert ganz gut. Danke.
-
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage