PHP:按多个元素对XML节点列表进行排序

Beginner programmer here.

I am in php, working with a dom document nodelist comprising of selected nodes retrieved from an XPath query on an xml file. Excerpt of contents of nodelist:

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

I wish to sort the nodelist by price ascending, and in the case of matching prices, by no of infants descending. In the above snippet, for example, the result would be:

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

I have seen some sorting questions answered relating to multi-dimensional arrays but I can't seem to translate these to nodelists. I can sort by price ok (see below), but I can't determine how to then sort by 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;
}

3个回答



如果你的代码价格合适,为什么不扩展呢?</ p>

   $ properties = iterator_to_array($ matches);  //其中matches =从XPath查询返回
nortort($ properties,'sortByPrice');

function sortByPrice($ a,$ b){
$ aPrice = $ a-&gt; getElementsByTagName(“price”) );
$ aPrice = $ aPrice-&gt; item(0) - &gt; nodeValue;
$ bPrice = $ b-&gt; getElementsByTagName(“price”);
$ bPrice = $ bPrice-&gt; item( 0) - &gt; nodeValue;
$ r =(int)$ aPrice - (int)$ bPrice;
if(!$ r){
$ ainfants = $ a-&gt; getElementsByTagName(“infants”);

$ ainfants = $ ainfants-&gt; item(0) - &gt; nodeValue;
$ binfants = $ b-&gt; getElementsByTagName(“infants”);
$ binfants = $ bPrice-&gt; item(0) - &gt; nodeValue;
$ r =(int)$ ainfants - (int)$ binfants;
}
返回$ r;
}
</ code> </ pre>
</ div>

展开原文

原文

if your code works ok for price, why not just extend it:

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

doulaozhang0238
doulaozhang0238 甚至本垒打有时点头:)
5 年多之前 回复
doupiao1893
doupiao1893 哦,傻我。 谢谢!
5 年多之前 回复

You can fetch scalar values depending on a context node with DOMXPath::evaluate(). number() will cast the first node in the location path result into a float. If no node was found the result is zero.

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



尝试此功能。 它充当 uasort </ code> PHP函数的泛化:</ p>

  function sortByKeyValue($ the_array,$ key)
{
$ cmp_val =“ ((\ $ a ['$ key']&gt; \ $ b ['$ key'])?1:
((\ $ a ['$ key'] == \ $ b ['$ key'] )?0:-1))“;
$ cmp = create_function('$ a,$ b',”return $ cmp_val;“);
uasort($ the_array,$ cmp);

返回$ the_array;
}
</ code> </ pre>

在您的情况下,您可以这样使用它:</ p>

  $ properties = iterator_to_array  ($ matches); 
sortByKeyValue($ properties,'price');
sortByKeyValue($ properties,'infants');
</ code> </ pre>

我希望它有所帮助。< / p>
</ div>

展开原文

原文

Try this function. It acts as a generalisation of the uasort PHP function:

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

In your case, you may use it thus:

$properties = iterator_to_array($matches);
sortByKeyValue($properties, 'price');
sortByKeyValue($properties, 'infants');

I hope it helps.

douhuang9886
douhuang9886 这是一个隐藏的eval()。 缓慢而危险。
5 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐