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
公開 getNamedItemNS(?字串 $namespace, 字串 $localName): ?DOMNode
公開 item(整數 $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 迭代 named node map 集合時,使用 DOMNode->removeAttribute() 或 DOMNode->removeAttributeNode() 移除屬性會改變集合,就像它是堆疊一樣。 舉例來說,以下程式碼嘗試從每個元素中移除所有屬性,但只移除第一個。 一個解決方法是在移除屬性之前將 named node map 複製到陣列中。 在 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: 已移除屬性 `$name`<br>";
}
// 從 p 元素移除屬性
$p = $doc->getElementsByTagName('p')->item(0);
foreach (
$p->attributes as $name => $attrNode) {
$p->removeAttribute($name);
echo
"p: 已移除屬性 `$name`<br>";
}

?>

輸出
-------
h1: 已移除屬性 `id`

注意:在 nodemap.php 的第 13 行嘗試取得非物件的屬性
h1: 已移除屬性 ``
p: 已移除屬性 `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
'檢查屬性 ', $attribute->name, '<br />';

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

}

?>

輸出結果會是

檢查屬性 onclick
sirajshaikh96 at yahoo dot com
3 年前
我嘗試解決 DOMNamedNodeMap 中發生的常見問題,即在執行 for/foreach 迴圈時,在對 item(0) 執行 removeAttribute('$name') 後,item(1) 不會執行並出現警告。以下程式碼提供此問題的解決方案,即在迴圈中應該套用 item(0) 而不是 item($i),因為移除第一個屬性節點後,現在的元素只有一個屬性節點。

<?php
$html
= '<h1 id="h1test" class="h2test">標題</h1>';
$html .= '<p align="left" class="right">哈囉世界</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