为什么 getElementsByTagName 只抓取这里的所有其他元素?

发布于 2024-11-29 05:19:25 字数 902 浏览 1 评论 0原文

通过使用 DomDocument 的此代码:

<?php
$html = '<pre>one</pre><pre>two</pre><pre>three</pre><pre>four</pre>';

$doc = new DomDocument();
$doc->loadHTML($html);
$sub = $doc->getElementsByTagName("pre");
foreach($sub as $pre) {
    $fragment = $doc->createDocumentFragment(); 
    $fragment->appendXML(str_replace('&', '&amp;', '<p>& it\'s replaced</p>'));
    $pre->parentNode->replaceChild($fragment, $pre);
}

echo $doc->saveHTML();
?>

我得到以下输出:

<p>& it's replaced</p> 
<pre>two</pre>
<p>& it's replaced</p>
<pre>four</pre>

工作(或不工作)示例< /a>

有人可以向我解释发生了什么以及为什么所有 pre 标签没有被替换吗?

With this code using DomDocument:

<?php
$html = '<pre>one</pre><pre>two</pre><pre>three</pre><pre>four</pre>';

$doc = new DomDocument();
$doc->loadHTML($html);
$sub = $doc->getElementsByTagName("pre");
foreach($sub as $pre) {
    $fragment = $doc->createDocumentFragment(); 
    $fragment->appendXML(str_replace('&', '&', '<p>& it\'s replaced</p>'));
    $pre->parentNode->replaceChild($fragment, $pre);
}

echo $doc->saveHTML();
?>

I get this output:

<p>& it's replaced</p> 
<pre>two</pre>
<p>& it's replaced</p>
<pre>four</pre>

Working (or not) example

Can someone explain to me what is going on and why all the pre tags aren't being replaced?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

漆黑的白昼 2024-12-06 05:19:25

您可以尝试以下方式: http://codepad.viper-7.com/ALYWEi

<?php
$html = '<pre>one</pre><pre>two</pre><pre>three</pre><pre>four</pre>';

$doc = new DomDocument();
$doc->loadHTML($html);
$sub = $doc->getElementsByTagName("pre");
$i = $sub->length - 1;
while ($i > -1) {
    $pre = $sub->item($i);
    $fragment = $doc->createDocumentFragment(); 
    $fragment->appendXML(str_replace('&', '&', '<p>& it\'s replaced</p>'));


    $pre->parentNode->replaceChild($fragment, $pre);

    $i--;
} 

echo $doc->saveHTML();
?>

我发现当我在没有引号的情况下搜索“DomDocument Replacechild”时出现的问题

请参阅此处的第一条评论: http://php.net/manual/en/domnode.replacechild.php 特别是这个:

如果您尝试一次替换多个节点,则在迭代 DOMNodeList 时必须小心。如果旧节点与新节点的名称不同,则在替换后它将从列表中删除。使用回归循环:

You can try this way: http://codepad.viper-7.com/ALYWEi

<?php
$html = '<pre>one</pre><pre>two</pre><pre>three</pre><pre>four</pre>';

$doc = new DomDocument();
$doc->loadHTML($html);
$sub = $doc->getElementsByTagName("pre");
$i = $sub->length - 1;
while ($i > -1) {
    $pre = $sub->item($i);
    $fragment = $doc->createDocumentFragment(); 
    $fragment->appendXML(str_replace('&', '&', '<p>& it\'s replaced</p>'));


    $pre->parentNode->replaceChild($fragment, $pre);

    $i--;
} 

echo $doc->saveHTML();
?>

I found the issue when I googled "DomDocument replacechild" without the quotes

see the first comment here: http://php.net/manual/en/domnode.replacechild.php particularly this:

If you are trying to replace more than one node at once, you have to be careful about iterating over the DOMNodeList. If the old node has a different name from the new node, it will be removed from the list once it has been replaced. Use a regressive loop:

冷弦 2024-12-06 05:19:25

这与方向有关:

for ($i = 0; $i < $sub->length; $i++) {
    $pre = $sub->item($i);
    $fragment = $doc->createDocumentFragment();
    $fragment->appendXML(str_replace('&', '&', '<p>& it\'s replaced</p>'));
    $pre->parentNode->replaceChild($fragment, $pre);
}

不起作用,但

for ($i = $sub->length -1; $i >=0; $i--) {
    $pre = $sub->item($i);
    $fragment = $doc->createDocumentFragment();
    $fragment->appendXML(str_replace('&', '&', '<p>& it\'s replaced</p>'));
    $pre->parentNode->replaceChild($fragment, $pre);
}

效果很好。我想一定有类似内部计数器的东西。

安德烈亚斯 HTH

It has something to do with the direction:

for ($i = 0; $i < $sub->length; $i++) {
    $pre = $sub->item($i);
    $fragment = $doc->createDocumentFragment();
    $fragment->appendXML(str_replace('&', '&', '<p>& it\'s replaced</p>'));
    $pre->parentNode->replaceChild($fragment, $pre);
}

doesn't work but

for ($i = $sub->length -1; $i >=0; $i--) {
    $pre = $sub->item($i);
    $fragment = $doc->createDocumentFragment();
    $fragment->appendXML(str_replace('&', '&', '<p>& it\'s replaced</p>'));
    $pre->parentNode->replaceChild($fragment, $pre);
}

works fine. There must be something like an internal counter, I reckon.

HTH Andreas

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文