Reputation: 355
I have a xml file in this format:
<?xml version="1.0" encoding="ISO-8859-1"?>
<adp_report name="Average Draft Position - Mixed 5x5" rundate="2013-01-29 17:22:10.0" begin="2013-01-26" end="2013-01-29" draftcount="126">
<player id="500736" name="Mike Trout" position="OF" team="ANA" adp="1.66" early="1" late="4" selections="126" />
<player id="291154" name="Ryan Braun" position="OF" team="MIL" adp="2.01" early="1" late="4" selections="126" />
<player id="213968" name="Miguel Cabrera" position="3B" team="DET" adp="2.55" early="1" late="4" selections="126" />
</adp_report>
I need to load this into php where I will be able to access it by finding the name attribute and what the corresponding adp is. I am using it to perform some calculations and insert the results into a table that is being called from a MYSQL database. This is what I have so far:
$url = '...some url';
$xml = simplexml_load_file($url);
while($row = mysqli_fetch_array($resultbat, MYSQLI_ASSOC))
{
echo "<td>" . $row['NAME'] . "</td>";
...print out some more player data from database...
foreach($xml->player as $player)
{
$attr = $player->attributes();
if($attr['name'] == $row['NAME']) //$row['NAME'] is the players name from my database
{
$adp = (float) $attr['adp'];
$early = (int) $attr['early'];
$stdev = -0.42+0.42*($adp-$early);
if($stdev<0)
$stdev = 1;
$chance =number_format(((1-NORMDIST($pickNumber,$adp,$stdev,TRUE))*100), 0);
echo "<td class='adp'>".$adp."</td>";
echo "<td class='chance'>".$chance."%</td>";
break;
}
}
}
This takes a while to process because I'm going through every row in my player database, then using foreach
to look through the xml file and if I find a match I do the calculations. I have to imagine there is a more efficient way to go about this. Thanks in advance.
Upvotes: 0
Views: 353
Reputation: 28997
I'd pre-process the XML file to an associative-array (user-id/user-name => properties);
$url = '...some url';
$xml = simplexml_load_file($url);
$players = array();
foreach($xml->player as $player) {
$attr = $player->attributes();
// cast the SimpleXMLElement to a string
$username = (string) $attr['name'];
$players[$username] = $attr;
}
Then retrieve the data from the database and match the results from XML
while($row = mysqli_fetch_array($resultbat, MYSQLI_ASSOC)) {
if(!array_key_exists($row['NAME'], $players)) {
// player was not found in the XML
continue;
}
// get the player's properties by matching the 'name'
$player_stats = $players[$row['NAME']];
// here, process player_stats
}
However, your code assumes the player-name to be unique, it may be possible that multiple players share the same name (this problem was already present in your current code)
Upvotes: 0
Reputation: 24551
You could use XPath (see: SimpleXMLElement::xpath() and XPath documentation). So, instead of your foreach
loop, this:
$player = $xml->xpath('//player[@name="' . $row['NAME'] . '"]');
if (is_array($player) && count($player)) {
$player = $player[0];
} else {
continue; // not found
}
$attr = $player->attributes();
// and so on...
Upvotes: 1