1
4

1 に答える 1

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の代わりに使用してコード例を修正しました。後者は、追加されるノードのクローンを作成しない場合にヒックアップを引き起こし、その結果、反復されるノード リストから削除されます。foreachchildNodes/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);
于 2013-08-09T12:32:09.233 に答える