Первоначально я задавал вопрос в том же духе, используя Regex, но вместо этого мне рекомендовали использовать библиотеку PHP DOM ... что лучше, но я все еще застрял.
По сути, я хочу обернуть содержимое<a>
в <span>
, если он еще не обернут в <span>
.
<?php
$input = <<<EOT
<html><head></head>
<body bgcolor="#393a36">
<a href="#"><span style="color:#ffffff;">Link 1</span></a>
<a href="#">Link 2</a>
<a href="#"><img src="mypic.gif" />Image Link</a>
<a href="#"><u>Underlined Link</u></a>
</body>
</html>
EOT;
$doc = new DOMDocument();
$doc->loadHTML($input);
$tags = $doc->getElementsByTagName('a');
foreach ($tags as $tag) {
$spancount = $tag->getElementsByTagName("span")->length;
if($spancount == 0){
$content = nodeContent($tag);
$element = $doc->createElement('span');
$element->setAttribute('style','color:#ffffff;');
$frag = $doc->createDocumentFragment();
$frag->appendXML($content);
$element->appendChild($frag);
$tag->nodeValue = ""; //clear node
$tag->appendChild($element);
}
}
echo $doc->saveHTML();
function nodeContent($n, $outer=false) {
$d = new DOMDocument('1.0');
$d->formatOutput = true;
$b = $d->importNode($n->cloneNode(true),true);
$d->appendChild($b);
$h = $d->saveHTML();
// remove outter tags
if (!$outer) $h = substr($h,strpos($h,'>')+1,-(strlen($n->nodeName)+4));
return $h;
}
Он обеспечивает такой вывод:
Предупреждение PHP: DOMDocumentFragment :: appendXML (): Entity: строка 1: ошибка синтаксического анализатора: преждевременное завершение данных в строке тега img 1в /private/var/folders/78/78vHGigZHcuFeXB1KKJSb++++TI/-Tmp-/untitled_3xd..php в строке 24
PHP Предупреждение: DOMDocumentFragment :: appendXML (): ссылка на изображение в / private / var / folder/78/78vHGigZHcuFeXB1KKJSb++++TI/-Tmp-/untitled_3xd..php on line 24 PHP Предупреждение: DOMDocumentFragment :: appendXML (): ^ in / private / var / folder / 78 / 78vHGigZHcuFeXB1KKJIb+ ++ ++Tmp- / untitled_3xd..php в строке 24 Предупреждение PHP: DOMNode :: appendChild (): фрагмент документа пуст в /private/var/folders/78/78vHGigZHcuFeXB1KKJSb++++TI/-Tmp-/untitled_3xd..phpстрока 25
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head></head>
<body bgcolor="#393a36">
<a href="#"><span style="color:#ffffff;">Link 1</span></a>
<a href="#"><span style="color:#ffffff;">Link 2</span></a>
<a href="#"><span style="color:#ffffff;"></span></a>
<a href="#"><span style="color:#ffffff;"><u>Underlined Link</u></span></a>
</body>
</html>
Это в основном работает, за исключением того, что оно действительно требовательно, и, как вы можете видеть, оно умирает, если внутри a href
есть тег img
(или аналогичный).
Какой лучший способ сделать эту работу.Я долго бился в неловкое положение.
РЕДАКТИРОВАТЬ
На основе приведенных ниже отзывов приведен пересмотренный код и вывод.Обратите внимание, что текст, предшествующий тегу img
, по какой-то причине не переносится.Есть идеи?
$doc = new DOMDocument();
$doc->loadHTML($input);
$tags = $doc->getElementsByTagName('a');
foreach ($tags as $tag) {
$spancount = $tag->getElementsByTagName("span")->length;
if($spancount == 0){
$element = $doc->createElement('span');
$element->setAttribute('style','color:#ffffff;');
foreach ($tag->childNodes as $child) {
$tag->removeChild($child);
$element->appendChild($child);
}
$tag->appendChild($element);
}
}
echo $doc->saveHTML();
Вывод:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head></head>
<body bgcolor="#393a36">
<a href="#"><span style="color:#ffffff;">Link 1</span></a>
<a href="#"><span style="color:#ffffff;">Link 2</span></a>
<a href="#">Image Link<span style="color:#ffffff;"><img src="mypic.gif"></span></a>
<a href="#"><span style="color:#ffffff;"><u>Underlined Link</u></span></a>
</body>
</html>