Aditya
Aditya

Reputation: 165

How do I loop through a SimpleXML object in PHP

I have a simpleXml object and want to read the data from the object , I am new to PHP and dont quite know how to do this. The object details are as follows.

I need to read [description] and [hours]. Thankyou.

SimpleXMLElement Object (
    [@attributes] => Array (
        [type] => array
    )
    [time-entry] => Array (
        [0] => SimpleXMLElement Object (
            [date] => 2010-01-26
            [description] => TCDM1 data management: sort & upload
            [hours] => 1.0
            [id] => 21753865
            [person-id] => 350501
            [project-id] => 4287373
            [todo-item-id] => SimpleXMLElement Object (
                [@attributes] => Array (
                    [type] => integer
                    [nil] => true
                )
            )
        )
        [1] => SimpleXMLElement Object (
            [date] => 2010-01-27
            [description] => PDCH1: HTML
            [hours] => 0.25
            [id] => 21782012
            [person-id] => 1828493
            [project-id] => 4249185
            [todo-item-id] => SimpleXMLElement Object (
                [@attributes] => Array (
                    [type] => integer
                    [nil] => true
                )
            )
)   )   )

Please help me. I tries a lot of stuff , but not getting the syntax right.

Upvotes: 6

Views: 13725

Answers (3)

Pro-grammar
Pro-grammar

Reputation: 375

Sorry I am new to PHP I just started learning so my concepts come from C programming. I might be doing an excessive amount of work/coding here... but I'm sure I'll get yelled at by someone and learn.

This returns an array back which is nicely laid out for accessing all the individual bits of data without having to handle SimpleXMLElement objects:

public $xmlFileInName = 'sample.xml';

public $errorMessage = "Failed to open file: ";

public function actionGetArray()
{
    try {
        $xml = file_exists($this->xmlFileInName) ?
        simplexml_load_file($this->xmlFileInName) :
        exit($this->errorMessage. $this->xmlFileInName);

        $xmlArray=$this->arrayFromSxe ($xml);

        echo var_dump($xmlArray);
    }
    catch(Exception $e) {
        echo $e->getMessage();
    }
}

public function arrayFromSxe($sxe)
{
    $returnArray = array();
    foreach ((array)$sxe as $key=>$value) {
        if(is_array($value) && !$this->is_assoc($value)) {
            $indies = array();
            foreach($value as $secondkey=>$secondvalue)
                $indies[$secondkey] = $this->arrayFromSxe($secondvalue);
            $returnArray[$key] = $indies;
        }
        else {
            if(is_object($value)) {
                $returnArray[$key] = $this->arrayFromSxe($value);
            } else {
                $returnArray[$key] = $value;
            }
        }
    }
    return $returnArray;
}

function is_assoc($array) {
    return (bool)count(array_filter(array_keys($array), 'is_string'));
}

Note that with multiple xml tags, i.e. in your example:

[time-entry] => Array (
    [0] => SimpleXMLElement Object (
    ...
    )
    [1] => SimpleXMLElement Object (
    ...
    )

You will have to know something about the structure of the XML file in order to address this in you code. This will return in an array after calling this line:

$xmlArray=$this->arrayFromSxe ($xml);

Which will have:

[time-entry][0]
[time-entry][1]

So your code will need to know to iterate over all time-entries via int indexers or in any situation which their are multiple occurrences of an xml element.

If what I have said doesn't make sense then disregard it and simply observe and evaluate the code as it stands.

Hope this helps.

Upvotes: 0

salathe
salathe

Reputation: 51950

If the object that you print_r-ed in the question is in $element then the following will loop over the two time-entry elements while printing out their respective description and hours values.

foreach ($element->{'time-entry'} as $entry) {
    $description = (string) $entry->description;
    $hours       = (string) $entry->hours;
    printf("Description: %s\nHours: %s\n\n", $description, $hours);
}

Outputs something like:

Description: TCDM1 data management: sort & upload NFP SubProducers list
Hours: 1.0

Description: PDCH1: HTML
Hours: 0.25

Note that the time-entry element name has to be wrapped in curly braces1 as a string since otherwise $element->time-entry would try to read the time element and subtract the value of a constant called entry which is obviously not what we want. Also, the description and hours values are cast2 to strings (they would otherwise be objects of type SimpleXMLElement).

1. See variable variables 2. See type casting

Upvotes: 1

Kerry Jones
Kerry Jones

Reputation: 21838

It's really hard to read the above, if you could give us a screen shot or give line spacing and indents, that would be a bit better If you have an object

$xml that is a simplexml object, you can access elements like

$xml->element.

It looks like is an element of time entry, in which case you would loop through like this:

foreach( $xml->{'time-entry'} as $time_entry ) {
    echo $time_entry->description . "<br />\n";
}

Upvotes: 10

Related Questions