Hi!
I hope someone can help me with this, I am getting kind of desperate.

I am working on an XML parser and I have 2 foreach statements in this code. I need them to run as one but I tried foreach ($params as $param && $note as $value) but no luck. As it is now all the odds are displayed before all the games, but they should be displayed together. Hope someone has some knowledge about this.

/Carl

$dom = new DomDocument;
$dom->load("http://odds.expekt.com/exportServlet");
$dom->preserveWhiteSpace = FALSE;
$params = $dom->getElementsByTagName('alternative');
$note = $dom->getElementsByTagName("game");

 foreach ($params as $param) {
       $odds= $param -> getAttribute('odds');
	   echo "$odds<br/>";
}


foreach( $note as $value)

  {

$descriptions = $value->getElementsByTagName("description");
$description  = $descriptions->item(0)->nodeValue;

$categories = $value->getElementsByTagName("category");
$category  = $categories->item(0)->nodeValue;

$alts = $value->getElementsByTagName("alternatives");
$alt  = $alts->item(0)->nodeValue;


if ($category==NHL) {
    echo "$description <br/>$alt<br/>";

}

 }

    My first thought would be to look at the XML structure and make sure that this is even necessary. But if it is, you could do a foreach() on one array, and within that loop use current()/next() on the other array:

    reset($arr2);
    foreach($arr1 as $a1)
    {
       $a2 = current($arr2);
       if($a2 === false)
       {
          break;
       }
       next($arr2);
       // do stuff with $a1 and $a2
    }
    

      This probably doesn't produce the output you want; it's just to show one way it can be done:

      $dom = new DomDocument;
      $dom->load('http://odds.expekt.com/exportServlet');
      $dom->preserveWhiteSpace = false;
      $note = $dom->getElementsByTagName('game');
      
      foreach ($note as $value) {
          $description = $value->getElementsByTagName('description')->item(0)->nodeValue;
          $category    = $value->getElementsByTagName('category')->item(0)->nodeValue;
          echo $description . '<br />';
          echo $category . '<br />';
          $alt    = $value->getElementsByTagName('alternative');
          $length = $alt->length;
          for ($index = 0; $index < $length; $index++) {
              $odds = $alt->item($index)->attributes->getNamedItem('odds')->nodeValue;
              $text = $alt->item($index)->nodeValue;
              echo $text . ' : ' . $odds . '<br />';
          }
          echo '---------------' . '<br />';
      }
        $params = $dom->getElementsByTagName('alternative');
        $note = $dom->getElementsByTagName("game");
        
        for ($i = 0; $i < $params->length; ++$i) {
        	$params->item($i);
        	$note->item($i);
        }
        

        And as a sidenote, && is a binary logical operator. That is, it evaluates to true if both sides are true (non-zero).

          johanafm - That's nice and concise code; unfortunately it has no applicability to the actual xml source in question. For instance, in the source each game element has anywhere from one to dozens of alternative descendant elements.

            Ah, I never thought to actually look at the xml in question and made some assumptions based on what I thought he wanted. Indeed, my code would not work.

              No problem, I'm just so happy that Installers code works 🙂

                I have another question.

                I will do the same with atleast another xml feed that is similar and I want to be able to list the odds from that bookmaker under the right game from the first xml so to speak.

                Should I use mysql database to combine the 2 (or more) xml feeds so each game gets a table in a database or could I just parse it with php directly? Just want to know which road I should take 😉

                  I should add that what I really want at this stage is to import the xml into a database, even if I'm just gonna use 1 xml file. Can I do that with the parsed xml from the php code?

                    Being able to combine two feeds into a database would depend mostly, I guess, on whether or not they both use the same identifiers for each game, or there is some other way to programmatically match the data. I see you've also used the code on another xml file and added each game's date, but that of course wouldn't work as an identifier (many games on the same day). If the "game id" elements are unique and consistent across the feeds it shouldn't be any problem combining the feeds using those elements. It would probably work best to use (at least) two tables, one for the game names, etc., and one for the odds, with the game ids as the correlating key. Then do the inserts/updates at the same time as reading the xml. The database would need to be carefully designed, taking into account the great variations in the types of "alternative" data, the potential for the database to become very large, etc.

                    But first I suggest you should do more work on the xml reading and data presentation code (such as separating the two). The code I posted was more or less just "proof of concept" stuff, and probably not very robust.

                    hth

                      Ok, thank you for your reply.

                      Also I have one problem with the code. This line $description = $value->getElementsByTagName('description')->item(0)->nodeValue; gets both the value from the "description" and from the child "category". Is there some way to just get the info from the top level node?

                        $description = $value->getElementsByTagName('description')->item(0)->childNodes->item(2)->nodeValue;
                        

                        But you might want to actually iterate over the child nodes and only include those that are of type #text.

                          Thank you so much Johan 🙂

                          That was exactly what I was looking for.

                            Adding a str_replace() would do it:

                            foreach ($note as $value) {
                                $description = $value->getElementsByTagName('description')->item(0)->nodeValue;
                                $category    = $value->getElementsByTagName('category')->item(0)->nodeValue;
                                $description = str_replace($category, '', $description);
                                // etc.
                            }

                            I'm sure there's a better way. But the "description" text should really be in a separate child element (or attribute) of "description".

                              They are in separate child elements in the DOM tree, of type #text

                                I will probably make 1 table for each league, I guess that is the best solution, and only include the big leagues so the database don't spin out of control lol.

                                  johanafm - Thanks. I have a knack for missing the obvious. 🙂

                                    Write a Reply...