Jump to content

Matching events in an array


Go to solution Solved by Barand,

Recommended Posts

Hi,

 

I have an XML files of sports events (see below). Some of the events have the same match name, so I've put everything into an array and then tried to match them using matchname as a key.

 

 

The XML looks like this:

 

<match><sportname>Football</sportname><tournamentname>Red League</tournamentname><thetime>201311021245</thetime><matchname dateandtime="1383396300">Town Rovers vs Chanel</matchname><linkset><link lang="en" kbps="300" channelname="Link 1">link1.html</link><link lang="en" kbps="350" channelname="Link 2">link2.html</link></linkset></match>
 
<match><sportname>Football</sportname><tournamentname>Red League</tournamentname><thetime>201311021245</thetime><matchname dateandtime="1383396300">Town Rovers vs Chanel</matchname><linkset><link lang="en" kbps="320" channelname="Link 3">link3c.html</link><link lang="en" kbps="320" channelname="Link 3">link4.html</link></linkset></match>

 

Here's my PHP code (I'm pulling in the XML file using SimpleXML)...

 


$xml = simplexml_load_file('test3.xml'); 
$aCopy = array();
 
foreach ($xml->match AS $match)
{
    if (!isset($aCopy[(string)$match->matchname]))
    {
        $aCopy[(string)$match->matchname] = $match;
    }
    else
    {
        foreach ($match->linkset->link AS $link)
        {
            $aCopy[(string)$match->matchname]->linkset->addChild('link', $link);
        }
    }
}  
 

 

 

The code above seems to have gotten me 80% of the way in that they are matching ok and the links output ok. But the weird thing is the attributes on the 2nd instance of the match aren't outptting...

 

Link 1 en 300 link1.html
Link 2 en 350 link2.html
[blank] [blank] [blank] link3.html
[blank] [blank] [blank] link4.hmtl

(Where [blank] is supposed to be the channelname, lang and kbps outputted attributes) 

 

Any suggestions on what I might be doing wrong here?

 

Thanks in advance for any help you can offer.

Link to comment
https://forums.phpfreaks.com/topic/283534-matching-events-in-an-array/
Share on other sites

does this help?

$xml = simplexml_load_string($str);
$channelname = "CHANNEL";   // get from xml feed
$lang = "LANG";             // get from xml feed
$kbps = "KBPS";             // get from xml feed

$acopy = array();

foreach ($xml->match as $match) {
    foreach ($match->linkset->link as $link) {
        $acopy[(string)$match->matchname][] = array($channelname, $lang, $kbps, (string)$link);
    }
}

echo '<pre>',print_r($acopy, true),'</pre>';

RESULT

Array
(
    [Town Rovers vs Chanel] => Array
        (
            [0] => Array
                (
                    [0] => CHANNEL
                    [1] => LANG
                    [2] => KBPS
                    [3] => link1.html
                )

            [1] => Array
                (
                    [0] => CHANNEL
                    [1] => LANG
                    [2] => KBPS
                    [3] => link2.html
                )

            [2] => Array
                (
                    [0] => CHANNEL
                    [1] => LANG
                    [2] => KBPS
                    [3] => link3c.html
                )

            [3] => Array
                (
                    [0] => CHANNEL
                    [1] => LANG
                    [2] => KBPS
                    [3] => link4.html
                )

        )

)



Thanks for your reply - I've updated my code. 

 
 
For the attributes in the array you pasted, will the channel name output as "Link 3" or literally "CHANNEL"?
 
Also, I'm not able to output my HTML for some reason. Here is my code:
 
 
foreach ($acopy AS $thematches)
 
{
 
  $singlematchname = strtolower($thematches->matchname); // FORMAT 
 
 $singlematchlinks = '';
 
// LOOP THROUGH ALL LINKS
 
foreach ($thematches->linkset->link AS $link)
        {
 
            $singlematchlinks .= '<div class="matchrow"><div class="channelname">'.$link["channelname"].'</div><div class="language">'.$link["lang"].'</div><div class="kbps">'.$link["kbps"].'</div><div class="link"><a href="'.$link.'" target="_blank">Watch</a></div><div class="clearb"></div></div>';
 
    }
 
echo '<h5>'.$singlematchname.'</h5>'.$singlematchlinks;
  }
 
This gives the error: 
Warning: Invalid argument supplied for foreach() in /home/freefoot/public_html/newsite/read_test2.php on line 55
 
Line 55 starts with:
foreach ($thematches->linkset->link AS $link)
 
Any idea what I might be doing wrong?
Edited by denhamd2

$thematches->linkset->link is obviously not an array (anymore), thats why its flagged as invalid

 

Simple test:

if(is_array($thematches->linkset->link)){
  echo '<p>is array:</p>';
  print_r($thematches->linkset->link);
}
else{
  echo '<p>is not an array:</p>';
  echo $thematches->linkset->link;
}

Sorry, missed those

$xml = simplexml_load_string($str);

$acopy = array();

foreach ($xml->match as $match) {
    foreach ($match->linkset->link as $link) {
        $acopy[(string)$match->matchname][] = array(
            (string)$link['channelname'], 
            (string)$link['lang'], 
            (string)$link['kbps'], 
            (string)$link
            );
    }
}

echo '<pre>',print_r($acopy, true),'</pre>';

do you mean something like this?

$xml = simplexml_load_string($str);

$acopy = array();

foreach ($xml->match as $match) {
    $acopy[(string)$match->matchname]['sportname'] = (string)$match->sportname;
    $acopy[(string)$match->matchname]['tournamentname'] = (string)$match->tournamentname;
    $acopy[(string)$match->matchname]['time'] = (string)$match->thetime;
    foreach ($match->linkset->link as $link) {
        $acopy[(string)$match->matchname]['links'][] = array(
            (string)$link['channelname'], 
            (string)$link['lang'], 
            (string)$link['kbps'], 
            (string)$link
            );
    }
}

echo '<pre>',print_r($acopy, true),'</pre>';

result

Array
(
    [Town Rovers vs Chanel] => Array
        (
            [sportname] => Football
            [tournamentname] => Red League
            [time] => 201311021245
            [links] => Array
                (
                    [0] => Array
                        (
                            [0] => Link 1
                            [1] => en
                            [2] => 300
                            [3] => link1.html
                        )

                    [1] => Array
                        (
                            [0] => Link 2
                            [1] => en
                            [2] => 350
                            [3] => link2.html
                        )

                    [2] => Array
                        (
                            [0] => Link 3
                            [1] => en
                            [2] => 320
                            [3] => link3c.html
                        )

                    [3] => Array
                        (
                            [0] => Link 3
                            [1] => en
                            [2] => 320
                            [3] => link4.html
                        )

                )

        )

)

This is perfect, thanks so much again.

 

In terms of outputting it in HTML, I'm trying to output it like below:

 

Football

 

Red League - Town Rovers vs Chanel

Link 1: 300: en: link1.html

Link 2: 300: en: link2.html

Link 3: 300: en: link3.html

Link 4: 300: en: link4.html

 

Blue League - Blue United vs FC Turf

Link 5: 200: en: link5.html

Link 6: 300: de: link6.html

Link 7: 500: en: link7.html

Link 8: 300: en: link8.html

 

I just can't get my head around how to use the perfectly formatted array you gave me to do this. I just keep getting errors.

 

Any last help you could offer would be hugely appreciated!

I have altered the structure of the array so they are grouped by sportname/tournamentname/matchname. Makes it nice and easy to loop through the structure.

$xml = simplexml_load_string($str);

$acopy = array();

/**********************************
* Build the array
***********************************/
foreach ($xml->match as $match) {
    $acopy[(string)$match->sportname][(string)$match->tournamentname][(string)$match->matchname]['time'] = (string)$match->thetime;
    foreach ($match->linkset->link as $link) {
        $acopy[(string)$match->sportname][(string)$match->tournamentname][(string)$match->matchname]['links'][] = array(
            (string)$link['channelname'], 
            (string)$link['kbps'], 
            (string)$link['lang'], 
            (string)$link
            );
    }
}

/**********************************
* Output the array
***********************************/
foreach ($acopy as $sportname => $sportarray) {
    echo "$sportname<br><br>";
    foreach ($sportarray as $tournament => $tournarray) {
        foreach ($tournarray as $match => $matcharray) {
            echo "$tournament - $match<br>";
            foreach ($matcharray['links'] as $linkarray) {
                echo join(' : ', $linkarray) . '<br>';
            }
            echo '<br>';
        }
    }
}
  • 1 month later...

Excellent, this works a charm - thanks so much! :)

 

One last thing ... I'm trying to output the time and date from the XML node "thetime" in the format:

Blue League - Blue United vs FC Turf - 29th December 2013, 16:00

 

Any idea how I'd do this?

 

Thanks again


/**********************************
* Output the array
***********************************/
foreach ($acopy as $sportname => $sportarray) {
echo "$sportname<br><br>";
foreach ($sportarray as $tournament => $tournarray) {
foreach ($tournarray as $match => $matcharray) {
$dt = date('jS F Y, H:i', strtotime($matcharray['time'])); // added
echo "$tournament - $match - $dt<br>"; // changed
foreach ($matcharray['links'] as $linkarray) {
echo join(' : ', $linkarray) . '<br>';
}
echo '<br>';
}
}
}

Given there is only one date value in the trivial amount of data provided then there is no way to test.

 

However, try it with this extra line

/**********************************
* Output the array
***********************************/
foreach ($acopy as $sportname => $sportarray) {
    echo "$sportname<br><br>";
    foreach ($sportarray as $tournament => $tournarray) {
        uasort($tournarray, function($a,$b){return strcmp($a['time'], $b['time']);});    // ADD
        foreach ($tournarray as $match => $matcharray) {
            $dt = date('jS F Y, H:i', strtotime($matcharray['time'])); 
            echo "$tournament - $match - $dt<br>";
            foreach ($matcharray['links'] as $linkarray) {
                echo join(' : ', $linkarray) . '<br>';
            }
            echo '<br>';
        }
    }
}
Edited by Barand

So by re-structuring the array, do you mean having the top level be the date? Like so?...

Array
(
[201301041400] => Array
{
    [Town Rovers vs Chanel] => Array
        (
            [0] => Array
                (
                    [0] => CHANNEL
                    [1] => LANG
                    [2] => KBPS
                    [3] => link1.html
                )

            [1] => Array
                (
                    [0] => CHANNEL
                    [1] => LANG
                    [2] => KBPS
                    [3] => link2.html
                )

            [2] => Array
                (
                    [0] => CHANNEL
                    [1] => LANG
                    [2] => KBPS
                    [3] => link3c.html
                )

            [3] => Array
                (
                    [0] => CHANNEL
                    [1] => LANG
                    [2] => KBPS
                    [3] => link4.html
                )

        )

    )
}

Not necessarily.

 

At present there is an array of sports.

    Each sport contains an array of leagues.

        Each league contains an array of matches

 

So when an array of matches is sorted by time, it is within each league. It's matter of deciding at what level you want them sorted.

 

But, instead of using XML as your data source it would be much better to load the data from the XML into a database and use the XML as a data transfer medium.

Thanks for this advice. Unfortunately I do not have access to a database, so I need to use just XML.

 

The level I need them sorted is instead of within each league, it should be within each sport. How hard would it be to do this?

Edited by denhamd2
  • Solution

This should do it

$xml = simplexml_load_string($str);

$acopy = array();

/**********************************
* Build the array
***********************************/
foreach ($xml->match as $match) {
    $acopy[(string)$match->sportname][(string)$match->matchname]['time'] = (string)$match->thetime;
    $acopy[(string)$match->sportname][(string)$match->matchname]['tournament'] = (string)$match->tournamentname;
    foreach ($match->linkset->link as $link) {
        $acopy[(string)$match->sportname][(string)$match->matchname]['links'][] = array(
            (string)$link['channelname'], 
            (string)$link['kbps'], 
            (string)$link['lang'], 
            (string)$link
            );
    }
}
//echo '<pre>',print_r($acopy, true),'</pre>'; exit;

/**********************************
* Output the array
***********************************/
foreach ($acopy as $sportname => $sportarray) {
    echo "$sportname<br><br>";
    uasort($sportarray, function($a,$b){return strcmp($a['time'], $b['time']);});
    
    foreach ($sportarray as $match => $matcharray) {
        $dt = date('jS F Y, H:i', strtotime($matcharray['time'])); 
        echo "{$matcharray['tournament']} - $match - $dt<br>";
        foreach ($matcharray['links'] as $linkarray) {
            echo join(' : ', $linkarray) . '<br>';
        }
        echo '<br>';
    }
}

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.