rpmth
rpmth

Reputation: 75

Getting child and sub-child elements from XML in PHP with SimpleXMLElement

Okay, what should be a simple little task has already cost me three days! I am working with PHP on OS X 10.6.8 and for various reasons cannot upgrade to Mavericks, so I am stuck without a proper PHP IDE and damned to TextWrangler.

So here's my XML:

<?xml version="1.0" encoding="ISO-8859-1"?>
<adapt_xml>
<annonce>
    <reference>0001</reference>
    <liste_photos>
        <photo>photo1.jpg</photo>
        <photo>photo2.jpg</photo>
        <photo>photo3.jpg</photo>
        <photo>photo4.jpg</photo>
    </liste_photos>
    <agence>AVENUE RIVIERA</agence>
</annonce>
<annonce>
    <reference>0002</reference>
    <liste_photos>
        <photo>photo1.jpg</photo>
        <photo>photo2.jpg</photo>
        <photo>photo3.jpg</photo>
        <photo>photo4.jpg</photo>
    </liste_photos>
    <agence>AVENUE RIVIERA</agence>
</annonce>
<annonce>
    <reference>0003</reference>
    <liste_photos>
        <photo>photo1.jpg</photo>
        <photo>photo2.jpg</photo>
        <photo>photo3.jpg</photo>
        <photo>photo4.jpg</photo>
    </liste_photos>
    <agence>AVENUE RIVIERA</agence>
</annonce>
</adapt_xml>

I have figured out how to cycle through the annonce elements to extract each sub attribute so that I can write them all to my database table annonce:

$xmlFile = simplexml_load_file($file);

foreach($xmlFile->annonce as $annonce)
{
    foreach($annonce->children() as $child)
    {
        ...
        echo $child->getName().": ".(string)$child."<br />";
    }
}

What I want to be able to do is cycle through the photos, recuperating each photo as well as the referent to the annonce (the relationship photo to annonce is many-to-one). When I insert the code into the foreach($annonce->children() as $child) space, nothing shows up for the photos:

$xmlFile = simplexml_load_file($file);

foreach($xmlFile->annonce as $annonce)
{
    foreach($annonce->children() as $child)
    {
        ...
        echo $child->getName().": ".(string)$child."<br />";

        foreach ($child->{"liste_photos"} as $liste_photos)
        {
            foreach ($liste_photos->{"photo"} as $photo)
            {
                ...
                echo $photo->getName().": ".(string)$photo."<br />";
            }
        }
    }
}

What am I doing wrong??

Upvotes: 1

Views: 2336

Answers (2)

i alarmed alien
i alarmed alien

Reputation: 9520

The problem with your script is that you're calling $child->liste_photos on the XML elements that are at the same level as <liste_photos>, including <liste_photos> itself. You need to be calling it on the parent element, <annonce> ($annonce in your script), as <liste_photos> is a child of <annonce>.

Since you're using simpleXML and you know the structure of your XML, you can make life a lot easier for yourself by accessing the elements using the element names:

foreach($xmlFile->annonce as $annonce) {
    $ref = $annonce->reference;
    echo "reference: " . $annonce->reference . PHP_EOL;
    echo "agence: " . $annonce->agence . PHP_EOL;
    foreach ($annonce->liste_photos->photo as $photo) {
        echo "photo: " . $photo . "; reference: $ref" . PHP_EOL;
    }
}

Output for your XML:

reference: 0001
agence: AVENUE RIVIERA
photo: photo1.jpg; reference: 0001
photo: photo2.jpg; reference: 0001
photo: photo3.jpg; reference: 0001
photo: photo4.jpg; reference: 0001
reference: 0002
agence: AVENUE RIVIERA
photo: photo1.jpg; reference: 0002
photo: photo2.jpg; reference: 0002
photo: photo3.jpg; reference: 0002
photo: photo4.jpg; reference: 0002
reference: 0003
agence: AVENUE RIVIERA
photo: photo1.jpg; reference: 0003
photo: photo2.jpg; reference: 0003
photo: photo3.jpg; reference: 0003
photo: photo4.jpg; reference: 0003

Re: using braces around the names of subelements in simpleXML, as you did here:

foreach ($child->{"liste_photos"} as $liste_photos)
{
    foreach ($liste_photos->{"photo"} as $photo)

Braces are unnecessary unless you have a character in the XML element name that would cause PHP to misinterpret it; for most XML documents, the only character that will cause trouble is a hyphen (e.g. if you had $child->{'liste-photos'}). Underscores are correctly interpreted by PHP, so braces are unnecessary.

Upvotes: 1

Kevin Lynch
Kevin Lynch

Reputation: 24703

You shouldn't need the braces in this instant. in my experience.

foreach($xmlFile->annonce as $annonce)
{
    foreach($annonce->liste_photos as $liste_photos)
    {
        foreach ($liste_photos->photo as $photo)
        {
                ...
                echo $photo->getName().": ".(string)$photo."<br />";
        }
    }
}

Upvotes: 2

Related Questions