Search code examples
phpxmlsimplexml

It does not return all values using SimpleXML


I am working with an XML type database in PHP. Using SimpleXML I'm working with the documentation. But when collecting a value, it remains in the first node.

Here XML-DataBase

<?php

$xml = simplexml_load_file('course_catalog.xml');

foreach($xml->department->course as $paj) {
    if($paj->prerequisites->prereq == 'CS106B'){
        echo $paj->title . PHP_EOL;
    }
}

?>

Output;

Computer Organization and Systems

Introduction to Probability for Computer Scientists

All belonging to the first department. But do not access the second department (where there is another -> prereq 'CS106B')

Then i tried this... to collect all the departments and not get stuck in the first (or so I think)

<?php

$xml = simplexml_load_file('course_catalog.xml');

foreach($xml->department as $paj) {
    if($paj->course->prerequisites->prereq == 'CS106B'){
        echo $paj->course->title . PHP_EOL;
    }
}

?>

But it does not return anything.

Any ideas?


Solution

  • The problem is that you are only looping over the courses in the first department because of - $xml->department->course. There are several points where there may be multiple elements, even with prereq may have multiple entries.

    It may be simpler to use XPath to find the elements where prereq is 'CS106B'. The following says - find the courses which have a prerequisites and then a prereq element with a value of 'CS106B'...

    $courses = $xml->xpath("//course[prerequisites/prereq/text()='CS106B']");
    foreach ( $courses as $course ) {
        echo $course->title . PHP_EOL;
    }
    

    With your XML file, this produces

    Computer Organization and Systems
    
    Introduction to Probability for Computer Scientists
    
    Digital Systems II
    

    Without using XPath...

    foreach($xml->department as $paj) {
        foreach ( $paj->course as $course ) {
            if ( isset($course->prerequisites)) {
                foreach ( $course->prerequisites->prereq as $prereq )   {
                    if($prereq == 'CS106B'){
                        echo $course->title . PHP_EOL;
                    }
                }
            }
        }
    }
    

    The main thing is that not all courses seem to have prerequisites, so you have to check this before trying to loop over them.