0

i am running a foreach loop to get data from an xml file. the xml file has the same date listed several times, each with different data. what i need to do is show each date only once.

basicly i need the foreach loop to show the first date (object) on the first loop. if the date (object) is the same on the second, third, fourth loop, etc. then skip that loop and move to the next where the date (object) is not the same. here is what i have now:

$dateResults = $xml->xpath('/rtnshowtime/filmtitle/show[preceding-sibling::shortname="AGOODDAYTODIEHARD"]');
foreach ($dateResults as $dateResult) {
    print_r($dateResult->date);
    echo "<br>";
}

that produces:

SimpleXMLElement Object ( [0] => 02152013 ) 
SimpleXMLElement Object ( [0] => 02152013 ) <-- this one needs to be skipped
SimpleXMLElement Object ( [0] => 02152013 ) <-- this one needs to be skipped
SimpleXMLElement Object ( [0] => 02162013 ) 
SimpleXMLElement Object ( [0] => 02162013 ) <-- this one needs to be skipped
SimpleXMLElement Object ( [0] => 02162013 ) <-- this one needs to be skipped
SimpleXMLElement Object ( [0] => 02162013 ) <-- this one needs to be skipped
SimpleXMLElement Object ( [0] => 02162013 ) <-- this one needs to be skipped
SimpleXMLElement Object ( [0] => 02172013 ) 
SimpleXMLElement Object ( [0] => 02172013 ) <-- this one needs to be skipped
SimpleXMLElement Object ( [0] => 02172013 ) <-- this one needs to be skipped
SimpleXMLElement Object ( [0] => 02172013 ) <-- this one needs to be skipped
SimpleXMLElement Object ( [0] => 02172013 ) <-- this one needs to be skipped
SimpleXMLElement Object ( [0] => 02182013 ) 
SimpleXMLElement Object ( [0] => 02182013 ) <-- this one needs to be skipped
SimpleXMLElement Object ( [0] => 02192013 ) 
SimpleXMLElement Object ( [0] => 02192013 ) <-- this one needs to be skipped
SimpleXMLElement Object ( [0] => 02202013 ) 
SimpleXMLElement Object ( [0] => 02202013 ) <-- this one needs to be skipped
SimpleXMLElement Object ( [0] => 02212013 ) 
SimpleXMLElement Object ( [0] => 02212013 ) <-- this one needs to be skipped
JSP254
  • 39
  • 1
  • 9

3 Answers3

2

You could try something like putting the date as key and check to see if the date has already been used.

$dateResults = $xml->xpath('/rtnshowtime/filmtitle/show[preceding-sibling::shortname="AGOODDAYTODIEHARD"]');

$finalResults = array();

foreach ($dateResults as $dateResult) {

    // change your simplexml object to either (int) or (string)
    $date = (int) $dateResult->date;

    // checks key for repeating date
    if (!array_key_exists($date, $finalResults)){
        // assuming you want the entire $dateResult match with date as key
        $finalResults[$date] = $dateResult
    }       

}

//  to print out the results
foreach ( $finalResult as $result ){
    foreach ( $results as $key => $value ){
        echo $key." : ".$value;
    }
}

// or if you know the date and what you want from that array
echo (string) $finalResult[2152013]['salelink']

Untested, please let me know if theres something not working.

Nick Fury
  • 1,313
  • 3
  • 13
  • 23
  • it returns this: Notice: Undefined variable: date in C:\UniServer\UniServer\www\boaz9REDUX\xmlreadertest.php on line 28 Notice: Undefined variable: finalResults in C:\UniServer\UniServer\www\boaz9REDUX\xmlreadertest.php on line 29 Warning: array_key_exists() expects parameter 2 to be array, null given in C:\UniServer\UniServer\www\boaz9REDUX\xmlreadertest.php on line 29 Warning: Illegal offset type in C:\UniServer\UniServer\www\boaz9REDUX\xmlreadertest.php on line 30 – JSP254 Feb 16 '13 at 18:35
  • my knowledge of php is very primitive. i cant explain loops, arrays, objects, etc. but i know they are different. when i tried array_unique, it said basicly that i wasnt outputting an array. – JSP254 Feb 16 '13 at 18:43
  • I fixed a syntax error that had `$date = $dateResult->$date` (undefined variable: date) to `$date = $dateResult->date`. Make sure you add `$finalResults = array();` before your loop. The warning is because `$finalResults` is reading `NULL` right now – Nick Fury Feb 16 '13 at 18:51
  • Warning: array_key_exists(): The first argument should be either a string or an integer in C:\UniServer\UniServer\www\boaz9REDUX\xmlreadertest.php on line 33 Warning: Illegal offset type in C:\UniServer\UniServer\www\boaz9REDUX\xmlreadertest.php on line 35 – JSP254 Feb 16 '13 at 19:06
  • line 35 is: $finalResults[$date] = $dateResult; – JSP254 Feb 16 '13 at 19:07
  • I updated my answer again. `$date` is still a simplexml object and `array_key_exist` only takes in *integers* or *strings* so change the type before you set the `$date` variable. `$date = (int) $dateResult->date;`... that's if you want a integer instead of a string. – Nick Fury Feb 16 '13 at 19:13
  • ok. how do i call this after the if statement? i tried `print_r($finalResults);` and got this [array1.txt](http://projectjsp.net/array1.txt) – JSP254 Feb 16 '13 at 19:27
  • Just updated my answer with how you can loop through `$finalResults` – Nick Fury Feb 16 '13 at 19:40
  • i did. made a few grammatical changes (result, results, finalResults, finalResult, etc.) and added a
    for separation. the result for the top portion is screen : 6 date : 02152013 time : 1705 Info1 : 0 Info2 : 0 Info3 : 0 Info4 : 0 soldout : 0 reserved : 0 salelink : http://14682.formovietickets.com:2235/Tickets.ASP?WCI=buyticket&Page=PickTickets&Title=AGOODDAYTODIEHARD&ShowTime=20130215170500&Auditorium=6
    – JSP254 Feb 16 '13 at 20:38
  • `echo (string) $finalResult[2152013]['salelink']` does not produce anything. also tried it with `$finalResults`. – JSP254 Feb 16 '13 at 20:40
  • i'll be back later... seeing code when i close my eyes right now! LOL – JSP254 Feb 16 '13 at 20:52
0

You could add the dates into an array and then check for existence during the loop:

// create array for storing unique dates
$unique_dates = array();

$dateResults = $xml->xpath('/rtnshowtime/filmtitle/show[preceding-sibling::shortname="AGOODDAYTODIEHARD"]');
foreach ($dateResults as $dateResult) 
{
    // need this to get the time attribute from the object
    $time_index = 0;

    // if the date does not exist in unique dates array
    if ( ! in_array($dateResult->date->$time_index, $unique_dates))
    {
        // add to unique dates array
        $unique_dates[] = $dateResult->date->$time_index;

        print_r($dateResult->date);
        echo "<br>";
    }
}
diggersworld
  • 12,770
  • 24
  • 84
  • 119
  • produces this: Notice: Undefined variable: unique_dates in C:\UniServer\UniServer\www\boaz9REDUX\xmlreadertest.php on line 29 Warning: in_array() expects parameter 2 to be array, null given in C:\UniServer\UniServer\www\boaz9REDUX\xmlreadertest.php on line 29 – JSP254 Feb 16 '13 at 18:38
  • Make sure you defined the array correctly: `$unique_dates = array();` – diggersworld Feb 16 '13 at 18:42
  • xpath('/rtnshowtime/filmtitle/show[preceding-sibling::shortname="AGOODDAYTODIEHARD"]'); foreach ($dateResults as $dateResult) { // if the date does not exist in unique dates array if ( ! in_array($dateResult->date, $unique_dates)) { // add to unique dates array $unique_dates[] = $dateResult->date; print_r($dateResult->date); echo "
    "; } } ?>
    – JSP254 Feb 16 '13 at 18:47
  • produces: SimpleXMLElement Object ( [0] => 02152013 ) SimpleXMLElement Object ( [0] => 02152013 ) SimpleXMLElement Object ( [0] => 02152013 ) SimpleXMLElement Object ( [0] => 02162013 ) SimpleXMLElement Object ( [0] => 02162013 ) – JSP254 Feb 16 '13 at 18:47
  • Ah I see, `$dateResult->date` is an object. If you replace the occurrences of `$dateResult->date` with the value from that object this will work. You want to get the numeric into the array and check that value. – diggersworld Feb 16 '13 at 18:56
  • You need to put these values `02152013, 02162013, 02172013, ...` into the array and then check them when looping. – diggersworld Feb 16 '13 at 19:04
  • i'm not sure about how to do that. also these are dates and these values would need to change everyday or week and would have to continue to do so unaided. – JSP254 Feb 16 '13 at 19:10
  • same result. `SimpleXMLElement Object ( [0] => 02152013 ) SimpleXMLElement Object ( [0] => 02152013 ) SimpleXMLElement Object ( [0] => 02152013 ) SimpleXMLElement Object ( [0] => 02162013 )` – JSP254 Feb 16 '13 at 19:31
  • What do you get if you `print_r($unique_dates);` after the closing `}` of the `foreach` loop? – diggersworld Feb 16 '13 at 19:39
  • sorry. result too long. attached -> [print-unique-dates](http://projectjsp.net/print-unique-dates.txt) – JSP254 Feb 16 '13 at 20:46
  • Can you attach the XML file? – diggersworld Feb 17 '13 at 07:47
  • sorry, been busy with another project. here's the xml. [movie-xml](http://projectjsp.net/movie-xml.xml) – JSP254 Feb 26 '13 at 18:09
0

ok, here's what i have opted for.

$shortname = $_GET['shortname'];
$dateURL = $_GET['date'];
$use_errors = libxml_use_internal_errors(true);
$xml = simplexml_load_file('XML/showtimes.xml');
if (!$xml) {echo "NO XML loaded<br>";}else{echo "XML IS loaded<br>";}
$results = $xml->xpath('/rtnshowtime/filmtitle[child::shortname="'.$shortname.'"]');

foreach ($results as $result) {
    echo "showtimes for ".$dateURL."<br>";
    foreach ($result->show as $result2) {
        if ($result2->date == $dateURL) {
            echo " -".$result2->time."- ";
        }
    }
}

that produces this for example:

showtimes for 02152013
 -1300-  -1400-  -1500-  -1600-  -1700- 

i use $_GET to get the date and shortname from the URL, then i use the shortname to decide which movie inside the xml that i will be dealing with. i then produce that as a result with the first foreach. i then run a second foreach within the first foreach specifically dealing with the child element that contains the dates and times. i then use an if statement to segregate which date i will be dealing with based on the URL. because of that if statement, i can then echo all of the times within that result where the sibling dates are the same. i would like to echo the times such as: 1300, 1400, 1500, 1600 with no comma following the last time, but i dont know how to do that. i tried using implode(), but because each time echo is inside an if statement it's an object instead of array results. i assume that... i'm not extremely familiar with the terminology. i have instead opted for a space and - before each time and a - and space after each time. it will have to work for now. :)

thanks to all of you guys for your assistance! stackoverflow ROCKS!!!

JSP254
  • 39
  • 1
  • 9
  • i failed to add, this only resolves one of my problems with this xml feed. i will have to write a line of code that gives today's date such as 02152013 and make sure it exists within the xml. then i will have to increase that date by one day... i'll probably use strtotime() to do that, and then see if that day exists within the xml. if it does, then echo it as a link, then increase the day again, and so on until the day does not exist within the xml and stop. – JSP254 Feb 27 '13 at 03:02