views:

177

answers:

4

The following PHP code:

<html>
<?php


$name = Secrezy;
$server = Sunstrider;

 $raidurl='http://eu.wowarmory.com/character-achievements.xml?r='.$server.'&amp;cn='.$name.'&amp;c=168';
 print_r($raidurl); // This is to check if the link is valid. Follow the link printed here and you should find a valid XML page
 echo "<br>"; 
 $xmlraid = simplexml_load_file($raidurl);
 $achievement = array($xmlraid->xpath("/category/achievement[@id='4602']"));  
 print_r($achievement);

?>
</html>

Isn't working as I would expect it to. Shouldn't $achievement be populated with this:

<achievement categoryId="168" dateCompleted="2010-03-26T00:01:00+01:00" desc="Complete the 10-player raid achievements listed below." icon="inv_helmet_74" id="4602" points="25" reward="Reward: Bloodbathed Frostbrood Vanquisher" title="Glory of the Icecrown Raider (10 player)">

Instead, I just get an empty array.

Here is the full URL to the page http://eu.wowarmory.com/character-achievements.xml?r=Sunstrider&amp;cn=Secrezy&amp;c=168

Thanks!

Edit: After changing the xpath to /achievements/category/achievement[@id='4602'] which I completely missed, everything works fine. So thanks for that. However, if I implement this into my original code, it still doesn't work as I would expect. I'm sure I'm doing something terribly wrong, so thanks for the help.

<?php
echo "<html>
 <head>
  <title>ARMORY.</title>
  <meta http-equiv='Content-Type' content='text/html' charset=iso-8859-1>
 </head>
 <body>
 <table width='50%' border='1' cellpadding='10' cellspacing='10'>";
ini_set("user_agent", "Mozilla/5.0 (X11; U; Linux i686; pl-PL; rv:1.9.0.2) Gecko/20121223 Ubuntu/9.25 (jaunty) Firefox/3.8");

$server = "Sunstrider";
$guild = "Operation+Eskimo";

$url='http://eu.wowarmory.com/guild-info.xml?r='.$server.'&amp;gn='.$guild;
$xml = simplexml_load_file($url);



$array = array();



foreach($xml->guildInfo->guild->members->character as $char)
  if(strtolower($char['level']) === '80')
  {
        $array[] = $char['name']."<br />";
  } 

$i = 0;
while($array[$i] != null) 
{
 $name = $array[$i];
 $raidurl='http://eu.wowarmory.com/character-achievements.xml?r='.$server.'&amp;cn='.$name.'&amp;c=168';
 $xmlraid = simplexml_load_file($raidurl);
 var_dump($xmlraid);
 echo "<br><br>";
 $achievement = array($xmlraid->xpath("/achievements/category/achievement[@id='4602']")); 
    $i++; 
}


?>

 </body>
</html>

That var_dump of xmlraid only produces this (many many times due to $i):

object(SimpleXMLElement)#3 (2) { ["@attributes"]=>  array(2) { ["lang"]=>  string(5) "en_us" ["requestUrl"]=>  string(27) "/character-achievements.xml" } ["category"]=>  object(SimpleXMLElement)#2 (1) { ["category"]=>  array(12) { [0]=>  object(SimpleXMLElement)#5 (0) { } [1]=>  object(SimpleXMLElement)#6 (0) { } [2]=>  object(SimpleXMLElement)#7 (0) { } [3]=>  object(SimpleXMLElement)#8 (0) { } [4]=>  object(SimpleXMLElement)#9 (0) { } [5]=>  object(SimpleXMLElement)#10 (0) { } [6]=>  object(SimpleXMLElement)#11 (0) { } [7]=>  object(SimpleXMLElement)#12 (0) { } [8]=>  object(SimpleXMLElement)#13 (0) { } [9]=>  object(SimpleXMLElement)#14 (0) { } [10]=>  object(SimpleXMLElement)#15 (0) { } [11]=>  object(SimpleXMLElement)#16 (0) { } } } 

I should add that I'm very new to PHP so my code isn't great.

A: 

No, check the doc. simplexml_load_file() returns an object representing the XML into $xmlraid. I suggest doing a var_dump($xmlraid); and to verify your xpath expression.

Jason McCreary
+2  A: 

Shouldn't the xpath be:

/achievements/category/achievement[@id='4602']

Or:

//category/achievement[@id='4602']

http://www.w3schools.com/xpath/xpath_syntax.asp

Update:

The issue with that code is the fact that you were adding <br /> to the end of each name in $array. Generally, avoid adding formatting in this way, unless there's a good reason.

Also, note my notes in the comments. Especially, urlendcode(). I left this for you to do with $url as I didn't notice it until after starting this edit and I'm lazy. ;) Note, that once you pass those query string params through urlencode() the + in the guild name won't be necessary and it will actually get in the way.

ini_set("user_agent", "Mozilla/5.0 (X11; U; Linux i686; pl-PL; rv:1.9.0.2) Gecko/20121223 Ubuntu/9.25 (jaunty) Firefox/3.8");

$server = "Sunstrider";
$guild = "Operation+Eskimo";

$url='http://eu.wowarmory.com/guild-info.xml?r='.$server.'&amp;gn='.$guild;
$xml = simplexml_load_file($url);

$array = array();

foreach ($xml->guildInfo->guild->members->character as $char)
{
    if (strtolower($char['level']) === '80')
    {
        $array[] = $char['name'];
    }
}

foreach ($array as $i => $name)
{
// note that this if statement and $i in the foreach are only here to limit this to 1 for testing, the full list spews out A LOT of data and takes A LONG time
if ($i) 
{
exit;
}
    // note the urlencode() call, that's important
    $raidurl='http://eu.wowarmory.com/character-achievements.xml?r=' . urlencode($server) . '&cn=' . urlencode($name) . '&c=168';
    $xmlraid = simplexml_load_file($raidurl);

    // note the pre tags around var_dump, makes things easier to read in the browser
    // also note print instead of echo, I lke to do this for debugging, as it makes 
    // it easier to determine what's is debug output for those long running debugging sessions
    print '<pre>';
    var_dump($xmlraid);
    print '</pre>';
     echo "<br><br>";

    // quick and dirty solution for viewing the XML
    /*print '<textarea cols="400" rows="2000">';
    print $xmlraid->asXML();
    print '</textarea>';*/

    $achievement = $xmlraid->xpath("/achievements/category/achievement[@id='4602']");

    print '<pre>';
    var_dump($achievement);
    print '</pre>';
}
George Marian
+1 yep, he is missing the root element.
Felix Kling
Thanks a lot George.
James
A: 

The document element is achievements.

Your XPATH statement should be:

/achievements/category/achievement[id='4602']
Mads Hansen
A: 

Damn, those people are nasty browser-sniffers. I didn't do it all in vain though, this works:

<?php
$opts = array(
    'http' => array(
        'header' => 'User-Agent: Firefox/3.5.9\r\n'
    )
);
$context = stream_context_create($opts);
libxml_set_streams_context($context);

$d = simplexml_load_file('http://eu.wowarmory.com/character-achievements.xml?r=Sunstrider&amp;cn=Secrezy&amp;c=168');
var_dump($d->xpath("//achievement[@id='4602']"));

The _extremely sad thing is, at first I just hoped it would be at least Accept or at the most Accept-Encoding - headers. But no, the "shouldn't mean anything significant"-User-Agent-header. A fine example why browser sniffing is bad if I ever saw one.

Wrikken
Thanks for this. I did actually have the user agent in my original code which I have now edited into the first post. simplexml_load_file seems to work now unless I try to implement it into a while loop...
James