Поэтому у меня есть XML-файл, который я пытаюсь выполнить в порядке, в соответствии с атрибутом «order».
Вот пример:
<page> <talentTrees> <tree name="Football" order="2"> <tree name="Baseball" order="0"> <tree name="Frisbee" order="1"> </talentTrees> </page>
Моя цель – прокрутить каждое «дерево» с помощью foreach, но я хочу прочитать их в порядке атрибута заказа: Бейсбол, Фрисби, Футбол. (0,1,2).
Извините за плохой английский, не мой первый язык.
Это должно дать вам то, что вы хотите:
$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
теперь отсортированы по атрибуту order.
Для дальнейшего использования здесь вы можете использовать для запроса узлов через XPath и сортировать результат через XPath: SimpleDOM . В этом примере я сортирую все узлы <tree/>
по значениям атрибута 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"; }
Я написал рекурсивную расширенную версию, которая будет сортировать по любому количеству атрибутов, чтобы:
//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; } }
На этой странице приводятся некоторые прекрасные примеры, которые я хотел бы использовать
Я получил решение сортировки xml с использованием атрибутов в PHP.
Пожалуйста, посетите ниже URL:
http://ewebsurf.blogspot.com/2010/12/xml-sorting-using-attributes-php.html
Если у вас много таких элементов
$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); }
этот$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); }
не$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