...

View Full Version : XML and Arrays



moos3
08-15-2007, 06:23 PM
I have the following code for a gallery i wrote:



$gallery_Xml = new SimpleXMLElement(utf8_encode(file_get_contents('gallery/gallery.xml')));
$author = (string)$gallery_Xml->information->author;
$copyright = (string)$gallery_Xml->information->copyright;
$desc = (string)$gallery_Xml->information->description;
$albums = $gallery_Xml->album;
$imgset;
$i = 0;
$j = 0;
echo'<h2>"Photos by '.$author.'"</h2>';
echo '<div class="info">'.$desc.'</div>';
foreach($gallery_Xml->album as $albums=>$images){
echo "boo";
switch($images){
case "title":
echo "<h2>".$images['title']."</h2></br>";
break;
case "imgfile":
echo $images['imgfile'];
break;
}
}

heres the xml document:


<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
# This file is part of m3xml Gallery.
#
# m3xml Gallery is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# m3xml Gallery is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# To Add a album just make a in new <album></album> node
# You must put the images in a image node
# One image per node only
# So each each album node can have many image nodes but each image node
# can only have one title node and one imgfile node.
#
# Each album node can have a name and a description(not currently used)
# Each album node must have a title
#
# Please enjoy
# Written by moos3
# Alpha date 14 AUG 2007
# Beta1 date 15 AUG 2007
-->
<gallery>
<information>
<author>Jayme Gallant</author>
<description>This is a my simple PHP gallery written by Moos3 Studios</description>
<copyright>All Rights Reserved and All Contributors Maintin own CopyRights. </copyright>
</information>
<album>
<name>Camp</name>
<desc>Pictures From Camp</desc>
<image>
<title>Up the River</title>
<imgfile>gallery/photos/camp/up_river.jpg</imgfile>
</image>
<image>
<title>River Road</title>
<imgfile>gallery/photos/camp/road_to_camp.jpg</imgfile>
</image>
<image>
<title>Up The River Road</title>
<imgfile>gallery/photos/camp/up_the_riverroad.jpg</imgfile>
</image>
<image>
<title>Down The River</title>
<imgfile>gallery/photos/camp/down_river.jpg</imgfile>
</image>
</album>
<album>
<name>Funny Pictures</name>
<image>
<title>barcode</title>
<imgfile>http://circle.ch/blog/cache/qr697.jpg</imgfile>
</image>
<image>
<title>A Tower</title>
<imgfile>http://farm2.static.flickr.com/1405/818970598_5f0934dee0.jpg?v=0</imgfile>
</image>
<image>
<title>Buddy Jesus</title>
<imgfile>gallery/photos/funstuff/buddyjesus.png</imgfile>
</image>
</album>
</gallery>

The thing is a I can't get it to work. Suggestions?

CFMaBiSmAd
08-15-2007, 06:38 PM
The thing is a I can't get it to work. Suggestions?Yes, tell us what it is doing and what it is not doing. Are there any error messages? What troubleshooting steps have you done to pin down which part of it does not work?

We only see the information you provide in your post. Just posting code and saying that it does not work does not provide any useful information for anyone here to help you.

TheShaner
08-15-2007, 06:44 PM
$gallery_Xml = new SimpleXMLElement(utf8_encode(file_get_contents('gallery/gallery.xml')));
$author = (string)$gallery_Xml->information->author;
$copyright = (string)$gallery_Xml->information->copyright;
$desc = (string)$gallery_Xml->information->description;
$albums = $gallery_Xml->album;
$imgset;
$i = 0;
$j = 0;
echo'<h2>"Photos by '.$author.'"</h2>';
echo '<div class="info">'.$desc.'</div>';
foreach($gallery_Xml->album as $albums=>$images){
echo "boo";
switch($images){
case "title":
echo "<h2>".$images['title']."</h2></br>";
break;
case "imgfile":
echo $images['imgfile'];
break;
}
}



In your above code, what is happening? What is $imgset; doing?

Most important, your foreach loop isn't correct. You also store the album information in $albums but then ignore it in your foreach loop.

I would get rid of $albums = $gallery_Xml->album; and change that whole loop to:

foreach($gallery_Xml->album as $albums)
{
echo '<h3>' . $albums->name . '</h3>';
foreach($albums->image as $image)
{
echo '<h4>' . $image->title . '</h4>';
echo '<img src="' . $image->imgfile . '" alt="' . $image->title. '" />';
}
}
The above code will loop through each album, spit out the name of the album and then loop through the images in each album.

I've never used the SimpleXMLElement class, so I'm assuming I used it correctly but change if need be.

Hope that gets you what you wanted. Look over the code carefully and make sure you understand what I did.

-Shane

moos3
08-15-2007, 07:05 PM
What is its doing is not spitting out the information. But thanks to TheShanner
the following fixed that


foreach($gallery_Xml->album as $albums)
{
echo '<h3>' . $albums->name . '</h3>';
foreach($albums->image as $image)
{
echo '<h4>' . $image->title . '</h4>';
echo '<img src="' . $image->imgfile . '" alt="' . $image->title. '" />';
}
}

The only thing is now i need to figure out how to make it return a certian album. $albumnanme = camp; then have it do a foreach. I think it would be done like so


if(!empty($albumname)){
foreach($gallery_Xml->album as $albums){
echo '<h3>' . $albums->name . '</h3>';
foreach($albums->image as $image){
echo '<h4>' . $image->title . '</h4>';
echo '<img src="' . $image->imgfile . '" alt="' . $image->title. '" />';
}
}
}
else{
foreach($gallery_Xml->album as $albums){
echo '<h3>' . $albums->name . '</h3>';
echo '<img src="' . $image[0]->imgfile . '" alt="' . $image->title. '" />';
}
}

Any ideas?

GJay
08-15-2007, 08:05 PM
Xpath is one (quite straightforward) way of doing what you want:



<?php
$xml = simplexml_load_file('/path/to/file.xml');
$predicate = "//name[.='Camp']/ancestor::album";
$album = current($xml->xpath($predicate));
echo $album->name;
echo $album->desc;
?>

It's basically an expression that allows you to select from XML docs, saying 'return all albums that are the ancestor of a node with text="Camp"'.
$xml->xpath() returns an array of SimpleXMLElements which you can access in the normal way; selecting, as I have done, the name and description of whatever else.

Useful links:
http://uk.php.net/manual/en/function.simplexml-element-xpath.php
http://en.wikipedia.org/wiki/XPath
http://www.w3schools.com/xpath/

moos3
08-15-2007, 08:13 PM
so that will return all all the images in that album?

GJay
08-15-2007, 08:22 PM
it will return the album node, getting the images you loop over $album->image:


$xml = simplexml_load_file('/path/to/file.xml');
$predicate = "//name[.='Camp']/ancestor::album";
$album = current($xml->xpath($predicate));
echo '<h1>'.$album->name.'</h1>';
echo '<p>'.$album->desc.'</p>';
foreach($album->image as $image) {
echo '<h2>'.$image->title.'</h2>';
echo '<img src="/'.$image->imgfile.'" />';
}


will display the album's title and description, followed by all the images+their titles.

moos3
08-15-2007, 08:41 PM
Cool. thanks for the help.

moos3
08-15-2007, 09:11 PM
I think something is wrong but this should work.


function getAlbum($album){
echo $album;
$xml = simplexml_load_file('gallery/gallery.xml');
$predicate = "//name[.='{$album}']/ancestor::album";
$album = current($xml->xpath($predicate));
echo '<h1>'.$album->name.'</h1>';
echo '<p>'.$album->desc.'</p>';
foreach($album->image as $image) {
echo '<h2>'.$image->title.'</h2>';
echo '<img src="/'.$image->imgfile.'" />';
}
}

its getting the pasted album name campstring(32) "//name[.='camp']/ancestor::album"
but when it gets to $album its returning campbool(false) according to var_dump. Ideas?

GJay
08-15-2007, 10:54 PM
in the XML it's 'Camp' with a capital C.

I think the predicate //name[lower-case(self)='camp']/ancestor::album should be what you want, but when I try that PHP complains about a function not found, and core-dumps, which is odd...

moos3
08-16-2007, 04:36 AM
I even tried a match in the XML Camp and no images.

moos3
08-16-2007, 05:14 AM
ok got it working but trying to figure out how to handle albums that don't exist.


echo '<div class="gallery">';
$xml = simplexml_load_file('gallery/gallery.xml');
$copyright = (string)$xml->information->copyright;
$predicate = "//name[.='{$album}']/ancestor::album";
$albums = current($xml->xpath($predicate));
if($albums == true){
echo '<h2>'.$album->name.'</h2>';
echo '<p>'.$album->desc.'</p>';
foreach($album->image as $image) {
echo '<a href="'.$image->imgfile.'" rel="lightbox['.$imgcell.']" title="'.$image->title.'"><img src='.$image->imgfile.' width="100" height="75" /></a>';
}
}
else{
echo "Sorry the Album your looking for isn't here!";
}
echo "<br />";
echo '<br />'.
'<div class="info">'.$copyright.' Powered by <a href="http://labs.guthnur.net/scripts/scripts.php">m3xml Gallery</a></div>'
.'</div>';

I'm getting the following errors


Warning: SimpleXMLElement::xpath() [function.SimpleXMLElement-xpath]: Invalid predicate in /home/richard/labs/gallery/gallery.php on line 69

Warning: SimpleXMLElement::xpath() [function.SimpleXMLElement-xpath]: xmlXPathEval: evaluation failed in /home/richard/labs/gallery/gallery.php on line 69

Warning: current() [function.current]: Passed variable is not an array or object in /home/richard/labs/gallery/gallery.php on line 69

Ideas?



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum