XML durchsuchen -> simplexml

webbudda

Mitglied
Hallo,

ich habe ein XMLfile folgender Art:

Code:
<markers>
<marker entry="149"  eintrag="2009-10-10 16:35:52" ... />
<markers>

Jetzt möchte ich die "neusten" 5 Einträge darstellen. Folgenden Code habe ich bisher:
PHP:
$xml = simplexml_load_file("data.xml");
for($i = 0; $i < 5; $i++)
  {
$att = $xml->marker[$i]->attributes();

echo $att['entry'];

  }

Ich steh gerade auf dem Schlauch und weiss nicht so recht, die ich die Abfrage der 5 neusten Einträge gestallten kann.

Jemand eine idee?
 
Auch wenn du es in eine andere Variable speicherst, bleibt es ein Objekt und wird nicht zu einem Array.

PHP:
<?php

$str = '<markers>
	<marker entry="149"  eintrag="2009-10-10 16:35:52" />
	<marker entry="151"  eintrag="2009-10-10 16:35:52"/>
	<marker entry="152"  eintrag="2009-10-10 16:35:52"/>
	<marker entry="153"  eintrag="2009-10-10 16:35:52"/>
	<marker entry="154"  eintrag="2009-10-10 16:35:52"/>
</markers>';

$xml = simplexml_load_string($str);

for($i = 0; $i < 5; $i++)
{
	$attributes = $xml->marker[$i]->attributes();
	
	echo $attributes->entry.'<br/>';
}
?>
 
Hi!

Das Zauberwort heißt usort(). Ich glaube der einfachste Weg ist das gesamte Array $xml->marker zu durchlaufen und mal eben usort() 'drüber zu jagen, allerdings wirst Du die Funktion zum Vergleichen selber basteln müssen:
PHP:
<?php

$str = <<<EOT
<markers>
 <marker entry="149"  eintrag="2007-10-10 16:35:52"/>
 <marker entry="151"  eintrag="2009-10-10 16:35:00"/>
 <marker entry="152"  eintrag="2009-10-10 16:30:52"/>
 <marker entry="153"  eintrag="2003-11-10 15:35:52"/>
 <marker entry="154"  eintrag="2009-10-10 16:35:52"/>
 <marker entry="149"  eintrag="2007-10-10 16:35:52"/>
 <marker entry="151"  eintrag="2009-10-10 16:33:00"/>
 <marker entry="152"  eintrag="2007-10-10 16:30:52"/>
 <marker entry="153"  eintrag="2009-11-10 16:35:52"/>
 <marker entry="154"  eintrag="2004-10-10 16:35:52"/>
</markers>
EOT;

$xml = simplexml_load_string($str);

function sort_callback($a, $b)
{
    if($a->eintrag == $b->eintrag)
    {
        return 0;
    }

    $a = strtotime($a->eintrag);
    $b = strtotime($b->eintrag);

    return $a > $b? 1: -1;
}

for($i=count($xml->marker); $i;)
{
    $data[] = $xml->marker[--$i]->attributes();
}

unset($xml);
usort($data, sort_callback);

for($i=0; $i!=5; ++$i)
{
    echo $data[$i]->eintrag, ": ", $data[$i]->entry, "\n";
}

Ach ja, die Schleife in den Zeilen 33 bis 35 hat nicht nur den Zweck die Attribute schon vorher zu extrahieren (was einen Performance-Gewinn sein müsste), sondern auch ein Problem im SimpleXMLElement zu umgehen: Das Array $xml->marker würde von usort() zwar sortiert werden, allerdings wäre nach der Operation die Sortierung wieder verloren. Die Ursache kann man sich ausmalen...

Gruß
Enum

[EDIT]
Ok, usort() basiert nicht (mehr?) auf Quicksort.
 
Zuletzt bearbeitet:
Danke. Irgendwie klappt das mit folgendem XML nicht.


Code:
<markers>
<marker entry="149" eintrag="2009-10-10 16:35:52"  />
<marker entry="150" eintrag="2009-10-11 13:09:07"  />
<marker entry="151" eintrag="2009-10-11 13:35:02" />
<marker entry="152" eintrag="2009-10-13 20:01:50" />
<marker entry="153" eintrag="2009-10-21 15:50:59" />
<marker entry="154" eintrag="2009-10-21 15:53:39" />
<marker entry="155" eintrag="2009-10-21 16:01:23" />
<marker entry="156" eintrag="2009-10-21 16:10:30"/>
<marker entry="157" eintrag="2009-10-21 16:17:30"/>
<marker entry="158" eintrag="2009-10-21 16:18:30"/>
<marker entry="159" eintrag="2009-10-21 16:19:30"/>

</markers>
,

Er kommt dabei mit den gleichen tagen nicht klar. Hm..
 
Zuletzt bearbeitet:
Danke. Irgendwie klappt das mit folgendem XML nicht.


Code:
<markers>
<marker entry="149" eintrag="2009-10-10 16:35:52"  />
<marker entry="150" eintrag="2009-10-11 13:09:07"  />
<marker entry="151" eintrag="2009-10-11 13:35:02" />
<marker entry="152" eintrag="2009-10-13 20:01:50" />
<marker entry="153" eintrag="2009-10-21 15:50:59" />
<marker entry="154" eintrag="2009-10-21 15:53:39" />
<marker entry="155" eintrag="2009-10-21 16:01:23" />
<marker entry="156" eintrag="2009-10-21 16:10:30"/>
<marker entry="157" eintrag="2009-10-21 16:17:30"/>
<marker entry="158" eintrag="2009-10-21 16:18:30"/>
<marker entry="159" eintrag="2009-10-21 16:19:30"/>

</markers>
,

Er kommt dabei mit den gleichen tagen nicht klar. Hm..

Bei mir spuckt er da Folgendes aus:
Code:
2009-10-10 16:35:52: 149
2009-10-11 13:09:07: 150
2009-10-11 13:35:02: 151
2009-10-13 20:01:50: 152
2009-10-21 15:50:59: 153
Wenn ich nicht allzu müde bin, ist das doch vollkommen richtig, oder
Natürlich sind das die Ältesten Einträge. Um auf die jüngsten zu kommen, kannst Du entweder dir Rückgabewerte von sort_callback vertauschen oder $data von hinten an den Kragen gehen...

Gruß
Enum

PS:
Wenn das XML immer so aussieht wie oben, sprich wenn die jüngsten Einträge ganz unten und die ältesten ganz oben sind, würde ich auf eine Sortierung vollkommen verzichten und stattdessen mit dem XML-Baum arbeiten:
PHP:
$str = '<markers>
<marker entry="149" eintrag="2009-10-10 16:35:52"  />
<marker entry="150" eintrag="2009-10-11 13:09:07"  />
<marker entry="151" eintrag="2009-10-11 13:35:02" />
<marker entry="152" eintrag="2009-10-13 20:01:50" />
<marker entry="153" eintrag="2009-10-21 15:50:59" />
<marker entry="154" eintrag="2009-10-21 15:53:39" />
<marker entry="155" eintrag="2009-10-21 16:01:23" />
<marker entry="156" eintrag="2009-10-21 16:10:30"/>
<marker entry="157" eintrag="2009-10-21 16:17:30"/>
<marker entry="158" eintrag="2009-10-21 16:18:30"/>
<marker entry="159" eintrag="2009-10-21 16:19:30"/>
</markers>';

$xml = simplexml_load_string($str);

for($i=count($xml->marker), $j=$i-5; $j!=$i; --$i)
{
    $attributes = $xml->marker[$i]->attributes();
    echo $attributes->entry.'<br/>';
}
 
Zuletzt bearbeitet:
Zurück