DOMElement replace HTML value

北慕城南 提交于 2019-12-24 15:26:06

问题


I have this HTML string in a DOMElement:

<h1>Home</h1>
test{{test}}

I want to replace this content in a way that only

<h1>Home</h1>
test

remains (so I want to remove the {{test}}).

At this moment, my code looks like this:

$node->nodeValue = preg_replace(
    '/(?<replaceable>{{([a-z0-9_]+)}})/mi', '' , $node->nodeValue);

This doesn't work because nodeValue doesn't contain the HTML value of the node. I can't figure out how to get the HTML string of the node other than using $node->C14N(), but by using C14N I can't replace the content. Any ideas how I can remove the {{test}} in an HTML string like this?


回答1:


Have you tried the DOMDocument::saveXML function? (http://php.net/manual/en/domdocument.savexml.php)

It has a second argument $node with which you can specify which node to print the HTML/XML of.

So, for example:

<?php

$doc = new DOMDocument('1.0');
// we want a nice output
$doc->formatOutput = true;

$root = $doc->createElement('body');
$root = $doc->appendChild($root);

$title = $doc->createElement('h1', 'Home');
$root->appendChild($title);

$text = $doc->createTextNode('test{{test}}');
$text = $root->appendChild($text);

echo $doc->saveXML($root);

?>

This will give you:

<body>
  <h1>Home</h1>
  test{{test}}
</body>

If you do not want the <body> tag, you could cycle through all of its childnodes:

<?php

foreach($root->childNodes as $child){    
    echo $doc->saveXML($child);
}

?>

This will give you:

<h1>Home</h1>test{{test}}

Edit: you can then of course replace {{test}} by the regex that you are already using:

<?php

$xml = '';
foreach($root->childNodes as $child){    
    $xml .= preg_replace(
                '/(?<replaceable>{{([a-z0-9_]+)}})/mi', '', 
                $doc->saveXML($child)
    );
}

?>

This will give you:

<h1>Home</h1>test

Note: I haven't tested the code, but this should give you the general idea.




回答2:


The issue is mainly around how you navigate the DOM but there's also an issue with your RegExp; XPath actually provides a lot of flexibility when it comes to DOM manipulation so that's my preferred solution.

Assuming you have a DOMDocument built like this (I've attached an XPath):

$dom = new DOMDocument('1.0', 'utf-8');
$xpath = new DOMXPath($dom);

$node = $dom->createElement('div');
$node->appendChild(
    $dom->createElement('h1', "Home")
    );
$node->appendChild(
    $dom->createTextNode("test{{test}}")
    );

$dom->appendChild($node);

You can specifically target the text node of that <div> with '/div/text()' in XPath.

So to replace {{test}} within that text node without corrupting the rest of the node, you would do:

$xpath->query('/div/text()')->item(0)->nodeValue = preg_replace(
        '/(.*){{[^}]+}}/m', 
        '$1',
        $xpath->query('/div/text()')->item(0)->nodeValue
);

Somewhat convoluted but the output from $dom->saveXML(); is:

<?xml version="1.0" encoding="utf-8"?>
<div><h1>Home</h1>test</div>

{{test}} has been removed leaving the rest intact.



来源:https://stackoverflow.com/questions/37964378/domelement-replace-html-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!