Reputation: 75
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
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
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