Change outerHTML of a php DOMElement?
You can create a copy of the element content and attributes in a new node (with the new name you need), and use the function replaceChild()
.
The current code will work only with simple elements (a text inside a node), if you have nested elements, you will need to write a recursive function.
$dom = new DOMDocument;
$dom->loadHTML($html);
$titles = $dom->getElementsByTagName('h3');
for($i = $titles->length-1 ; $i >= 0 ; $i--)
{
$title = $titles->item($i);
$titleText = $title->textContent ; // get original content of the node
$newTitle = $dom->createElement('h5'); // create a new node with the correct name
$newTitle->textContent = $titleText ; // copy the content of the original node
// copy the attribute (class, style, ...)
$attributes = $title->attributes ;
for($j = $attributes->length-1 ; $j>= 0 ; --$j)
{
$attributeName = $attributes->item($j)->nodeName ;
$attributeValue = $attributes->item($j)->nodeValue ;
$newAttribute = $dom->createAttribute($attributeName);
$newAttribute->nodeValue = $attributeValue ;
$newTitle->appendChild($newAttribute);
}
$title->parentNode->replaceChild($newTitle, $title); // replace original node per our copy
}
libxml_clear_errors();
$html = $dom->saveHTML();
echo $html;
returning element altered by outerHTML
Consider the snippet below:
var element = document.createElement(null);console.log(element);document.body.appendChild(element);console.log(element);element.outerHTML = "<div id='hi'> hello there </div>";console.log(element);element = document.getElementById("hi");console.log(element);
Why do these two DOMDocument functions behave differently?
What this comes down to is even more simple than your test case above:
<?php
$html = '<p>ACME’s 27” Monitor is $200.</p>';
$dom = new DOMDocument();
@$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
echo $dom->saveHtml($dom->documentElement) . PHP_EOL;
echo $dom->saveHtml() . PHP_EOL;
So the question becomes, why does DomDocument::saveHtml
behave differently when saving an entire document instead of just a specific node?
Taking a peek at the PHP source, we find a check for whether it's working with a single node or a whole document. For the former, the htmlNodeDumpFormatOutput
function is called with the encoding explicitly set to null. For the latter, the htmlDocDumpMemoryFormat
function is used, the encoding is not included as an argument to this function.
Both of these functions are from the libxml2 library. Looking at that source, we can see that htmlDocDumpMemoryFormat
tries to detect the document encoding, and explicitly sets it to ASCII/HTML if it can't find one.
Both functions end up calling htmlNodeListDumpOutput
, passing it the encoding that's been determined; either null – which results in no encoding – or ASCII/HTML – which encodes using HTML entities.
My guess is that, for a document fragment or single node, encoding is considered less important than for a full document.
How to make out of an HTML text a DOM object
The solution should be like, you get the a HTML string with the contents. Then you use the $sce.trustAsHtml();
and assign to a scope variable which will ensure the HTML is safe then you can use the HTML below which has the directive ng-bind-html
to render the HTML String as actual HTML.
Here is a working example of the same.
var app = angular.module("angularApp", []);app.controller("appController", function($scope, $sce) { $scope.content = "This text is <em>html capable</em> meaning you can have <a href=\"#\">all</a> sorts <b>of</b> html in here."; $scope.output = $sce.trustAsHtml($scope.content);});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script><h2>Rendering HTML with angularJS</h2><div ng-app="angularApp" ng-controller="appController"> <div ng-bind-html="output"></div></div>
How to get html code of DOMElement node?
Use the optional argument to DOMDocument::saveHTML
: this says "output this element only".
return $node->ownerDocument->saveHTML($node);
Note that the argument is only available from PHP 5.3.6. Before that, you need to use DOMDocument::saveXML
instead. The results may be slightly different. Also, if you already have a reference to the document, you can just do this:
$doc->saveHTML($node);
How to get innerHTML of DOMNode?
Compare this updated variant with PHP Manual User Note #89718:
<?php
function DOMinnerHTML(DOMNode $element)
{
$innerHTML = "";
$children = $element->childNodes;
foreach ($children as $child)
{
$innerHTML .= $element->ownerDocument->saveHTML($child);
}
return $innerHTML;
}
?>
Example:
<?php
$dom= new DOMDocument();
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->load($html_string);
$domTables = $dom->getElementsByTagName("table");
// Iterate over DOMNodeList (Implements Traversable)
foreach ($domTables as $table)
{
echo DOMinnerHTML($table);
}
?>
Related Topics
Get Value from Simplexmlelement Object
Performance of Foreach, Array_Map With Lambda and Array_Map With Static Function
Pulling Track Info from an Audio Stream Using PHP
MySQL Prepared Statements With a Variable Size Variable List
Glob() - Sort Array of Files by Last Modified Datetime Stamp
How Does True/False Work in PHP
Secure Random Number Generation in PHP
PHP Fatal Error: Call to Undefined Function Curl_Init()
How to Truncate a String to the First 20 Words in PHP
PHP MySQL Google Chart Json - Complete Example
Run Process With Realtime Output in PHP
Login to Remote Site With PHP Curl
Simple PHP Post-redirect-get Code Example
Preserving Session Variables Across Different Domains
Where Does PHP'S Error Log Reside in Xampp
I Have an Array of Integers, How to Use Each One in a MySQL Query (In PHP)