2009-08-31 14 views
5

属性に応じて、順番にループするXMLファイルがあります。ここで属性値を使用してXMLをソートするPHP

は一例です:

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

私の目標は、foreachのを使用して、各「木」をループしているが、私は順序属性の順序でそれらを読みたい:野球、フリスビー、サッカー。 (0,1,2)。

私の母国語ではなく、英語が貧弱なため申し訳ありません。

答えて

6

を使用することができますいくつかの素晴らしい例を示します:

$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を今順序属性によってソートされています。

+1

:1、100 2、245、300、4の代わりに1、2、4、100、下記のJosh Davisの提案を使用してください。それはうまくいく。 – matthoiland

0

This pageは、私は薄いあなたはこれが何をしたいあなたを与える必要があります

1

私は順番に、任意の数の属性でソートされます再帰的な、拡張バージョン書いた:将来の参考のために

//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

を、ここであなたは、XPathを経由して、ノードを照会およびXPathを経由して、結果をソートするために使用することができます何か同様に:SimpleDOM。この例では、私は一種のすべてorder属性の値によって<tree/>ノード:

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

これは素晴らしいです。 SimpleDOMをインクルードとしてダウンロードする必要があることを理解するには、これをしばらく見なければなりませんでした。 – Aaron

+0

私はSimpleDom.phpをインクルードしますが、システムはまだsortedXPathメソッドを実装していません。なぜですか? – budamivardi

+0

@budamivardi simpleedom_load_stringの代わりにsimplexml_load_stringを使用する必要があります。またはsimpledom_load_fileの代わりにsimplexml_load_fileを使用する必要があります。 –

0

あなたはこのような多くの要素

$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; 

を持っている場合あなたがforeachを使用することができます。

$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); 
} 

出力:

別の例として
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 
         ) 

       ) 

     ) 

) 

https://stackoverflow.com/a/44379495/3506219この数字は9よりも大きい場合にはこのようにソートされます失敗

関連する問題