PHP DOMDocument 用文本节点替换多个 child
PHP DOMDocument replace multiple child with text nodes
我有一个示例字符串如下:
$feed_status = "Nice to see you all back again <img src=\"http://52.1.47.143/file/pic/emoticon/default/smile.png\" alt=\"Smile\" title=\"Smile\" title=\"v_middle\" /><img src=\"http://52.1.47.143/file/pic/emoticon/default/smile.png\" alt=\"Smile\" title=\"Smile\" title=\"v_middle\" /><img src=\"http://52.1.47.143/file/pic/emoticon/default/smile.png\" alt=\"Smile\" title=\"Smile\" title=\"v_middle\" />";
(单引号、双引号等语法错误请见谅)
供您参考,我刚刚在字符串中添加了三个 <img>
标签,但在实际情况下,该字符串可能包含单个 <img>
标签或不包含 <img>
标签或更多一个 <img>
个标签。
我想获取每个 <img>
标记的 src 属性中存在的文件名,并制作这些文件名的数组。然后我必须用标题为 $emoticon_codes
的数组中的字符串替换这些 <img>
标签,该数组是根据 <img>
标签中存在的文件名动态创建的。这种字符串替换应该以相同的顺序进行。
为此,我尝试了以下代码。直到创建标题为 $emoticon_codes
的动态数组一切正常,但我面临着用数组 $emoticon_codes
中的字符串替换当前 <img>
标签的代码。那么有人可以帮我纠正我在代码中犯的错误,同时从字符串中替换 <img>
标签。
以下是我的代码:
$doc = new DOMDocument();
$doc->loadHTML($feed_status);
$imageTags = $doc->getElementsByTagName('img');
if(count($imageTags)) {
$emoticon_codes = array();
foreach($imageTags as $tag) {
if (basename($tag->getAttribute('src')) == 'evilgrin.png') {
array_push($emoticon_codes, '\ue404');
}
if (basename($tag->getAttribute('src')) == 'grin.png') {
array_push($emoticon_codes, '\ue415');
}
if (basename($tag->getAttribute('src')) == 'happy.png') {
array_push($emoticon_codes, '\ue057');
}
if (basename($tag->getAttribute('src')) == 'smile.png') {
array_push($emoticon_codes, '\ue056');
}
if (basename($tag->getAttribute('src')) == 'surprised.png') {
array_push($emoticon_codes, '\ue107');
}
if (basename($tag->getAttribute('src')) == 'tongue.png') {
array_push($emoticon_codes, '\ue105');
}
if (basename($tag->getAttribute('src')) == 'unhappy.png') {
array_push($emoticon_codes, '\ue403');
}
if (basename($tag->getAttribute('src')) == 'waii.png') {
array_push($emoticon_codes, '\ue407');
}
if (basename($tag->getAttribute('src')) == 'wink.png') {
array_push($emoticon_codes, '\ue405');
}
}
/*Till here everything works fine. The array $emoticon_codes is also getting generated finely*/
/*Following is the code giving problem to me,*/
$t = 0;
foreach($imageTags as $img) {
$img->parentNode->replaceChild($img, $doc->createTextNode($emoticon_codes[$t]));
$t++;
if ($t > count($emoticon_codes)) {
break;
}
}
}
我想要的输出字符串在 echo $feed_status;
之后应该如下所示:
$feed_status = Nice to see you all back again \ue056 \ue056 \ue056;
提前致谢。
你有这个:
foreach($imageTags as $img) {
$img->parentNode->replaceChild($img, $doc->createTextNode($emoticon_codes[$t]));
$t++;
if ($t > count($emoticon_codes)) {
break;
}
}
然而,这只会循环 $imageTags
,而不是 $emoticon_codes
。
你需要这个:
foreach($imageTags as $img) {
foreach($emoticon_codes as $emoticon_code) {
$img->parentNode->replaceChild($img, $doc->createTextNode($emoticon_code));
}
}
如果您尝试更改多个子项,则需要一些 regression 来进行一些更改,我建议尝试将每个替换项映射到一个数组中,而不是使用多个 if 语句。示例:
$feed_status = "Nice to see you all back again <img src=\"http://52.1.47.143/file/pic/emoticon/default/smile.png\" alt=\"Smile\" title=\"Smile\" title=\"v_middle\" /><img src=\"http://52.1.47.143/file/pic/emoticon/default/smile.png\" alt=\"Smile\" title=\"Smile\" title=\"v_middle\" /><img src=\"http://52.1.47.143/file/pic/emoticon/default/smile.png\" alt=\"Smile\" title=\"Smile\" title=\"v_middle\" />";
$doc = new DOMDocument();
@$doc->loadHTML($feed_status, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$imageTags = $doc->getElementsByTagName('img');
$replacements = array(
'evilgrin.png' => '\ue404',
'grin.png' => '\ue415',
'happy.png' => '\ue057',
'smile.png' => '\ue056',
'surprised.png' => '\ue107',
'tongue.png' => '\ue105',
'unhappy.png' => '\ue403',
'waii.png' => '\ue407',
'wink.png' => '\ue405',
);
// regression
$i = $imageTags->length - 1;
while($i > -1) {
$tag = $imageTags->item($i);
$basename = basename($tag->getAttribute('src'));
if(isset($replacements[$basename])) { // if the file name matches
// make replacements
$r = $replacements[$basename];
$text = $doc->createTextNode($r);
$tag->parentNode->replaceChild($text, $tag);
}
$i--;
}
// append to string container again
$feed_status = '';
foreach($doc->childNodes->item(0)->childNodes as $e) {
$feed_status .= $doc->saveHTML($e);
}
echo $feed_status;
我有一个示例字符串如下:
$feed_status = "Nice to see you all back again <img src=\"http://52.1.47.143/file/pic/emoticon/default/smile.png\" alt=\"Smile\" title=\"Smile\" title=\"v_middle\" /><img src=\"http://52.1.47.143/file/pic/emoticon/default/smile.png\" alt=\"Smile\" title=\"Smile\" title=\"v_middle\" /><img src=\"http://52.1.47.143/file/pic/emoticon/default/smile.png\" alt=\"Smile\" title=\"Smile\" title=\"v_middle\" />";
(单引号、双引号等语法错误请见谅)
供您参考,我刚刚在字符串中添加了三个 <img>
标签,但在实际情况下,该字符串可能包含单个 <img>
标签或不包含 <img>
标签或更多一个 <img>
个标签。
我想获取每个 <img>
标记的 src 属性中存在的文件名,并制作这些文件名的数组。然后我必须用标题为 $emoticon_codes
的数组中的字符串替换这些 <img>
标签,该数组是根据 <img>
标签中存在的文件名动态创建的。这种字符串替换应该以相同的顺序进行。
为此,我尝试了以下代码。直到创建标题为 $emoticon_codes
的动态数组一切正常,但我面临着用数组 $emoticon_codes
中的字符串替换当前 <img>
标签的代码。那么有人可以帮我纠正我在代码中犯的错误,同时从字符串中替换 <img>
标签。
以下是我的代码:
$doc = new DOMDocument();
$doc->loadHTML($feed_status);
$imageTags = $doc->getElementsByTagName('img');
if(count($imageTags)) {
$emoticon_codes = array();
foreach($imageTags as $tag) {
if (basename($tag->getAttribute('src')) == 'evilgrin.png') {
array_push($emoticon_codes, '\ue404');
}
if (basename($tag->getAttribute('src')) == 'grin.png') {
array_push($emoticon_codes, '\ue415');
}
if (basename($tag->getAttribute('src')) == 'happy.png') {
array_push($emoticon_codes, '\ue057');
}
if (basename($tag->getAttribute('src')) == 'smile.png') {
array_push($emoticon_codes, '\ue056');
}
if (basename($tag->getAttribute('src')) == 'surprised.png') {
array_push($emoticon_codes, '\ue107');
}
if (basename($tag->getAttribute('src')) == 'tongue.png') {
array_push($emoticon_codes, '\ue105');
}
if (basename($tag->getAttribute('src')) == 'unhappy.png') {
array_push($emoticon_codes, '\ue403');
}
if (basename($tag->getAttribute('src')) == 'waii.png') {
array_push($emoticon_codes, '\ue407');
}
if (basename($tag->getAttribute('src')) == 'wink.png') {
array_push($emoticon_codes, '\ue405');
}
}
/*Till here everything works fine. The array $emoticon_codes is also getting generated finely*/
/*Following is the code giving problem to me,*/
$t = 0;
foreach($imageTags as $img) {
$img->parentNode->replaceChild($img, $doc->createTextNode($emoticon_codes[$t]));
$t++;
if ($t > count($emoticon_codes)) {
break;
}
}
}
我想要的输出字符串在 echo $feed_status;
之后应该如下所示:
$feed_status = Nice to see you all back again \ue056 \ue056 \ue056;
提前致谢。
你有这个:
foreach($imageTags as $img) {
$img->parentNode->replaceChild($img, $doc->createTextNode($emoticon_codes[$t]));
$t++;
if ($t > count($emoticon_codes)) {
break;
}
}
然而,这只会循环 $imageTags
,而不是 $emoticon_codes
。
你需要这个:
foreach($imageTags as $img) {
foreach($emoticon_codes as $emoticon_code) {
$img->parentNode->replaceChild($img, $doc->createTextNode($emoticon_code));
}
}
如果您尝试更改多个子项,则需要一些 regression 来进行一些更改,我建议尝试将每个替换项映射到一个数组中,而不是使用多个 if 语句。示例:
$feed_status = "Nice to see you all back again <img src=\"http://52.1.47.143/file/pic/emoticon/default/smile.png\" alt=\"Smile\" title=\"Smile\" title=\"v_middle\" /><img src=\"http://52.1.47.143/file/pic/emoticon/default/smile.png\" alt=\"Smile\" title=\"Smile\" title=\"v_middle\" /><img src=\"http://52.1.47.143/file/pic/emoticon/default/smile.png\" alt=\"Smile\" title=\"Smile\" title=\"v_middle\" />";
$doc = new DOMDocument();
@$doc->loadHTML($feed_status, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$imageTags = $doc->getElementsByTagName('img');
$replacements = array(
'evilgrin.png' => '\ue404',
'grin.png' => '\ue415',
'happy.png' => '\ue057',
'smile.png' => '\ue056',
'surprised.png' => '\ue107',
'tongue.png' => '\ue105',
'unhappy.png' => '\ue403',
'waii.png' => '\ue407',
'wink.png' => '\ue405',
);
// regression
$i = $imageTags->length - 1;
while($i > -1) {
$tag = $imageTags->item($i);
$basename = basename($tag->getAttribute('src'));
if(isset($replacements[$basename])) { // if the file name matches
// make replacements
$r = $replacements[$basename];
$text = $doc->createTextNode($r);
$tag->parentNode->replaceChild($text, $tag);
}
$i--;
}
// append to string container again
$feed_status = '';
foreach($doc->childNodes->item(0)->childNodes as $e) {
$feed_status .= $doc->saveHTML($e);
}
echo $feed_status;