views:

312

answers:

2

Im using SimpleXML to add new images childs for a slideshow tool on my website, the code is something like this:

$xml_toload = $_SERVER['DOCUMENT_ROOT']. '/xml/'.$country.'/compact.xml';
$xml = simplexml_load_file($xml_toload); //This line will load the XML file. 

$sxe = new SimpleXMLElement($xml->asXML());
//In this line it create a SimpleXMLElement object with the source of the XML file. 
//The following lines will add a new child and others child inside the previous child created. 
$image = $sxe->addChild('image');
$image->addAttribute('imageURL',$file);
$image->addAttribute('thumbURL',$file);
$image->addAttribute('linkURL',$linkurl);
$image->addAttribute('linkTarget',$linkurl);
$image->addChild('caption',$caption);

$sxe->asXML($xml_toload);

Which is working perfectly to add the new <image attr="blabla"><caption>imageinfo</caption><image> child, inside of <imagegallery></imagegalley>

But I have a serious problem, I need this childs to go just after <imagegallery>, not before the tag is closed, (one after other), this makes to appear new images, at the last place on the imagegallery slideshow.

So the newest chids that I add, should go before the last it has added to the xml, like

<imagegallery>
<image attr="HEREGOESTHENEWST">
    <caption>description</caption>
</image>
<image attr="THEOLDONE">
    <caption>description</caption>
</image>
</imagegallery>

Anyone can help me with a clear example? Thank you, its urgent!

A: 

i'd suggest using DOM api instead of simplexml. insertBefore seems to be what you're looking for.

stereofrog
A: 

SimpleXML doesn't support that kind of manipulation. Currently, it can only append children. To insert children at arbitrary places in the tree, you need DOM and DOMNode::insertBefore() specifically. The problem is that DOM is verbose and it makes it annoying to use, that's why when I have to do that kind of things, I use a mixture of SimpleXML and DOM. The result became a library aptly named SimpleDOM: use DOM methods with SimpleXML grammar.

Also, here's a few tips that I recommend as good practice:

  • Whenever you create a SimpleXMLElement object, name it after the node it represents. Never name it $xml. "XML" is a markup language, it's text. If I'd see an $xml var I'd think it contains text.
  • The same applies to your $xml_toload var. It doesn't contain XML, it contains a filepath. Therefore, it should be named something like $filepath.
  • You don't have to use addAttribute() or addChild() for everything. It's often simpler to use the array notation and/or the object notation.

The result script:

include 'SimpleDOM.php';

// create an <image/> element
$image = new SimpleXMLElement('<image/>');
$image['imageURL']   = $file;
$image['thumbURL']   = $file;
$image['linkURL']    = $linkurl;
$image['linkTarget'] = $linkurl;
$image->caption      = $caption;

// load the file
$path_to_file = $_SERVER['DOCUMENT_ROOT']. '/xml/'.$country.'/compact.xml';
$imagegallery = simpledom_load_file($path_to_file);

// insert the new element before the first <image/>
$imagegallery->insertBefore($image, $imagegallery->image[0]);

// save the file
$imagegallery->asXML($path_to_file);
Josh Davis
Wow John, you surprised me with this answer, It was as clear as Hawaian Ocean water. I have to be honest, Ive been around PHP for long time, but never had the chance or the requirement to manipulate XML files, not my speciality
BoDiE2003