I’m trying to build an unordered list from an existing XML file which contains categories and subcategories + images. I need each subcategory to be an item in an unordered list with each related image in a nested list. The subcategories should be shown only once (must not repeat if it’s the same). I believe what I’m looking for is a recursive loop, but that’s where I get lost.
Essentially, I’m trying to achieve a look similar to this:
————–DOGS————-
[……….small……….]
[picture] [picture]
[……….large……….]
[picture]
————–CATS————-
[……….medium……….]
[picture]
[……….large……….]
[picture] [picture]
My XML file structure:
<root>
<animal>
<category>DOGS</category>
<subcategory>small</subcategory>
<name>Terrier</name>
<image>aaa.jpg</image>
</animal>
<animal>
<category>-</category>
<subcategory>small</subcategory>
<name>Havanese</name>
<image>bbb.jpg</image>
</animal>
<animal>
<category>-</category>
<subcategory>large</subcategory>
<name>Dalmatian</name>
<image>ccc.jpg</image>
</animal>
<animal>
<category>CATS</category>
<subcategory>medium</subcategory>
<name>Abyssinian</name>
<image>ddd.jpg</image>
</animal>
<animal>
<category>-</category>
<subcategory>large</subcategory>
<name>Birman</name>
<image>eee.jpg</image>
</animal>
<animal>
<category>-</category>
<subcategory>large</subcategory>
<name>American Shorthair</name>
<image>fff.jpg</image>
</animal>
</root>
Here’s what I have attempted so far:
<?php
$xml = simplexml_load_file("file.xml");
$categories = array();
$subcategories = array();
$names = array();
$image = array();
foreach($xml->animal as $animals) {
$category = $animals->category;
$subcategory = $animals->subcategory;
$name = $animals->name;
$image = $animals->image;
$categories[] = $category;
$subcategories[] = $subcategory;
$names[] = $name;
$images[] = $image
}
function getMenu($xml, $categories, $subcategories, $names, $images) {
$output = '<ul>';
foreach(array_keys($images) as $n) {
$output .= '<li class="animals" data-tags="'.$names[$n].'">';
$output .= '<img src="xml/'.$images[$n].'" width="75" height="75" alt="'.$names[$n].'" />';
$output .= '</li>';
}
$output.= '</ul>';
return array($output);
}
$result = getMenu($xml, $categories, $subcategories, $names, $images);
echo json_encode($result);
?>
There are literally a thousand ways how you can do that. Most straight forward is probably with
xpath(). It’s a powerful XML querying language worth to learn. Example with your$xmlsimplexmlelement:Output:
You further on might want to replace the lengthy xpath strings out there. With the help of a closure and an iterator aggregate, it’s even possible to reduce the code quite comfortable to:
This would allow to change the XML structure later on and have the xpath’s configured in a central location:
I have put that example online as a demo.
I have the output just as text with indents, however thanks to the
foreachs it should be really straight forward to turn that into HTML. I leave that as an exercise.