I want to read an SVG file and get the SVG tag from this file (because I want to show svg in html e.g. <div><svg>...</svg></div> without the xml header).
And show this svg tag in browser like HTML - print this SVG TAG like SVG image. Becouse now I'm gettong wrong output "DOMNodeList Object ( [length] => 1 ) ".
PHP
$doc = new DOMDocument();
$doc->load('http://example.com/logo.svg');
$svg = $doc->getElementsByTagName('svg');
echo "<div style='width: 100%, height: 100%; '>";
print_r($svg); // DOMNodeList Object ( [length] => 1 )
echo "</div>";
I found solution, but it is not exactly the answer for my question. So I will not mark it as a answer, but I leave here this solution. Maybe there will be somebody who will need it... :)
I just read file content, then I look for position of string "< svg" , and then substract this piece of code.
PHP
<?php
$svg_file = file_get_contents('http://example.com/logo.svg');
$find_string = '<svg';
$position = strpos($svg_file, $find_string);
$svg_file_new = substr($svg_file, $position);
echo "<div style='width:100%; height:100%;' >" . $svg_file_new . "</div>";
?>
You were definitely on the right track with you first attempt. I could spot two small problems though:
As you may have guessed, you tried to output a DOMNodeList object, which is what you will get from a call to getElementsByTagName. As the name implies, it is not a single node object but a collection of those so you would be interested in just the first found svg node (item(0) in code below).
DOM* instances do not automatically get converted into strings when printed. Use the C14N() method instead for output.
Code:
$svg_file = <<<END_OF_SVG
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width='300px' height='300px'>
<title>Test</title>
<circle cx='150' cy='150' r='70' style='fill: gold;' />
</svg>
END_OF_SVG;
$doc = new DOMDocument();
$doc->loadXML($svg_file);
$svg = $doc->getElementsByTagName('svg');
echo '<div style="width: 100%; height: 100%;">';
echo $svg->item(0)->C14N();
echo '</div>';
This seems to be the first hit for this topic in Google. Based on the other replies and what the original question was about, the answer to the original question is that getElementsByTagName returns an array, so you need to take the the first item in that array and use the saveHTML() method of DOMDocument. I made a short utility function to do just that.
function print_svg($file){
$iconfile = new DOMDocument();
$iconfile->load($file);
echo $iconfile->saveHTML($iconfile->getElementsByTagName('svg')[0]);
}
Related
I'm trying to get full accurate img tags from a html code using DOM:
$content=new DOMDocument();
$content->loadHTML($htmlcontent);
$imgTags=$content->getElementsByTagName('img');
foreach($imgTags as $tag) {
echo $content->saveXML($tag); }
If i had the original <img src="img">, the result would be <img src="img"/>. But i need the exact value corresponding to the original.
It is possible - to get the exact img tag using DOM without regular expressions or thirdparty libraries (Simple HTML DOM)?
No. It isn't possible to do this.
However, you can achieve your goal of removing the <img> elements from an HTML document if they meet specific conditions using DOMDocument. Here's some sample code which removes images which contain the class attribute "removeme".
$htmlcontent =
'<!DOCTYPE html><html><head><title>Example</title></head><body>'
. '<img src="1"><img src="2" class="removeme"><img src="3"><img class="removeme" src="4">'
. '</body></html>';
$content=new DOMDocument();
$content->loadHTML($htmlcontent);
foreach ($content->getElementsByTagName('img') as $image) {
if ($image->getAttribute("class") == "removeme") {
$image->parentNode->removeChild($image);
}
}
echo $content->saveHTML();
Output:
<!DOCTYPE html> <html><head><title>Example</title></head><body><img src="1"><img src="3"></body></html>
New to PHP so don`t be mad if the question is really stupid.
i have made this code :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>
img {float: left; margin-right: 30px; margin-bottom: 10px;}
</style>
<script src="js/jquery-1.7.2.min.js"></script>
<script src="js/lightbox.js"></script>
<link href="css/lightbox.css" rel="stylesheet" />
<title>Untitled Document</title>
</head>
<body>
<?php
// specify url of xml file
$url = "http://travelplaza.ro/turcia/belek/Belek.xml" ;
// get xml file contents
$xml = simplexml_load_file($url);
// loop begins
foreach ($xml->hotel[0] as $hotel) {
echo $hotel["hotelname"];
echo " ";
echo $hotel["stars"];
echo "<p>";
echo $hotel->description . "</br>";
echo "</p>";
echo "<p>";
echo "</p>";
}
foreach ($xml->hotel[0]->images[0] as $i) {
echo '<a href="' . $i["url"] . '" rel="lightbox"><img src="' . $i["url"] . '" width="100" height="100">';
echo "</a>";
}
Above is the xml itself..of course there are many hotels.
The result that i want is to have the title, description and pictures from the feed for the first hotel , then the second one and so on.
Instead i get only the images. If i remove the atributes [0] it gives a list with al the hotels with name , description and pics. Where is my mistake? I just want to show the hotel,description and the images. Any help would be apreciated.
Thank you.
EDIT: If i want to show only hotel[45] with description and images ?
the xml looks like so :
<hotels>
<hotel hotelcode="xxx">
<description>
bla bla
</description>
<images>
<image url="http"/>
</images>
</hotel>
The above repeats and on the last one i have the end tag.
The xml file is like this:
http://travelplaza.ro/turcia/belek/Belek.xml
Since you don't post the content of that xml file we can only guess its content...
Most likely $xml->hotel is an array of hotels. However you iterate over the frist element in that, not over the list of hotels. Try this instead:
foreach($xml->hotel as $hotel)
For the images: most likely you have to place the second foreach loop addressing the images inside the first loop, since each hotel most likely can hold references to several images. So the second loop should look something like this:
foreach($hotel->images as $i)
So the final code probably is meant to be like this:
$url = "http://travelplaza.ro/turcia/belek/Belek.xml";
// get xml file contents
$xml = simplexml_load_file($url);
// loop over the hotels
foreach($xml->hotel as $hotel){
echo $hotel["hotelname"]." ".$hotel["stars"]."\n";
echo "<p>\n".$hotel->description."\n</p>\n";
// loop this hotels images
echo "<p>\n";
foreach($hotel->images as $image) {
echo '<a href="'.$image["url"].'" rel="lightbox">'."\n";
echo '<img src="'.$image["url"].'" width="100" height="100">'."\n";
echo "</a>"\n;
}
echo"</p>\n";
}
But as said: without more details we can only guess...
hotel[0] means the first hotel in the list; when you loop over that, SimpleXML assumes you want its children. In this case, each hotel has two children, one description and one images.
You want each hotel in turn, that is, all the elements called hotel so remove the [0]:
foreach($xml->hotel as $hotel)
For the images, you want to get them at the same time as the name and description, but you have two separate loops, so you don't start looking at images until you've displayed all the descriptions.
Move the image loop inside the main loop, and change it to look at whichever hotel you're currently examining. Again, you don't want the [0], but looking at the XML there are multiple image elements inside one images element, so you need this:
foreach($hotel->images->image as $i)
(The [0] in this case sort of works as well, because $hotel->images[0] is the first and only images element, and its children are the individual image elements. I think the above better shows your intention.)
try this:
<?php
$url = "http://travelplaza.ro/turcia/belek/Belek.xml";
// get xml file contents
$xml = simplexml_load_file($url);
// loop begins
foreach($xml->hotel as $hotel) {
echo <<<EOD
<div>
<p>{$hotel['hotelname']}</p>
<p>{$hotel['stars']};</p>
<p>{$hotel->description}</p>
<p>
EOD;
foreach ($hotel->images[0] as $i) {
echo <<<EOD
<p>
<img src="{$i["url"]}" width="100" height="100">'
</p>
EOD;
}
echo <<<EOD
</div>
EOD;
}
?>
Im trying to display the latest 5 images from:
http://api.flickr.com/services/feeds/photos_public.gne
with the tag "cars" and then output the latest 5 thumbnails into a blank html document as a type of gallery.
This is as far as i have gotten:
<?php
require_once 'HTTP/Request2.php';
$request = new HTTP_Request2();
$request->setUrl('http://api.flickr.com/services/feeds/photos_public.gne');
$request->setMethod(HTTP_Request2::METHOD_GET);
$url = $request->getUrl();
$url->setQueryVariable('tags', 'cars');
$url->setQueryVariable('tagmode', 'any');
$url->setQueryVariable('format', 'atom_1');
try {
$response = $request->send();
if (200 == $response->getStatus()) {
$body = $response->getBody();
} else {
echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .
$response->getReasonPhrase();
}
} catch (HTTP_Request2_Exception $e) {
echo 'Error: ' . $e->getMessage();
}
$DOM = new SimpleXMLElement($body);
?>
I don't know if this is correct and i'm not sure how to go about displaying it in html.
After looking into the feed of your question, it shows that each item does not have an image element. Therefore accessing it will give you NULL which is echoed as an empty string (invisible):
foreach ($DOM->entry as $entry) {
echo '', htmlspecialchars($entry->title), '', "\n",
'<img src="', $entry->image, '" alt="', htmlspecialchars($entry->title), '" ',
'width="304" height="228">', "\n";
;
}
The exemplary output shows that the title is available, but the image src is empty:
Picadas, Marco Juarez 01-05-13
<img src="" alt="Picadas, Marco Juarez 01-05-13" width="304" height="228">
Looking closer into the feed itself it turns out that there is not even any other element containing the thumbnail but the HTML text inside the conent element. And only inside that HTML there are the dimensions of the thumbnail image:
<entry>
<title>Picadas, Marco Juarez 01-05-13</title>
<link rel="alternate" type="text/html" href="http://www.flickr.com/photos/osvaldorainero/8709806523/"/>
<id>tag:flickr.com,2005:/photo/8709806523</id>
<published>2013-05-05T15:25:15Z</published>
<updated>2013-05-05T15:25:15Z</updated>
<flickr:date_taken>2013-05-01T15:42:01-08:00</flickr:date_taken>
<dc:date.Taken>2013-05-01T15:42:01-08:00</dc:date.Taken>
<content type="html"> <p><a href="http://www.flickr.com/people/osvaldorainero/">Osvaldo Rainero</a> posted a photo:</p>
<p><a href="http://www.flickr.com/photos/osvaldorainero/8709806523/" title="Picadas, Marco Juarez 01-05-13"><img src="http://farm9.staticflickr.com/8114/8709806523_3b8d7c0418_m.jpg" width="240" height="161" alt="Picadas, Marco Juarez 01-05-13" /></a></p>
</content>
<author>
<name>Osvaldo Rainero</name>
<uri>http://www.flickr.com/people/osvaldorainero/</uri>
<flickr:nsid>91267729#N05</flickr:nsid>
<flickr:buddyicon>http://farm9.staticflickr.com/8107/buddyicons/91267729#N05.jpg?1363607055#91267729#N05</flickr:buddyicon>
</author>
<link rel="enclosure" type="image/jpeg" href="http://farm9.staticflickr.com/8114/8709806523_3b8d7c0418_b.jpg"/>
<category term="cars" scheme="http://www.flickr.com/photos/tags/"/>
...
<category term="arrancadas" scheme="http://www.flickr.com/photos/tags/"/>
</entry>
Zoom:
<content type="html"> <p><a href="http://www.flickr.com/people/osvaldorainero/">Osvaldo Rainero</a> posted a photo:</p>
<p><a href="http://www.flickr.com/photos/osvaldorainero/8709806523/" title="Picadas, Marco Juarez 01-05-13"><img src="http://farm9.staticflickr.com/8114/8709806523_3b8d7c0418_m.jpg" width="240" height="161" alt="Picadas, Marco Juarez 01-05-13" /></a></p>
</content>
This is HTML encoded in XML. And this is kind of a show-stopper for simplexml you use, because it can only return the HTML verbatim out of the box:
echo $entry->content, "\n";
Output (plain text):
<p>Osvaldo Rainero posted a photo:</p>
<p><img src="http://farm9.staticflickr.com/8114/8709806523_3b8d7c0418_m.jpg" width="240" height="161" alt="Picadas, Marco Juarez 01-05-13" /></p>
This is the important part to understand: You do not only want to parse the XML from the feed, but you additionally want to parse HTML inside the node-value of an XML element.
So you need to extend the SimplexmlElement you use with a HTML parser. That is easy to do because if your PHP version ships with simplexml, it also ships with DOMDocument which has an HTML parser and it can return the parsed result as simplexml so this is pretty compatible.
So the following extends simplexml with a HTML parser:
class HtmledSimpleXML extends SimpleXMLElement
{
/**
* Parses element content as HTML and returns the
* body element of it.
*
* #param string $xpath (optional) specify a different element to return
*
* #return SimpleXMLElement
*/
public function html($xpath = '//body') {
$doc = new DOMDocument();
$doc->loadHTML($this);
$xml = simplexml_import_dom($doc->documentElement);
list($body) = $xml->xpath($xpath);
return $body;
}
}
It already allows to pass an xpath query to specify the concrete element you want to retrieve, normally that is the body tag from inside the HTML this is why it is set as default. Even if your HTML does not have that tag in there, it actually exists in the DOM, therefore this default is never wrong. But anyway in your case you're interested in the img tag. Thanks to simpelxml we can even output it directly as XML and can spare to even create the HTML by hand.
Usage example:
$DOM = new HtmledSimpleXML($body);
foreach ($DOM->entry as $entry) {
echo '', $entry->title, '', "\n",
$entry->content->html('//img')->asXML(), "\n";
;
}
The exemplary output for a single entry then is:
Picadas, Marco Juarez 01-05-13
<img src="http://farm9.staticflickr.com/8114/8709806523_3b8d7c0418_m.jpg" width="240" height="161" alt="Picadas, Marco Juarez 01-05-13"/>
Which should come pretty close to what you're looking for. Naturally you can as well just aquire the image-element and access it's attributes like with any other Simplexmlelement:
$thumb = $entry->content->html('//img');
echo 'Title: ', $entry->title, "\n",
'Thumb: ', $thumb['src'], "\n",
'Size : ', $thumb['width'], ' x ', $thumb['height'], "\n";
Output (plain text):
Title: Picadas, Marco Juarez 01-05-13
Thumb: http://farm9.staticflickr.com/8114/8709806523_3b8d7c0418_m.jpg
Size : 240 x 161
I hope this is helpful so far.
Last time I extended SimpleXMLElement on Stackoverflow was to show how to parse CSV data inside the underlying XML structure in PHP simplexml xpath search for value in an ELEMENT containing tab delimited text?.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Remove style attribute from HTML tags
Current image looks like
<img src="images/sample.jpg" alt="xyz"/>
Now I want to remove all such alt tags present in all the tags in HTML file, the PHP code itself should replace all the alt attribute appearances.
The output should be like
<img src="images/sample.jpg" /> only
How can be done with php?
Thanks in Advance
Use DOMDocument for HTML parsing/manipulation. The example below reads a HTML file, removes the alt attribute from all img tags, then prints out the HTML.
$dom = new DOMDocument();
$dom->loadHTMLFile('file.html');
foreach($dom->getElementsByTagName('img') as $image)
{
$image->removeAttribute('alt');
}
echo $dom->saveHTML(); // print the modified HTML
Read your file. You can use file_get_contents() to read a file
$fileContent = file_get_contents('filename.html');
$fileContent = preg_replace('/alt=\"(.*)\"/', '', $fileContent);
file_put_contents('filename.html', $fileContent);
Make sure your file is writable
First, you need to get a hold on the document source you want to modify. It's not clear if you want to edit some html files on your server, edit the html output generated by a request or what...
In this answer I'm gonna step over on how you get to the HTML. It could be a file_get_contents('filename.html'); or some magic with output buffering.
Since you don't want to parse HTML with regular expressions you need to use a parser:
Since the alt attribute is required for the HTML to be valid, if you want to "remove" it you have to set it to an empty string.
This should work:
$doc = DOMDocument::loadHTML($myhtml);
$images = $doc->getElementsByTagName('img');
foreach($images as $img) {
$image->setAttribute('alt', '');
}
$myhtml = $doc->saveHTML();
For valid xHTML it should have the alt attribute.
Something like this would work:
$xml = new SimpleXMLElement($doc); // $doc is the html document.
foreach ($xml->xpath('//img') as $img_tag) {
if (isset($img_tag->attributes()->alt)) {
unset($img_tag->attributes()->alt);
}
}
$new_doc = $xml->asXML();
I want to do something like:
<?php
$text = "<font style='color: #fff'>";
$replaceandshow = str_replace("<font style=\"?\">", "the font style is ?", $text);
echo $replaceandshow;
?>
For example the ? is color: #fff, but I want that PHP will trace it by itself, Is it possible + If it's possible , How can I do that?
P.S: Someone gave me a code but it's now working, it displays a White page for me.
<?php
$colorstring = "<font style='#fff'>";
$searchcolor = preg_replace('[a-fA-F0-9]{3,6}','[font style=$1]Test[/font]',$colorstring);
echo $searchcolor;
Thanks for helping.
You are getting white page because error reporting is turned off. The error in your code is missing delimiter in preg_replace. And additionally, to use back-referencing you should enclose the expression required to match in parentheses.
preg_replace('/([a-fA-F0-9]{3,6})/','the font style is $1',$colorstring);
shall give the correct output.
You might consider using a more constrictive expression because the current expression is very open to matching other strings like "FFFont". Another thing to note is that the expression may result in output like.
<font style='color: the color is #fff'>
Try:
/<font style='color: #([a-fA-F0-9]{3,6})'>/
Since you need to pull basically any attribute out of any HTML you can use php XML parsing to do this.
<?php
$doc=new DOMDocument();
$doc->loadHTML("<html><body>Test<br><font style='color: #fff;'>hellow</font><a href='www.somesite.com' title='some title'>some site</a></body></html>");
$xml=simplexml_import_dom($doc); // just to make xpath more simple
$fonts=$xml->xpath('//font');
foreach ($fonts as $font) {
echo 'font style = '.$font['style']."<br />";
}
$as=$xml->xpath('//a');
foreach ($as as $a) {
echo 'href = '.$a['href'] . ' title = ' . $a['title']."<br />";
}
?>
That will return:
font style = color: #fff;
href = www.somesite.com title = some title
You can use a different foreach loop for each HTML tag you need to extract and then output any of the attributes you want.
Answer based on How to extract img src, title and alt from html using php?
This will work with simple style attributes:
$text = "<font style='color: #fff'>";
preg_match("/<font style=['\"]([^'\"]+)['\"]>/", $text, $matches);
echo "The font style is ".$matches[1];
For anything more complicated (ex: if it includes quotes), you'll need to use a HTML parser, such as http://www.php.net/manual/en/class.domdocument.php