Sorting LowToHigh PHP/XML/Javascript



这是非常令人沮丧的工作了一整天
我正在尝试用从最低到最高的价格对XML文档进行排序。
使用PHP。
XML数据仅使用伦敦金融城,仅供参考
并且我不希望将价格按降序放在XML上,因为我希望操作的信息不会被静态添加。

首先是代码

var xHRObject = false;
if (window.XMLHttpRequest)
    xHRObject = new XMLHttpRequest();
else if (window.ActiveXObject)
    xHRObject = new ActiveXObject("Microsoft.XMLHTTP");
function retrieveInformation() 
{
    var city = document.getElementById("selectCity").value;
    var type = "";
    var input = document.getElementsByTagName("input");
    for (var i=0; i < input.length; i++)
    { 
        if (input.item(i).checked == true)
            type = input.item(i).value;
    }
      xHRObject.open("GET", "retrieveHotelInfo.php?id=" + Number(new Date) +"&city=" + city + "&type=" + type, true);
      xHRObject.onreadystatechange = function() {
           if (xHRObject.readyState == 4 && xHRObject.status == 200)
               document.getElementById('information').innerHTML = xHRObject.responseText;
      }
      xHRObject.send(); 
}

-

<html>
<head>
<script type="text/javascript" src="retrieveHotelInfo.js"></script> 
</head> 
<body>
Destination:
<br /> 
<select id="selectCity" onchange="retrieveInformation()">
    <option value="London" selected="true">London</option>
    <option value="Paris">Paris</option>
    <option value="New York">New York</option>
    <option value="Chicago">Chicago</option>
    <option value="Seattle">Seattle</option>
</select>
<br />
<br />
Price Range:
<br />
Budget<input name="range" value="Budget" type="radio"  onclick="retrieveInformation()"/>
Standard<input name="range" value="Standard" type="radio" onclick="retrieveInformation()" checked="true"/>
Luxury<input  name="range" value="Luxury" type="radio"  onclick="retrieveInformation()"/>
<div id="information">
</div>
</body>
</html>

-

<?php
 $xmlFile = "hotel.xml";
 $HTML = "";
 $count = 0;
 $dt = simplexml_load_file($xmlFile);
 $dom = DOMDocument::load($xmlFile);
 $hotel = $dom->getElementsByTagName("hotel"); 
 foreach($hotel as $node) 
 { 
 $city = $node->getElementsByTagName("City");
 $city = $city->item(0)->nodeValue;
 $type = $node->getElementsByTagName("Type");
 $type = $type->item(0)->nodeValue;
 $name = $node->getElementsByTagName("Name");
 $name = $name->item(0)->nodeValue;
 $price = $node->getElementsByTagName("Price");
 $price = $price->item(0)->nodeValue;
if (($type == $_GET["type"]) && ($city == $_GET["city"]) )
{
    $HTML = $HTML."<br><span>Hotel: ".$name."</span><br><span>Price: ".$price."</span><br>";
    $count++;
  }
  } 
  if ($count ==0)
 {
  $HTML ="<br><span>No hotels available</span>";
 }
 echo $HTML;   
 ?>

如果需要,xml文档就像这个一样编写

        <?xml version="1.0"?>
    <hotels>
    <hotel>
        <City>London</City>
        <Name>The Rilton</Name>
        <Type>Luxury</Type>
        <Price>300</Price>
    </hotel>
    <hotel>
        <City>London</City>
        <Name>The Rilton</Name>
        <Type>Budget</Type>
        <Price>150</Price>
    </hotel>
    <hotel>
        <City>London</City>
        <Name>The Rilton</Name>
        <Type>Standard</Type>
        <Price>250</Price>
    </hotel>
    <hotel>
        <City>London</City>
        <Name>The Lolipop</Name>
        <Type>Standard</Type>
        <Price>280</Price>
    </hotel>
    <hotel>
        <City>London</City>
        <Name>The non-Rilton</Name>
        <Type>Standard</Type>
        <Price>225</Price>
    </hotel>
    </hotels>

这里有一个灵活的函数,您可以使用它按任何标准进行排序。我还重写了XML解析,因为您的解析效率很低。

我已经使用DOMXPath从您的XML文档中提取数据;这是一种很有用的方法,可以提取出一组符合特定标准的节点,而无需对它们进行迭代。

排序本身是用usort完成的,它允许您定义一个回调来对数组项进行排序。

# this is the sort function; it takes two arguments, the aspect to sort on, and
# 'asc' or 'desc', depending on whether you want your sort ascending or descending
# the default is ascending
function sort_by( $aspect, $dir ){
    return function ($a, $b) use ($aspect, $dir) {
        if ($a[$aspect] == $b[$aspect]) {
            return 0;
        }
        if ($dir === 'asc') {
            return ($a[$aspect] > $b[$aspect]) ? +1 : -1;
        }
        else {
            return ($a[$aspect] > $b[$aspect]) ? -1 : +1;
        }
    };
}
$dom = new DOMDocument;
$dom->loadXML($xmlFile);
# if you want to search for nodes in an XML document that meet certain criteria,
# there's a handy W3C standard for doing so; it's called XPath, and PHP has an
# interface for it in DOMXPath
$xp = new DOMXPath($dom);
# this is our "base" node
$hnode = $dom->getElementsByTagName("hotels")->item(0);
# get the data that we're searching for from $_GET:
# (you may want to do a little sanitising of these variables first...)
$city = $_GET['city'];
$type = $_GET['type'];
# set up the xpath query to search for hotels with City == $city and Type == $type
# our "base node" is <hotels>, and this query can be translated as "find all the
# direct children of <hotels> that have the tag <hotel> and the children of that
# <hotel> node include <City> with value $city and <Type> with value $type
$results = $xp->query('hotel[ City = $city and Type = $type ]', $hnode);
# check whether we have any results
if ($results->length === 0) {
    echo "<p>No hotels found.</p>n";
}
else {
# we found hotels!!
    echo "<p>Found " . $results->length . " matching hotels</p>n";
    # since we are doing the same operation on each XML node, we can condense the code
    # we create an associative array, $hotel, with the hotel properties and the values.
    # that then gets pushed on to an array, $h_data
    $attrs = array('City', 'Type', 'Name', 'Price');
    $h_data = array();
    foreach($results as $h)
    {   $hotel = array();
        foreach ($attrs as $a) {
            $hotel[$a] = $h->getElementsByTagName($a)->item(0)->nodeValue;
        }
        # push the associative array on to $h_data
        $h_data[] = $hotel;
    }
    # Here is the sort criteria. You could get/set this from the page -- e.g.
    # set up $_GET['sort_by'] and $_GET['sort_dir'] if you wanted
    $aspect = 'Price';
    $dir = 'desc'; # or 'desc' for descending
    # check that the aspect is valid -- it should be in the set of $attrs above
    if (! in_array($aspect, $attrs)) {
        $aspect = 'Price';
    }
    # set the search direction to 'asc' unless it is the recognised value 'desc'
    if ($dir !== 'asc' && $dir !== 'desc') {
        $dir = 'asc';
    }
    # pass it to the sorting function...
    usort($h_data, sort_by($aspect, $dir) );
    $html = '';
    # now create our output
    foreach ($h_data as $h) {
        $html .= "<p>" . $h['Name'] ."<br>". $h['Price'] ."<br>". $h['Type'] . "</p>n";
    }
    echo $html;
}

可能不是最高效的,因为它会在酒店列表上循环两次,但这里有一个eval.in,它会按照您的意愿进行排序。请注意,我在脚本顶部设置了$_GET值,您可能不想在自己的代码中这样做。)

最新更新