所以我有一个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)。
抱歉英语不好,不是我的第一语言。
答案 0 :(得分:15)
为了将来参考,您可以使用以下方法通过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";
}
答案 1 :(得分:8)
这可以给你你想要的东西:
$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
现在按订单属性排序。
答案 2 :(得分: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;
}
}
答案 3 :(得分: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
)
)
)
)
答案 4 :(得分:-1)
This page提供了一些很好的例子,我可以使用
答案 5 :(得分:-1)
我使用PHP中的属性获得了xml排序的解决方案。
请访问以下网址: -
http://ewebsurf.blogspot.com/2010/12/xml-sorting-using-attributes-php.html