PHP Conference Japan 2024

DOMNamedNodeMap 类

(PHP 5, PHP 7, PHP 8)

类概要

class DOMNamedNodeMap implements IteratorAggregate, Countable {
/* 属性 */
public readonly int $length;
/* 方法 */
public count(): int
public getNamedItem(string $qualifiedName): ?DOMNode
public getNamedItemNS(?string $namespace, string $localName): ?DOMNode
public item(int $index): ?DOMNode
}

属性

length

映射中的节点数。有效子节点索引的范围为 0length - 1(包含)。

变更日志

版本 描述
8.0.0 已移除未实现的方法 DOMNamedNodeMap::setNamedItem()DOMNamedNodeMap::removeNamedItem()DOMNamedNodeMap::setNamedItemNS()DOMNamedNodeMap::removeNamedItem()
8.0.0 DOMNamedNodeMap 现在实现 IteratorAggregate。之前实现的是 Traversable

注释

注意: 可以使用数组语法访问映射中的节点。

目录

添加注释

用户贡献的注释 3 条注释

kendsnyder at gmail dot com
15 年前
补充 xafford 的评论。当使用 ->item() 或 foreach 迭代命名节点映射集合时,使用 DOMNode->removeAttribute() 或 DOMNode->removeAttributeNode() 删除属性会改变集合,就像它是一个堆栈一样。为了说明这一点,下面的代码尝试从每个元素中删除所有属性,但只删除第一个。一个解决方法是在删除属性之前将命名节点映射复制到数组中。在 Windows XP 上使用 PHP 5.2.9。

<?php
error_reporting
(E_ALL);
$html = '<h1 id="h1test" class="h1test">Heading</h1>';
$html .= '<p align="left" class="ptest">Hello World</p>';

$doc = new DOMDocument();
$doc->loadHTML($html);

// 从 h1 元素中删除属性
$h1 = $doc->getElementsByTagName('h1')->item(0);
$length = $h1->attributes->length;
for (
$i = 0; $i < $length; ++$i) {
$name = $h1->attributes->item($i)->name;
$h1->removeAttribute($name);
echo
"h1: removed attribute `$name`<br>";
}
// 从 p 元素中删除属性
$p = $doc->getElementsByTagName('p')->item(0);
foreach (
$p->attributes as $name => $attrNode) {
$p->removeAttribute($name);
echo
"p: removed attribute `$name`<br>";
}

?>

输出
-------
h1: removed attribute `id`

注意:尝试获取非对象的属性 nodemap.php 第 13 行
h1: removed attribute ``
p: removed attribute `align`
xafford
15 年前
我偶然发现 DOMNamedNodeMap 的一个问题。如果使用 foreach 迭代表示 DOMElement 属性的 DOMNamedNodeMap,并且使用 DOMElement::removeAttributeNode,则只会处理第一个属性。

示例(不完整)

<?php

/*
* 想象一下你得到了一个像这样的节点:
* <a onclick="alert('evil')" href="http://example.com">evil</a>
* 并且应该删除 onclick,href 将不会被测试。
*/

foreach ( $node->attributes as $attribute )
{

echo
'checking attribute ', $attribute->name, '<br />';

if ( !
in_array ( $attribute->name, $allowed_attributes ) )
{
$node->removeAttributeNode ( $attribute );
}

}

?>

输出结果为

检查onclick属性
sirajshaikh96 at yahoo dot com
3年前
我尝试解决DOMNamedNodeMap中发生的一个普遍问题:在执行for/foreach循环时,执行`removeAttribute('$name')`后,item(0)之后item(1)不会执行,并出现警告。以下代码给出了这个问题的解决方案:在循环中应该应用item(0)而不是item($i),因为移除第一个属性节点后,当前元素只有一个属性节点。

<?php
$html
= '<h1 id="h1test" class="h2test">Heading</h1>';
$html .= '<p align="left" class="right">Hello World</p>';

$doc = new DOMDocument();
$doc->loadHTML($html);

// 从h1元素中移除属性
$h1 = $doc->getElementsByTagName('h1')->item(0);
$length = $h1->attributes->length;
for (
$i = 0; $i < $length; $i++) {
$name = $h1->attributes->item(0)->nodeName;
$value = $h1->attributes->item(0)->nodeValue;
$h1->removeAttribute($name);
echo
"h1: 已移除属性名称 :- " .$name."</br>";
echo
"h1: 已移除属性值 :- " .$value."</br>";
}
// 从p元素中移除属性
$p = $doc->getElementsByTagName('p')->item(0);
for (
$i = 0; $i < $length; $i++) {
$name = $p->attributes->item(0)->nodeName;
$value = $p->attributes->item(0)->nodeValue;
$p->removeAttribute($name);
echo
"p: 已移除属性名称 :- " .$name."</br>";
echo
"p: 已移除属性值 :- " .$value."</br>";
}
?>

输出

h1: 已移除属性名称 :- id
h1: 已移除属性值 :- h1test
h1: 已移除属性名称 :- class
h1: 已移除属性值 :- h2test
p: 已移除属性名称 :- align
p: 已移除属性值 :- left
p: 已移除属性名称 :- class
p: 已移除属性值 :- right
To Top