4

I'm using the following script for a lightweight DOM editor. However, nodeValue in my for loop is converting my html tags to plain text. What is a PHP alternative to nodeValue that would maintain my innerHTML?

$page = $_POST['page'];
$json = $_POST['json'];

$doc = new DOMDocument();
$doc = DOMDocument::loadHTMLFile($page);

$xpath = new DOMXPath($doc);
$entries = $xpath->query('//*[@class="editable"]');
$edits = json_decode($json, true);
$num_edits = count($edits);

for($i=0; $i<$num_edits; $i++) 
{
    $entries->item($i)->nodeValue = $edits[$i]; // nodeValue strips html tags
}

$doc->saveHTMLFile($page);

2 Answers 2

3

Since $edits[$i] is a string, you need to parse it into a DOM structure and replace the original content with the new structure.

Update

The code fragment below does an incredible job when using non-XML compliant HTML. (e.g. HTML 4/5)

for($i=0; $i<$num_edits; $i++)
{
    $f = new DOMDocument();
    $edit = mb_convert_encoding($edits[$i], 'HTML-ENTITIES', "UTF-8"); 
    $f->loadHTML($edit);
    $node = $f->documentElement->firstChild;
    $entries->item($i)->nodeValue = "";
    foreach($node->childNodes as $child) {
        $entries->item($i)->appendChild($doc->importNode($child, true));
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

This feels a bit like cheating since I worked on the original code, but it's a common enough problem that maybe others will benefit from this post. :-)
Haha - I had posted this question before you answered it in the other post:). Thanks again! Worth noting, using appendXML, I did have to replace some special characters .replace(/&nbsp;/gi, "&#160;").replace(/<br>/gi, '<br />'); to get it to parse correctly, but all is working well!
@Josiah: I guess I should have tested more. :-) Anyway, I updated the answer with improved code so you don't have to resort to replace. It handles HTML (not XML), even if it contains UTF-8 characters.
0

I haven't working with that library in PHP before, but in my other xpath experience I think that nodeValue on anything other than a text node does strip tags. If you're unsure about what's underneath that node, then I think you'll need to recursively descend $entries->item($i)->childNodes if you need to get the markup back.

Or...you may wany textContent instead of nodeValue: http://us.php.net/manual/en/class.domnode.php#domnode.props.textcontent

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.