1 に答える
おそらくコードを単純化しすぎたのでしょう。現状では、開始タグを置き換えるだけであり、少なくともブラウザーが quirks モードに移行します。
とにかく、これは DOM を使用して確実に可能です (ただし、サポートされていない HTML5 要素のために警告がスローされます。 https://stackoverflow.com/a/6090728/1392379を参照してください)。ただし、XPath クエリが間違っているため、単純に配列を渡すことはできません。それ。また、クエリが機能したとしても、個々のテキスト ノードをすべて選択するだけなので、置き換えるものは何もありません。
ノードの名前を直接変更することはできません。ノードを新しいものに置き換える必要があります。静的 XPath クエリを使用する例を次に示します。選択したノードの属性と子ノードを新しいdiv
ノードにコピーし、元のノードを新しいノードに置き換えます。
$dom = new DOMDocument;
$dom->loadHTML($content);
$xp = new DOMXPath($dom);
$nodes = $xp->query('//*[self::article|self::summary|self::aside][not(ancestor::pre) and not(ancestor::code)]');
foreach($nodes as $node)
{
$newNode = $dom->createElement('div');
while($node->childNodes->length)
{
$childNode = $node->childNodes->item(0);
$newNode->appendChild($dom->importNode($childNode, true));
}
while($node->attributes->length)
{
$attributeNode = $node->attributes->item(0);
$newNode->setAttributeNode($dom->importNode($attributeNode));
}
$node->parentNode->replaceChild($newNode, $node);
}
echo $dom->saveXML($dom->documentElement);
更新onwhile
の代わりに使用してコード例を修正しました。後者は、追加されるノードのクローンを作成しない場合にヒックアップを引き起こし、その結果、反復されるノード リストから削除されます。foreach
childNodes/attributes
for
ループを使用しても問題なく動作するはずです。
for($i = 0; $i < $node->childNodes->length; $i ++)
{
$childNode = $node->childNodes->item($i);
$newNode->appendChild($dom->importNode($childNode, true));
}
for($i = 0; $i < $node->attributes->length; $i ++)
{
$attributeNode = $node->attributes->item($i);
$newNode->setAttributeNode($dom->importNode($attributeNode));
}
最初に述べたクローニングと同様に:
foreach($node->childNodes as $childNode)
{
$newNode->appendChild($dom->importNode($childNode->cloneNode(true), true));
}
foreach($node->attributes as $attributeNode)
{
$newNode->setAttributeNode($dom->importNode($attributeNode->cloneNode()));
}
$node->parentNode->replaceChild($newNode, $node);