初学者程序员。
我在php中,使用dom文档节点列表,该节点列表包含从xml文件上的XPath查询中检索到的选定节点。节点列表的内容摘录:
<properties>
<property>
<price>270</price>
<address>3/2 Farran Street, Castlemaine, VIC, Australia</address>
<infants>3</infants>
</property>
<property>
<price>250</price>
<address>2/37 William Street, Castlemaine, VIC, Australia</address>
<infants>2</infants>
</property>
<property>
<price>250</price>
<address>2/37 William Street, Castlemaine, VIC, Australia</address>
<infants>3</infants>
</property>
...
我希望按price
升序对节点列表进行排序,如果匹配价格,则按infants
降序排序。例如,在上面的代码段中,结果将是:
<property>
<price>250</price>
<address>2/37 William Street, Castlemaine, VIC, Australia</address>
<infants>3</infants>
</property>
<property>
<price>250</price>
<address>2/37 William Street, Castlemaine, VIC, Australia</address>
<infants>2</infants>
</property>
<property>
<price>270</price>
<address>3/2 Farran Street, Castlemaine, VIC, Australia</address>
<infants>3</infants>
</property>
我已经看到一些与多维数组有关的排序问题,但我似乎无法将这些问题转换为节点列表。我可以按price
排序(见下文),但我无法确定如何按infants
排序。
$properties = iterator_to_array($matches); // where matches = a return from an XPath query
usort($properties, 'sortByPrice');
function sortByPrice ($a, $b) {
$aPrice = $a->getElementsByTagName("price");
$aPrice = $aPrice->item(0)->nodeValue;
$bPrice = $b->getElementsByTagName("price");
$bPrice = $bPrice->item(0)->nodeValue;
return (int) $aPrice - (int) $bPrice;
}
答案 0 :(得分:0)
如果您的代码适用于价格,为什么不直接扩展它:
$properties = iterator_to_array($matches); // where matches = a return from an XPath query
usort($properties, 'sortByPrice');
function sortByPrice ($a, $b) {
$aPrice = $a->getElementsByTagName("price");
$aPrice = $aPrice->item(0)->nodeValue;
$bPrice = $b->getElementsByTagName("price");
$bPrice = $bPrice->item(0)->nodeValue;
$r = (int) $aPrice - (int) $bPrice;
if (!$r) {
$ainfants = $a->getElementsByTagName("infants");
$ainfants = $ainfants->item(0)->nodeValue;
$binfants = $b->getElementsByTagName("infants");
$binfants = $bPrice->item(0)->nodeValue;
$r = (int) $ainfants - (int) $binfants;
}
return $r;
}
答案 1 :(得分:0)
您可以根据具有DOMXPath::evaluate()
的上下文节点来获取标量值。 number()
会将位置路径结果中的第一个节点强制转换为浮点数。如果没有找到节点,则结果为零。
$dom = new DOMDocument();
$dom->loadXml($xml);
$xpath = new DOMXPath($dom);
$properties = iterator_to_array($xpath->evaluate('//properties/property'));
usort(
$properties,
function(DOMElement $a, DOMElement $b) use ($xpath) {
$aPrice = (int)$xpath->evaluate('number(price)', $a);
$bPrice = (int)$xpath->evaluate('number(price)', $b);
if ($aPrice == $bPrice) {
$aInfants = (int)$xpath->evaluate('number(infants)', $a);
$bInfants = (int)$xpath->evaluate('number(infants)', $b);
return $bInfants - $aInfants;
}
return $aPrice - $bPrice;
}
);
答案 2 :(得分:-1)
试试这个功能。它充当uasort
PHP函数的推广:
function sortByKeyValue($the_array, $key)
{
$cmp_val="((\$a['$key']>\$b['$key'])?1:
((\$a['$key']==\$b['$key'])?0:-1))";
$cmp=create_function('$a, $b', "return $cmp_val;");
uasort($the_array, $cmp);
return $the_array;
}
在您的情况下,您可以这样使用它:
$properties = iterator_to_array($matches);
sortByKeyValue($properties, 'price');
sortByKeyValue($properties, 'infants');
我希望它有所帮助。