Home > database >  SimpleXML looping through
SimpleXML looping through

Time:09-26

I get product data via xml like that

    <?xml version='1.0' encoding='UTF-8'?>
    <brands>
        <brand>
            <name>Spielberger Mühle</name>
            <kuerzel>SPI</kuerzel>
            <id>e3124594-1d4c-4a72-8c66-37de394fece2</id>
            <last_modified>27.04.2021 23:00:03</last_modified>
            <logo>
                <id>e3124594-1d4c-4a72-8c66-37de394fece2</id>
                <name>SPI_Spielberger Mühle_e3124594-1d4c-4a72-8c66-37de394fece2.jpg</name>
                <size>273981</size>
                <mime_type>image/jpeg</mime_type>
                <img_width>1533</img_width>
                <img_height>676</img_height>
                <last_modified>13.12.2016 12:48:02</last_modified>
            </logo>
            <url>www.spielberger-muehle.de</url>
            <adr_invb_name>Spielberger GmbH</adr_invb_name>
            <adr_invb_strasse>Burgermühle</adr_invb_strasse>
            <adr_invb_plz>74336</adr_invb_plz>
            <adr_invb_ort>Brackenheim</adr_invb_ort>
            <adr_invb_land_id>8</adr_invb_land_id>
        </brand>
    </brands>
    <producers>
        <producer>
 ....

and in my php (shortened to the relevant parts)

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

    foreach ($xml->brands->brand as $key => $value) {

        print "Key: $key - Value: $value\n";

    }

If I try to loop through the brand the following happens

 Key: brand - Value: 

edited because I figured I was way to verbose.

CodePudding user response:

The reason this is happening is because of how SimpleXMLElement handles it's iterator. You can iterate through the element using the get_object_vars function.

foreach (get_object_vars($xml) as $key => $value) {
    print "Key: $key - Value: $value\n";
}

CodePudding user response:

Bear in mind that SimpleXML does not give you arrays; all of the things you have output in the question are objects, and understanding how those particular objects work is key.

In particular, the object is designed to allow you to iterate over multiple nodes with the same name. In your particular case, there is only one <brand> element, but the library still lets you loop in case there's sometimes more than one:

foreach ( $xml->brands->brand as $brandElement )

This is the loop you've accidentally written; it loops once, because there is one matching element, and the key is "brand", because that's the name of that element. The actual object you wanted is the value in the loop.

Since you know that there is always one matching element in your case, you can directly ask for the first one:

$brandElement = $xml->brands->brand[0];

That is also implied if you access children of the element:

$brandName = $xml->brands->brand->name;
// short for $xml->brands[0]->brand[0]->name

Finally, you can get a list of all children of an element explicitly with ->children():

foreach ( $xml->brands->brand->children() as $name => $element )
// equivalent to foreach ( $xml->brands[0]->brand->children() as $name => $element )
// or foreach ( $xml->brands->brand[0] as $name => $element )
  • Related