通过属性值 PHP 对 XML 进行排序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1359224/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Sort XML via attribute value PHP
提问by ?ystein Riiser Gundersen
So I have an XML file that I am trying to loop through in order, according to the attribute, "order".
所以我有一个 XML 文件,我试图根据属性“order”按顺序循环。
Here is an example:
下面是一个例子:
<page>
<talentTrees>
<tree name="Football" order="2">
<tree name="Baseball" order="0">
<tree name="Frisbee" order="1">
</talentTrees>
</page>
My goal is to loop through each "tree" using foreach, but I want to read them in order of the order attribute: Baseball, Frisbee, Football. (0,1,2).
我的目标是使用 foreach 遍历每个“树”,但我想按照 order 属性的顺序阅读它们:棒球、飞盘、足球。(0,1,2)。
Sorry for poor English, not my first language.
对不起,英语不好,不是我的母语。
回答by Josh Davis
For future reference, here's something you can use to query nodes via XPath and sort the result via XPath as well: SimpleDOM. In this example, I sort all <tree/>nodes by values of the orderattribute:
为了将来参考,您可以使用以下内容通过 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";
}
回答by ?ystein Riiser Gundersen
This should give you what you want:
这应该给你你想要的:
$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);
$treesare now sorted by the order attribute.
$trees现在按订单属性排序。
回答by jcampbell
I wrote a recursive, expanded version that will sort by any number of attributes, in order:
我写了一个递归的扩展版本,它将按任意数量的属性排序:
//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;
}
}
回答by user3506219
If you have many elements like this
如果你有很多这样的元素
$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;
You can use foreach:
您可以使用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);
}
output:
输出:
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
)
)
)
)
For another example: https://stackoverflow.com/a/44379495/3506219
回答by user328895
I got the solution of xml sorting using attributes in PHP.
我得到了使用 PHP 中的属性进行 xml 排序的解决方案。
Please visit Below URL:-
请访问以下网址:-
http://ewebsurf.blogspot.com/2010/12/xml-sorting-using-attributes-php.html
http://ewebsurf.blogspot.com/2010/12/xml-sorting-using-attributes-php.html

