質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
DOM

DOMは、Document Object Modelの略で、HTML文書やXML文書をアプリケーションから利用するためのAPIです。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

2回答

1552閲覧

removeChildで指定の子要素ノードを削除することができない

pegy

総合スコア245

DOM

DOMは、Document Object Modelの略で、HTML文書やXML文書をアプリケーションから利用するためのAPIです。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2021/05/19 03:35

編集2021/05/19 06:08

下記のようにDomを操作してparentNodeから見て、子ノードの指定のitem($key)を削除しようとしているのですが、削除するノードの指定まではうまくいくのですが、 $key_node->parentNode->removeChild($remove_node);でエラーが発生し実装することができません。

removeChild自体の使い方は正しいように思えるのですが、どこかコードに間違いがあるのでしょうか?
※in_arrayでwhit_tagにあれば削除のように実際にはブラックリストのように使用しているように見えますが、現在は試しに反対方向にコードを書いているため、そこはご放念ください。実際のコードでは!in_arrayで否定します。

php

1//main.php 2require_once("function.php"); 3 4 $data = '<div id="wrapper"> 5 <img src="data:sssss" onclick="ss"> 6 <p style="background:#fff000" class="hoge"> 7 <span data="111" id="222">abcde</span> 8 <script><span>ss</span></script> 9 </p> 10 </div>'; 11 12$dom = new DOMDocument(); 13 $dom -> loadHTML($data); 14 $item = $dom->getElementById('wrapper')->childNodes;

php

1//function.php 2//--------------------------------------------------------------------------------------------------------// 3$white_tag=["p","span","strong","i","u","s","blockquote","sub","sup","ul","ol","li","hr",'div','figure','oembed','img']; 4$white_attr=["class","style",'src']; 5//--------------------------------------------------------------------------------------------------------// 6 7function recursive_tag ($node){ 8 global $white_tag; 9 10 foreach ($node as $key => $key_node) { 11 $tag_name = $key_node->tagName; 12 if(in_array($tag_name,$white_tag,true)){ 13 $remove_node = $key_node->parentNode->childNodes->item($key);//ここまではうまくいく 14    var_dump($remove_node); 15 $key_node->parentNode->removeChild($remove_node);//ここがうまくいかない 16 17 } 18 19 } 20} 21//--------------------------------------------------------------------------------------------------------//

追記

php

1Warning: DOMDocument::loadHTML(): Unexpected end tag : span in Entity, line: 5 in /Applications/MAMP/htdocs/textile/dist/main.php on line 39 2 3Notice: Undefined property: DOMText::$tagName in /Applications/MAMP/htdocs/textile/dist/function.php on line 24

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2021/05/19 04:19

エラー内容をコピペしてください
pegy

2021/05/19 04:32

失礼しました、エラーコードを追記しました。
yambejp

2021/05/19 04:35

HTML自体がただしくないとDOMDocumentで処理しきれないのでは?
guest

回答2

0

自己解決

foreachで順番にchildNodeを削除する場合、対象となる子要素ノードが複数ある場合には$keyの順番が変わってしまう可能性があることに問題がありました。

以下のようにforeachでは$keyだけを取得して、ASCとDESCをひっくり返す処理rsortを加えて、for文で処理することで解決いたしました。

foreachでもASCとDESCをひっくり返すことができればよりシンプルに実装できた可能性もありますが、当該方法は分からずに、rsortで配列の順番をひっくり返しました。
あまりスマートな方法ではないかもしれませんが、記載させていただきます。

php

1//--------------------------------------------------------------------------------------------------------// 2 3function recursive_tag ($node){ 4 global $white_tag; 5 $target_key=[]; 6 foreach ($node as $key => $key_node) { 7 $tag_name = $key_node->tagName; 8 9 if(!in_array($tag_name,$white_tag,true)){ 10 $target_key[]=$key; 11 } 12 13 if ($key_node->childNodes->length !==0) { 14 recursive_tag($key_node->childNodes); 15 } 16 17 } 18 rsort($target_key); 19 20 for ($i=0; $i <count($target_key) ; $i++) { 21 $remove_node = $node->item($target_key[$i])->parentNode->childNodes->item($target_key[$i]); 22 $node->item($target_key[$i])->parentNode->removeChild($remove_node); 23 } 24} 25//--------------------------------------------------------------------------------------------------------//

投稿2021/05/19 07:03

pegy

総合スコア245

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

HTMLの文法エラーをひろっているのでエラーを消すだけなら
libxml_use_internal_errors()を利用してください

投稿2021/05/19 06:32

yambejp

総合スコア116734

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yambejp

2021/05/19 06:33

エラーを消してもscriptタグ内のspanタグはタグとして認識されませんね
pegy

2021/05/19 06:59

ありがとうございます。一つ重大なポイントが判明したために、回答として追記させていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問