这是非常令人沮丧的工作了一整天
我正在尝试用从最低到最高的价格对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值,您可能不想在自己的代码中这样做。)