How to delete a particular XML child node based on their value - php

I have an XML structure like this:
<document>
<sliderimage>
<images>click.bmp</images>
<images>error_inotherpluginupload.JPG</images>
<images>dddd.jpg</images>
<images>Sunset123.jpg</images>
<images>Water lilies.jpg</images>
</sliderimage>
</document>
And I'm showing these images like this:
Code for fetching images you can see here :
<?php
$usernmeforxml = $_SESSION['username'];
$xmlpath = SITE_URL . "xml/" . $usernmeforxml . "/test.xml";
$xml = simplexml_load_string(file_get_contents($xmlpath));
$sliderimagesinner = $xml->sliderimage->images;
$imagenum = count($sliderimagesinner);
?>
</br>
<?php
for ($i = 0; $i < $imagenum; $i++)
{
?>
<a class="thumbnail" href="#thumb">
<img src="../slider_images/<?php
echo $sliderimagesinner[$i];
?>" width="120" height="70" />
<span>
<img src="../slider_images/<?php
echo $sliderimagesinner[$i];
?>" width="500" height="350" />
</span>
</a>
<?php
}
?>
Now i want to delete the image by adding a "delete" button on my images. When clicked, that image node should be deleted from the above XML file.
All things are dynamic, so it would be very helpful if anyone can help me regarding this.

$usernmeforxml=$_SESSION['username'];
$xmlpath=SITE_URL."xml/".$usernmeforxml."/test.xml";
$xml = simplexml_load_file($xmlpath);
if($_GET['remove'] == 'true') {
$myValue = $_GET['file'];
$xel_array = $xml->xpath("//images[text()='" . $myValue . "']");
//edited - forgot to double [0]
unset($xel_array[0][0]);
file_put_contents($xmlpath, $xml->asXML());
}
and a link like
remove
should do the trick.

Related

Grabbing an attribute with DOMXPath

i know there are lots of way to grabbing an attribute.
this is my html result :
<li class="result">
<a class="block_container" href="**FIRST**">
<img alt="changeable text" src="**SOME LINK**" border="0">
</a>
</li>
<li class="result">
<a class="block_container" href="**SECOND**">
<img alt="changeable text" src="**SOME LINK**" border="0">
</a>
</li>
//and many like this ...
i can grab (href) but i have many of this attribute !
i used DOMXPath query to help me choose grab first href or second href with item number :
$a = $xpath->query("//li[#class='block_container']/a");
echo $text = $a->item(**MY ITEM NUMBER**)->nodeValue;
but it doesn't work !
can you help me grab href and src with item number ?
if you want a.href
$hrefs = $xpath->query("//li/a[#class='block_container']/#href");
foreach($hrefs as $href) {
echo $href->nodeValue ."<br>\n";
}
and if you want outerHTML of image tag
$imgs = $xpath->query("//li/a[#class='block_container']/img");
foreach($imgs as $img) {
echo $dom->saveHTML($img) ."<br>\n";
}
demo on eval.in

PHP - Remove a child with a specific attribute selected

I’m trying to figure out how to remove a child with a specific attribute selected (filename). I have PHP displaying an XML file on a page that loads images. If someone where to click on any image or hit the delete button -
<img src="' . $child['src'] . '" alt="gallery image" />Delete me
it would know where to find in the XML file and delete it.
Here what loads and displays my XML file:
<?php
$xml = simplexml_load_file('myPhotos.xml');
//echo $xml->getName() . "<br />";
foreach ($xml->children() as $child)
{
echo '<img src="' . $child['src'] . '" alt="gallery image" />';
}
?>
Here is my XML structure:
<slideshow>
<image src="myPhotosResized/image1.jpg" desc="This is the 1st image!" />
<image src="myPhotosResized/image2.jpg" desc="This is the 2nd image!" />
<image src="myPhotosResized/image3.jpg" desc="This is the 3rd image!" />
<image src="myPhotosResized/image4.jpg" desc="This is the 4th image!" />
</slideshow>
Assuming that you want to actually delete the file (and not just remove it from the DOM), either use Ajax or wrap your images with a link that is targeting a script to delete the file:
With Ajax:
<?
$xml = simplexml_load_file('myPhotos.xml');
//echo $xml->getName() . "<br />";
foreach ($xml->children() as $child)
{
echo '<img src="' . $child['src'] . '" alt="gallery image" onclick="deleteFile('.$child["src"].')" />';
}
?>
<script>
function deleteFile(filename) {
var t = this;
$.ajax({
url: 'deleteFile.php?filename='+filename,
type: 'post',
success: function(data) {
t.style.display = 'none';//hide the link
alert('File deleted!');
}
});
}
</script>
And on your deleteFile.php you will need to use:
$filename = $_GET['filename'];//gets the file name from the URL
unlink($filename);//deletes the file
Second option:
If you must keep everything with PHP and not use jQuery or Ajax, you can simply wrap the images with a link and set its href to:
echo '<img src="' . $child['src'] . '" alt="gallery image" />';
Hope this helps
The key is to write your HTML properly and then write your jQuery to do the magic
Assuming your HTML is like this, give your elements class names
<img src="' . $child['src'] . '" class="deleteme" alt="gallery image" />Delete me
This jQuery code will do what you want. place it at the end of your file
<script>
$('.clicktodelete').click(function () {
$(this).prev('.deleteme').hide();
});
</script>

Parsing HTML to PHP

I hope you can help me with the following, i have a php method to scan a directory with pictures:
<?php
$dirname = "images/";
$images = scandir($dirname);
$ignore = Array(".", "..");
foreach($images as $curimg){
if(!in_array($curimg, $ignore)) {
echo "<li> class=\"portfolio-item-preview\" <img src=\"img/portfolio/portfolio-img-01.jpg\" /></li>\n ";
// echo "<li><img src=\"img.php?src=$dirname$curimg&w=300&zc=1\" alt='' /></li>\n ";
}
}
?>
I want to put the following code after the foreach loop:
<li class="one-fourth logos">
<p>
<img src="img/portfolio/portfolio-img-01.jpg" alt=" " width="210" height="145" class="portfolio-img pretty-box"/>
</p>
</li>
If I echo all the lines PHP generates all kinds of errors, could please someone help me with parsing the lines? I am just a beginner, sorry if it's very nooby:) I want this to create a class one-fourth logos for as long the folder contains images.
Just end your php code, put the HTML and reopen php.Like that:
?>
<li class="one-fourth logos">
<p>
<img src="img/portfolio/portfolio-img-01.jpg" alt=" " width="210" height="145" class="portfolio-img pretty-box"/>
</p>
</li>
<?php
Because your HTML doesn't contain single quotation marks (') you can put them around your HTML and it will be a valid string which you can echo:
echo '<li class="one-fourth logos">
<p>
<a href="images/project2/IMG_0268.jpg" class="portfolio-item-preview" data-rel="prettyPhoto">
<img src="img/portfolio/portfolio-img-01.jpg" alt=" " width="210" height="145" class="portfolio-img pretty-box">
</a>
</p>
</li>';

how do I get sets of data with xpath

My below code retrieves a series of images from the search results of a site and also the corresponding age data. It works fine however I get a list of images followed by a list of the information in the age field.
img img img img age age age age and so on.
How do I combine these so I can display them in sets: img age img age img age
<?php
error_reporting(-1);
$html = new DOMDocument();
#$html->loadHtmlFile('http://www.site.com/searchresults.html');
$xpath = new DOMXPath( $html );
$nodelist = $xpath->query( "//div[#class='age']" );
$tags = $html->getElementsByTagName('img');
foreach ($tags as $tag) {
$image = $tag->getAttribute('src');
echo '<img src='. $image .' alt="image" ><br>';
}
foreach ($nodelist as $n)
{
echo $n->nodeValue."<br>";
}
?>
Sample page, I want to extract the img source title data from <div class="age" title="30 usa">:
<div id="sr-15763292" class="search-result">
<div class="thumb-wrapper">
<a class="bioLink" href="http://www.site.com/user/" title="View user"><img src="http://www.site.com/img/15763292.jpg" class="thumb" alt="user" width="140" height="105"></a>
<p class="status"><a href="http://www.site.com/user/" >Online</a></p>
</div>
<div class="rating">
<div class="rating-stars rating4"></div>
</div>
<div class="age" title="30 usa">
<p>30</p>
<p class="gender m">m</p>
<p>USA</p>
</div>
<div>
<p class="headline">Hello there.</p>
</div>
</div>
It's hard to answer if we don't know what the HTML looks like! Assuming it looks something like this
<div class="age"><p>21</p>
<img src="a.jpg" />
</div>
<div class="age"><p>51</p>
<img src="b.jpg" />
</div>
you need to find each div and then find the image inside each div. getElementsByTagName() will give you a list even if there's only one result, so use item() to fetch the first.
error_reporting(-1);
$html = new DOMDocument();
#$html->loadHtmlFile('results.html');
$xpath = new DOMXPath( $html );
$nodelist = $xpath->query( "//div[#class='age']" );
foreach ($nodelist as $node) {
$tags = $node->getElementsByTagName('img');
$image = $tags->item(0)->getAttribute('src');
echo '<img src="'. $image .'" alt="image" ><br>';
echo $node->textContent . '<br>';
}
If the HTML is like this
<div class="age"><p>21</p></div><img src="a.jpg" />
you can try
$node->nextSibling()
As a general point trace through the HTML and think how do I get from A to B? Go forwards? backwards? up to parent, to the next node and down again ...?

PHP DOMDocument parse HTML

I have the following HTML markup
<div contenteditable="true" class="text"></div>
<div contenteditable="true" class="text"></div>
<div style="display: block;" class="ui-draggable">
<img class='avatar' src=""/>
<p style="">
<img class='pic' src=""/><br>
<span class='fulltext' style="display:none"></span>
</p>-<span class='create'></span>
<a class='permalink' href=""></a>
</div>
<div contenteditable="true" class="text"></div>
<div style="display: block;" class="ui-draggable">
<img class='avatar' src=""/>
<p style="">
<img class='pic' src=""/><br>
<span class='fulltext' style="display:none"></span>
</p><span class='create'></span><a class='permalink' href=""></a>
</div>
The parent div's can be more.In order to parse the information and to insert it in the DB I'm using the following code -
$dom = new DOMDocument();
$dom->loadHTML($xml);
$xpath = new DOMXPath($dom);
$div = $xpath->query('//div');
$i=0;
$q=1;
foreach($div as $book) {
$attr = $book->getAttribute('class');
//if div contenteditable
if($attr == 'text') {
echo '</br>'.$book->nodeValue."</br>";
}
else {
$new = new DOMDocument();
$newxpath = new DOMXPath($new);
$avatar = $xpath->query("(//img[#class='avatar']/#src)[$q]");
$picture = $xpath->query("(//p/img[#class='pic']/#src)[$q]");
$fulltext = $xpath->query("(//p/span[#class='fulltext'])[$q]");
$permalink = $xpath->query("(//a[#class='permalink'])[$q]");
echo $permalink->item(0)->nodeValue; //date
echo $permalink->item(0)->getAttribute('href');
echo $fulltext->item(0)->nodeValue;
echo $avatar->item(0)->value;
echo $picture->item(0)->value;
$q++;
}
$i++;
}
But I think that there's a better way for parsing the HTML. Is there? Thank you in advance
Note that DOMXPath::query supports a second param called contextparam. Also you won't need a second DOMDocument and DOMXPath inside the loop. Use:
$avatar = $xpath->query("img[#class='avatar']/#src", $book);
to get <img src=""> attribute nodes relative to the div nodes. If you follow my advices your example should be fine.
Here comes a version of your code that follows the above said:
$dom = new DOMDocument();
$dom->loadHTML($xml);
$xpath = new DOMXPath($dom);
$divs = $xpath->query('//div');
foreach($divs as $book) {
$attr = $book->getAttribute('class');
if($attr == 'text') {
echo '</br>'.$book->nodeValue."</br>";
} else {
$avatar = $xpath->query("img[#class='avatar']/#src", $book);
$picture = $xpath->query("p/img[#class='pic']/#src", $book);
$fulltext = $xpath->query("p/span[#class='fulltext']", $book);
$permalink = $xpath->query("a[#class='permalink']", $book);
echo $permalink->item(0)->nodeValue; //date
echo $permalink->item(0)->getAttribute('href');
echo $fulltext->item(0)->nodeValue;
echo $avatar->item(0)->value;
echo $picture->item(0)->value;
}
}
As a matter of fact, you do it the right way : html has to be parsed with a DOM object.
Then some optimisation can be brough :
$div = $xpath->query('//div');
is quite greedy, a getElementsByTagName should be more appropriate :
$div = $dom->getElementsByTagName('div');

Categories