2009-08-31 46 views
5

Vì vậy, tôi có một tệp XML mà tôi đang cố gắng lặp lại theo thứ tự, theo thuộc tính, "thứ tự".Sắp xếp XML qua giá trị thuộc tính PHP

Dưới đây là một ví dụ:

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

Mục tiêu của tôi là để lặp qua mỗi "cây" sử dụng foreach, nhưng tôi muốn đọc chúng theo thứ tự của thuộc tính theo thứ tự: Bóng chày, dĩa nhựa, Bóng đá. (0,1,2).

Xin lỗi vì tiếng Anh kém, không phải ngôn ngữ đầu tiên của tôi.

Trả lời

6

này sẽ cho bạn những gì bạn muốn:

$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 hiện đang được sắp xếp theo thứ tự các thuộc tính.

+1

này thất bại khi con số này lớn hơn 9. Nó sẽ sắp xếp như thế này: 1, 100, 2, 245, 300, 4. Thay vì 1, 2, 4, 100, 245, 300. Sử dụng gợi ý của Josh Davis bên dưới. Nó hoạt động tốt. – matthoiland

0

This page đưa ra một số ví dụ tuyệt vời mà tôi mỏng bạn có thể sử dụng

1

Tôi đã viết một phiên bản đệ quy, mở rộng đó sẽ sắp xếp theo bất kỳ số lượng các thuộc tính, theo thứ tự:

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

Để tham khảo trong tương lai, đây là một cái gì đó bạn có thể sử dụng để truy vấn các nút thông qua XPath và sắp xếp các kết quả thông qua XPath cũng như: SimpleDOM. Trong ví dụ này, tôi sắp xếp tất cả <tree/> nút bởi các giá trị của thuộc tính order:

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

Công trình này tuyệt vời. Tôi đã phải nhìn vào điều này một lúc để nhận ra rằng SimpleDOM cần phải được tải xuống như là một bao gồm. – Aaron

+0

Tôi bao gồm SimpleDom.php nhưng hệ thống vẫn không nhận ra phương thức sortXPath, tại sao? – budamivardi

+0

@budamivardi bạn phải sử dụng simplexml_load_string thay vì simpledom_load_string hoặc simplexml_load_file thay vì simpledom_load_file –

0

Nếu bạn có nhiều yếu tố như thế này

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

Bạn có thể sử dụng 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); 
} 

đầu ra:

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 
         ) 

       ) 

     ) 

) 

Ví dụ khác: https://stackoverflow.com/a/44379495/3506219

Các vấn đề liên quan