Place XML entries at the top using SimpleXML
I'm 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>
However, 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 childs that I add, should go before the last it has added to the xml, like
<imagegallery>
<ima开发者_Python百科ge attr="HEREGOESTHENEWST">
<caption>description</caption>
</image>
<image attr="THEOLDONE">
<caption>description</caption>
</image>
</imagegallery>
How can I achieve this?
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()
oraddChild()
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);
i'd suggest using DOM api instead of simplexml. insertBefore seems to be what you're looking for.
精彩评论