camargo Posted August 27, 2007 Share Posted August 27, 2007 Hello fellow PHP Freaks, I'm new here, and this is my very first post! So hello to you all! Here's my situation: I'm in the process of creating a page that displays multiple lines of inventory for a bunch of products (let's call them 'widgets'). The widgets are listed in XML format (they'll end up being pulled from a MySQL DB eventually). <inventory> <widget> <name>One</name> <color>Red</color> <weight>5</weight> <price>15</price> </widget> <widget> <name>Two</name> <color>Blue</color> <weight>8</weight> <price>21</price> </widget> <widget> <name>Three</name> <color>Green</color> <weight>3</weight> <price>12</price> </widget> <widget> <name>Four</name> <color>Red</color> <weight>15</weight> <price>35</price> </widget> </inventory> Now, I have a PHP page that loads up my XML file using SimpleXML: <?php $xml = simplexml_load_file('inventory.xml'); ?> Then it will display information for each widget in a nice, neat format: <?php foreach ($xml->widget as $widget) { echo "<div class='widget'>"; echo "<span class='name'>" . $widget->name . "</span>"; echo "<span class='color'>" . $widget->color . "</span>"; echo "<span class='weight'>" . $widget->weight . "</span>"; echo "<span class='price'>" . $widget->price . "</span>"; echo "</div>"; } ?> My question to you is, how would I go about building a function that would filter the results to this page. For instance if there was a set of check-boxes that allowed you to only display the "Red" or "Blue" colored widgets. Or perhaps I only want to see "Red" widgets with a price below "20". Any help or pointers are completely appreciated. Thanks in advance! Quote Link to comment https://forums.phpfreaks.com/topic/66919-filtering-xml-results-in-php/ Share on other sites More sharing options...
Barand Posted August 27, 2007 Share Posted August 27, 2007 Something like <?php $str = '<inventory> <widget> <name>One</name> <color>Red</color> <weight>5</weight> <price>15</price> </widget> <widget> <name>Two</name> <color>Blue</color> <weight>8</weight> <price>21</price> </widget> <widget> <name>Three</name> <color>Green</color> <weight>3</weight> <price>12</price> </widget> <widget> <name>Four</name> <color>Red</color> <weight>15</weight> <price>35</price> </widget> </inventory>'; function xmlfilter ($x, $color, $weight, $maxprice) { $xml = simplexml_load_string($x); $res = array(); foreach ($xml->widget as $w) { $keep = 1; if ($color!='') { if ((string)$w->color != $color) $keep = 0; } if ($weight) { if ((int)$w->weight > $weight) $keep = 0; } if ($price) { if ((int)$w->price > $maxprice) $keep = 0; } if ($keep) $res[] = $w; } return $res; } $filtered = xmlfilter($str,'Red','',20); echo '<pre>', print_r($filtered, true), '</pre>'; ?> Quote Link to comment https://forums.phpfreaks.com/topic/66919-filtering-xml-results-in-php/#findComment-335562 Share on other sites More sharing options...
camargo Posted August 27, 2007 Author Share Posted August 27, 2007 Hi Barand, Thanks for your quick response. As I look through the code you've written though, I seem to be clueless as to the execution of it. Perhaps I'm less advanced than I made myself out to be. I'm also having a hard time understanding the logic in the function. I'd hate to have you spell it out for me, but I think, in this case... I might need it. Quote Link to comment https://forums.phpfreaks.com/topic/66919-filtering-xml-results-in-php/#findComment-335708 Share on other sites More sharing options...
Barand Posted August 27, 2007 Share Posted August 27, 2007 Loop through the widgets. for each widget, assume we keep it ($keep=1) Now check if we are filtering by color (if $color != '' then we are) If it's not the color we want then set keep to 0 Similarly with the other attributes. If $keep is still 1 after the checks, add the widget to the results array Quote Link to comment https://forums.phpfreaks.com/topic/66919-filtering-xml-results-in-php/#findComment-335734 Share on other sites More sharing options...
camargo Posted August 27, 2007 Author Share Posted August 27, 2007 Okay, I'm understanding the logic behind the function. Now how do I get the arguments from a form on the page? I see that the arguments here are already populated. I'm just not familiar with the process of taking a form's values and having PHP use them as arguments. Quote Link to comment https://forums.phpfreaks.com/topic/66919-filtering-xml-results-in-php/#findComment-335738 Share on other sites More sharing options...
Barand Posted August 27, 2007 Share Posted August 27, 2007 <?php $str = '<inventory> <widget> <name>One</name> <color>Red</color> <weight>5</weight> <price>15</price> </widget> <widget> <name>Two</name> <color>Blue</color> <weight>8</weight> <price>21</price> </widget> <widget> <name>Three</name> <color>Green</color> <weight>3</weight> <price>12</price> </widget> <widget> <name>Four</name> <color>Red</color> <weight>15</weight> <price>35</price> </widget> </inventory>'; function xmlfilter ($x, $color, $weight, $maxprice) { $xml = simplexml_load_string($x); $res = array(); foreach ($xml->widget as $w) { $keep = 1; if ($color!='') { if ((string)$w->color != $color) $keep = 0; } if ($weight) { if ((int)$w->weight > $weight) $keep = 0; } if ($maxprice) { if ((int)$w->price > $maxprice) $keep = 0; } if ($keep) $res[] = $w; } return $res; } if (isset($_GET['sub'])) { $color = isset($_GET['color'])? $_GET['color'] : ''; $weight = $_GET['weight']; $price = $_GET['price']; $filtered = xmlfilter($str,$color, $weight, $price); echo '<pre>', print_r($filtered, true), '</pre>'; } ?> <form> Select color <input type="radio" name="color" value="Red"> Red <input type="radio" name="color" value="Green"> Green <input type="radio" name="color" value="Blue"> Blue <br/> Max weight <input type="text" name="weight" size="5"><br/> Max Price <input type="text" name="price" size="5"><br/> <input type="submit" name="sub" value="Submit"> </form> Quote Link to comment https://forums.phpfreaks.com/topic/66919-filtering-xml-results-in-php/#findComment-335752 Share on other sites More sharing options...
camargo Posted August 27, 2007 Author Share Posted August 27, 2007 I see! Barand you are extremely helpful! Now at the top of that script, you're defining $str as the full content of the XML file. What if I was to do: $str = simplexml_load_file('inventory.xml'); Will this achieve the same effect? Quote Link to comment https://forums.phpfreaks.com/topic/66919-filtering-xml-results-in-php/#findComment-335758 Share on other sites More sharing options...
Barand Posted August 27, 2007 Share Posted August 27, 2007 Alter slightly to read file <?php function xmlfilter ($xml, $color, $weight, $maxprice) { $res = array(); foreach ($xml->widget as $w) { $keep = 1; if ($color!='') { if ((string)$w->color != $color) $keep = 0; } if ($weight) { if ((int)$w->weight > $weight) $keep = 0; } if ($maxprice) { if ((int)$w->price > $maxprice) $keep = 0; } if ($keep) $res[] = $w; } return $res; } if (isset($_GET['sub'])) { $color = isset($_GET['color'])? $_GET['color'] : ''; $weight = $_GET['weight']; $price = $_GET['price']; $xml = simplexml_load_file('inventory.xml'); // read xml file $filtered = xmlfilter($xml ,$color, $weight, $price); // pass xml echo '<pre>', print_r($filtered, true), '</pre>'; } ?> <form> Select color <input type="radio" name="color" value="Red"> Red <input type="radio" name="color" value="Green"> Green <input type="radio" name="color" value="Blue"> Blue <br/> Max weight <input type="text" name="weight" size="5"><br/> Max Price <input type="text" name="price" size="5"><br/> <input type="submit" name="sub" value="Submit"> </form> Quote Link to comment https://forums.phpfreaks.com/topic/66919-filtering-xml-results-in-php/#findComment-335767 Share on other sites More sharing options...
camargo Posted August 28, 2007 Author Share Posted August 28, 2007 Okay, so I'm 90% there. I've got all my variables setup and I can see how the form functions with the PHP. I've even been able to add filters of my own. But how do I get the data out of the filtered array without using print_r? For instance, before I was able to do the following: <?php foreach ($xml->widget as $widget) { echo "<div class='widget'>"; echo "<span class='name'>" . $widget->name . "</span>"; echo "<span class='color'>" . $widget->color . "</span>"; echo "<span class='weight'>" . $widget->weight . "</span>"; echo "<span class='price'>" . $widget->price . "</span>"; echo "</div>"; } ?> Quote Link to comment https://forums.phpfreaks.com/topic/66919-filtering-xml-results-in-php/#findComment-335793 Share on other sites More sharing options...
Barand Posted August 28, 2007 Share Posted August 28, 2007 replace the print_r bit with foreach ($filtered as $widget) { echo "<div class='widget'>"; echo "<span class='name'>" . $widget->name . "</span>"; echo "<span class='color'>" . $widget->color . "</span>"; echo "<span class='weight'>" . $widget->weight . "</span>"; echo "<span class='price'>" . $widget->price . "</span>"; echo "</div>"; } Quote Link to comment https://forums.phpfreaks.com/topic/66919-filtering-xml-results-in-php/#findComment-335797 Share on other sites More sharing options...
camargo Posted August 28, 2007 Author Share Posted August 28, 2007 Wow, okay. I was closer than I thought there! Thanks! Now then, is there any way to perform this function without actually refreshing the page. Perhaps using XMLHttpRequest (AJAX)? Quote Link to comment https://forums.phpfreaks.com/topic/66919-filtering-xml-results-in-php/#findComment-335813 Share on other sites More sharing options...
Barand Posted August 28, 2007 Share Posted August 28, 2007 See my sig Quote Link to comment https://forums.phpfreaks.com/topic/66919-filtering-xml-results-in-php/#findComment-335853 Share on other sites More sharing options...
camargo Posted August 28, 2007 Author Share Posted August 28, 2007 Hey Barand! Let me show you what I was able to decypher. It ain't working yet, but perhaps you'll be able to tell me why. I've gone ahead and written up a JS file: var xmlHttp function updateColor(str) { xmlHttp=GetXmlHttpObject() if (xmlHttp==null) { alert ("Browser does not support HTTP Request") return } var url="ajaxFilter.php" url=url+"?color="+str xmlHttp.onreadystatechange=stateChanged xmlHttp.open("GET",url,true) xmlHttp.send(null) } function stateChanged() { if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete") { document.getElementById("results").innerHTML=xmlHttp.responseText } } function GetXmlHttpObject() { var xmlHttp=null; try { // Firefox, Opera 8.0+, Safari xmlHttp=new XMLHttpRequest(); } catch (e) { // Internet Explorer try { xmlHttp=new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { xmlHttp=new ActiveXObject("Microsoft.XMLHTTP"); } } return xmlHttp; } Here's is the form that now calls the function when it changes (only focusing on color for now)... <form> Select color <select name="color" onchange="updateColor(this.value)"> <option value="red">Red</option> <option value="blue">Blue</option> <option value="green">Green</option> </select> </form> <div id="results"> </div> Plus you can see the new <div> above which has been added to receive the results of the request. And finally the PHP script: <?php $xml = simplexml_load_file('inventory.xml'); function xmlfilter ($xml, $color) { $res = array(); foreach ($xml->widget as $w) { $keep = 1; if ($color!='') { if ((string)$w->color != $color) $keep = 0; } if ($keep) $res[] = $v; } return $res; $color = isset($_GET['color'])? $_GET['color'] : ''; $filtered = xmlfilter($xml ,$color); foreach ($filtered as $widget) { echo "<div class='widget'>"; echo "<span class='name'>" . $widget->name . "</span>"; echo "<span class='color'>" . $widget->color . "</span>"; echo "<span class='weight'>" . $widget->weight . "</span>"; echo "<span class='price'>" . $widget->price . "</span>"; echo "</div>"; } } ?> However, I no longer get any results from the PHP code. Did I hack it to pieces or remove something I shouldn't have? Quote Link to comment https://forums.phpfreaks.com/topic/66919-filtering-xml-results-in-php/#findComment-336348 Share on other sites More sharing options...
Barand Posted August 28, 2007 Share Posted August 28, 2007 Where do you update the div.innerHTML? Quote Link to comment https://forums.phpfreaks.com/topic/66919-filtering-xml-results-in-php/#findComment-336446 Share on other sites More sharing options...
camargo Posted August 28, 2007 Author Share Posted August 28, 2007 Its located in the JS file under function stateChanged(): var xmlHttp function updateColor(str) { xmlHttp=GetXmlHttpObject() if (xmlHttp==null) { alert ("Browser does not support HTTP Request") return } var url="ajaxFilter.php" url=url+"?color="+str xmlHttp.onreadystatechange=stateChanged xmlHttp.open("GET",url,true) xmlHttp.send(null) } function stateChanged() { if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete") { document.getElementById("results").innerHTML=xmlHttp.responseText } } function GetXmlHttpObject() { var xmlHttp=null; try { // Firefox, Opera 8.0+, Safari xmlHttp=new XMLHttpRequest(); } catch (e) { // Internet Explorer try { xmlHttp=new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { xmlHttp=new ActiveXObject("Microsoft.XMLHTTP"); } } return xmlHttp; } Quote Link to comment https://forums.phpfreaks.com/topic/66919-filtering-xml-results-in-php/#findComment-336455 Share on other sites More sharing options...
camargo Posted August 28, 2007 Author Share Posted August 28, 2007 I think something may be wrong with the PHP file, however. If I go directly to it and inject the string myself (ex: ajaxFilter.php?color=red), it won't actually display anything. Quote Link to comment https://forums.phpfreaks.com/topic/66919-filtering-xml-results-in-php/#findComment-336457 Share on other sites More sharing options...
Barand Posted August 28, 2007 Share Posted August 28, 2007 this code needs to be outside the function $filtered = xmlfilter($xml ,$color); // <------------- calls the function xmlfilter foreach ($filtered as $widget) { echo "<div class='widget'>"; echo "<span class='name'>" . $widget->name . "</span>"; echo "<span class='color'>" . $widget->color . "</span>"; echo "<span class='weight'>" . $widget->weight . "</span>"; echo "<span class='price'>" . $widget->price . "</span>"; echo "</div>"; } Quote Link to comment https://forums.phpfreaks.com/topic/66919-filtering-xml-results-in-php/#findComment-336521 Share on other sites More sharing options...
Barand Posted August 28, 2007 Share Posted August 28, 2007 Also the line that gets the GET data needs to be outside too Quote Link to comment https://forums.phpfreaks.com/topic/66919-filtering-xml-results-in-php/#findComment-336526 Share on other sites More sharing options...
camargo Posted August 28, 2007 Author Share Posted August 28, 2007 Hah! I just caught that. Quote Link to comment https://forums.phpfreaks.com/topic/66919-filtering-xml-results-in-php/#findComment-336539 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.