У меня есть эта строка HTML в DOMElement
:
<h1>Home</h1>
test{{test}}
Я хочу заменить этот контент таким образом, чтобы только
<h1>Home</h1>
test
остается (поэтому я хочу удалить {{test}}
).
На данный момент мой код выглядит так:
$node->nodeValue = preg_replace(
'/(?<replaceable>{{([a-z0-9_]+)}})/mi', '' , $node->nodeValue);
Это не работает, потому что nodeValue
не содержит значение HTML узла.
Я не могу понять, как получить строку HTML узла, кроме как с помощью $node->C14N()
, но с помощью C14N
Я не могу заменить контент.
Любые идеи, как я могу удалить {{test}}
в строке HTML, как это?
Вы пробовали DOMDocument::saveXML
функционировать? (http://php.net/manual/en/domdocument.savexml.php)
У него есть второй аргумент $node
с помощью которого вы можете указать, какой узел для печати HTML / XML.
Так, например:
<?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);
?>
Это даст вам:
<body>
<h1>Home</h1>
test{{test}}
</body>
Если вы не хотите <body>
тег, вы можете перебрать все его дочерние узлы:
<?php
foreach($root->childNodes as $child){
echo $doc->saveXML($child);
}
?>
Это даст вам:
<h1>Home</h1>test{{test}}
Изменить: вы можете, конечно, заменить {{test}}
с помощью регулярного выражения, которое вы уже используете:
<?php
$xml = '';
foreach($root->childNodes as $child){
$xml .= preg_replace(
'/(?<replaceable>{{([a-z0-9_]+)}})/mi', '',
$doc->saveXML($child)
);
}
?>
Это даст вам:
<h1>Home</h1>test
Примечание: я не тестировал код, но это должно дать вам общее представление.
Проблема в основном связана с тем, как вы перемещаетесь по DOM, но есть также проблема с вашим RegExp; XPath на самом деле обеспечивает большую гибкость, когда дело доходит до манипулирования DOM, так что это мое предпочтительное решение.
Предполагая, что у вас есть DOMDocument, построенный следующим образом (я прикрепил 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);
Вы можете специально предназначаться для текстового узла этого <div>
с '/div/text()'
в XPath.
Чтобы заменить {{test}}
внутри этого текстового узла, не повреждая остальную часть узла, вы должны сделать:
$xpath->query('/div/text()')->item(0)->nodeValue = preg_replace(
'/(.*){{[^}]+}}/m',
'$1',
$xpath->query('/div/text()')->item(0)->nodeValue
);
Несколько запутанный, но выход из $dom->saveXML();
является:
<?xml version="1.0" encoding="utf-8"?>
<div><h1>Home</h1>test</div>
{{test}}
был удален, оставив остальные нетронутыми.