2009-08-31 1 views
5

Also habe ich eine XML-Datei, die ich versuche, in der Reihenfolge zu durchlaufen, nach dem Attribut "Reihenfolge". HierXML über Attributwert sortieren PHP

ein Beispiel:

<page> 
<talentTrees> 
<tree name="Football" order="2"> 
<tree name="Baseball" order="0"> 
<tree name="Frisbee" order="1"> 
</talentTrees> 
</page> 

Mein Ziel in einer Schleife durch die einzelnen „Baum“ ist mit foreach, aber ich möchte, dass sie in der Reihenfolge der Bestellung Attribut lesen: Baseball, Frisbee, Fußball. (0,1,2).

Entschuldigung für schlechtes Englisch, nicht meine erste Sprache.

Antwort

6

verwenden könnte Dies sollte Sie geben, was Sie wollen:

$string = <<<EOS 
<page> 
<talentTrees> 
<tree name="Football" order="2" /> 
<tree name="Baseball" order="0" /> 
<tree name="Frisbee" order="1" /> 
</talentTrees> 
</page> 
EOS; 

$xml = simplexml_load_string($string); 

$trees = $xml->xpath('/page/talentTrees/tree'); 
function sort_trees($t1, $t2) { 
    return strcmp($t1['order'], $t2['order']); 
} 

usort($trees, 'sort_trees'); 
var_dump($trees); 

$trees jetzt durch die Reihenfolge Attribut sortiert werden.

+1

Dies schlägt fehl, wenn Zahlen sind größer als 9. Es ist wie diese Art wird: 1, 100, 2, 245, 300, 4. Anstelle von 1, 2, 4, 100, 245, 300. Verwenden Sie Josh Davis 'Vorschlag unten. Es läuft gut. – matthoiland

0

This page gibt einige gute Beispiele, die ich dünn, dass man

1

ich eine rekursive, erweiterte Version geschrieben, die durch eine beliebige Anzahl von Attributen, um sortieren wird:

//sort_xml_by_attr($simplexmlobject,array('attr_one','attr_two','attr_three')) 

    class SortXML { 
    public $xml; 
    var $attr; 
    function SortXML($xml,$attr) { 
     $this->xml = $xml; 
     $this->attr = $attr; 
    } 
    function cmp_attr($a,$b) { 
     $a1 = (string)$a->xml[(string)$a->attr]; 
     $b1 = (string)$b->xml[(string)$b->attr]; 
     if (is_numeric($a1) && is_numeric($b1)) { 
     if (is_float($a1) && is_float($b1)) { 
      $a1 = (float)$a1; 
      $b1 = (float)$b1; 
     } else { 
      $a1 = (int)$a1; 
      $b1 = (int)$b1; 
     } 
     } 
     if ($a1 == $b1) return 0; 
     return ($a1 > $b1) ? +1 : -1; 
    } 
    } 

    function sort_xml_by_attr($xml_obj,$attr) { 
    if (count($attr)>1) { 
     // break up array by unique values of the first attribute in the list 
     $unique_attrs = array(); 
     foreach ($xml_obj as $i) $unique_attrs[] = (string)$i[$attr[0]]; 
     $unique_attrs = array_unique($unique_attrs); 
     sort($unique_attrs); 
     // create an array of arrays who share a unique attribute value 
     foreach ($unique_attrs as $i) { 
     foreach ($xml_obj as $p) { 
      if ($p[$attr[0]] == $i) $xml_arrays[$i][] = $p; 
     } 
     } 
     // remove first element to progress the recursion to the next attribute 
     array_shift($attr); 
     $new_array = array(); 
     // concatenate sorted arrays 
     foreach ($xml_arrays as $i) { 
     $new_array = array_merge($new_array,sort_xml_by_attr($i,$attr)); 
     } 
     return $new_array; 
    } else { 
     // create wrapper objects with new comparison function 
     foreach ($xml_obj as $i) $new_obj[] = new SortXML($i,$attr[0]); 
     usort($new_obj,array('SortXML','cmp_attr')); 
     foreach ($new_obj as $i) $sorted_obj[] = $i->xml; 
     return $sorted_obj; 
    } 
    } 
15

Für die Zukunft, hier ist etwas, das Sie Knoten über XPath verwenden können und das Ergebnis über XPath sortieren abfragen außerdem: SimpleDOM. In diesem Beispiel habe ich sortieren alle <tree/> Knoten, die durch Werte des order Attribut:

include 'SimpleDOM.php'; 

$page = simpledom_load_string('<page> 
    <talentTrees> 
     <tree name="Football" order="2"/> 
     <tree name="Baseball" order="0"/> 
     <tree name="Frisbee" order="1"/> 
    </talentTrees> 
</page>'); 

$nodes = $page->sortedXPath('//tree', '@order'); 

foreach ($nodes as $node) 
{ 
    echo $node->asXML(), "\n"; 
} 
+0

Das funktioniert super. Ich musste mir eine Weile Zeit nehmen, um zu erkennen, dass SimpleDOM als Include heruntergeladen werden muss. – Aaron

+0

Ich schließe SimpleDom.php ein, aber das System erkennt immer noch nicht die sortedXPath-Methode, warum? – budamivardi

+0

@budamivardi Sie müssen simplexml_load_string anstelle von simplestom_load_string oder simplexml_load_file anstelle von simpledom_load_file verwenden –

0

Wenn Sie diese viele Elemente wie haben

$string = <<<EOS 
<page> 
<talentTrees> 
<tree name="Football" order="2" /> 
<tree name="Baseball" order="0" /> 
<tree name="Frisbee" order="1" /> 
</talentTrees> 
<talentTrees> 
<tree name="Football2" order="1" /> 
<tree name="Baseball2" order="2" /> 
<tree name="Frisbee2" order="0" /> 
</talentTrees> 
</page> 
EOS; 

Sie foreach verwenden können:

$xml = simplexml_load_string($string); 

function sort_trees($t1, $t2) { 
    return $t1['order'] - $t2['order']; 
} 

foreach($xml->talentTrees as $talentTrees){ 
    foreach($talentTrees->tree as $tree){ 
    $trees[]= $tree; 
    } 
    usort($trees, 'sort_trees'); 
    print_r($trees); 
    unset($trees); 
} 

Ausgabe:

Array 
(
    [0] => Array 
     (
      [0] => SimpleXMLElement Object 
       (
        [@attributes] => Array 
         (
          [name] => Baseball 
          [order] => 0 
         ) 

       ) 

      [1] => SimpleXMLElement Object 
       (
        [@attributes] => Array 
         (
          [name] => Frisbee 
          [order] => 1 
         ) 

       ) 

      [2] => SimpleXMLElement Object 
       (
        [@attributes] => Array 
         (
          [name] => Football 
          [order] => 2 
         ) 

       ) 

     ) 

    [1] => Array 
     (
      [0] => SimpleXMLElement Object 
       (
        [@attributes] => Array 
         (
          [name] => Frisbee2 
          [order] => 0 
         ) 

       ) 

      [1] => SimpleXMLElement Object 
       (
        [@attributes] => Array 
         (
          [name] => Football2 
          [order] => 1 
         ) 

       ) 

      [2] => SimpleXMLElement Object 
       (
        [@attributes] => Array 
         (
          [name] => Baseball2 
          [order] => 2 
         ) 

       ) 

     ) 

) 

Für ein anderes Beispiel: https://stackoverflow.com/a/44379495/3506219