Jump to content

Matching events in an array


denhamd2
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
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
                )

        )

)



Link to comment
Share on other sites

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
Link to comment
Share on other sites

$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;
}
Link to comment
Share on other sites

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>';

Link to comment
Share on other sites

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
                        )

                )

        )

)
Link to comment
Share on other sites

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!

Link to comment
Share on other sites

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>';
        }
    }
}
Link to comment
Share on other sites

  • 1 month later...

/**********************************
* 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>';
}
}
}

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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
                )

        )

    )
}

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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
Link to comment
Share on other sites

  • 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>';
    }
}

Link to comment
Share on other sites

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.