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

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

新規登録して質問してみよう
ただいま回答率
85.50%
XPath(XML Path)

XML Path Language (XPath; XMLパス言語)は、マークアップ言語 XML に準拠した文書の特定の部分を指定する言語構文の事をいいます。XPathはXMLとは別の構文を使用します。XMLドキュメントの抽象、論理ストラクチャ上で動作します。

PHP

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

Q&A

解決済

2回答

2064閲覧

タグを除外するXpathの書き方について

agep31

総合スコア29

XPath(XML Path)

XML Path Language (XPath; XMLパス言語)は、マークアップ言語 XML に準拠した文書の特定の部分を指定する言語構文の事をいいます。XPathはXMLとは別の構文を使用します。XMLドキュメントの抽象、論理ストラクチャ上で動作します。

PHP

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

0グッド

0クリップ

投稿2018/10/23 07:18

編集2018/10/25 02:56

前提・実現したいこと

<html> <body> <header> </header> </body> <html>

上記の構造のhtmlからDOMxpathを用いて<header>タグを抜いた状態の<body>タグを抽出したいのですが、xpathの書き方がわからず困っています。

$body = $xpath->query('//body')->item(0)->nodeValue;

<body>タグの抽出には成功しています。

<?php $url = "https://4travel.jp/travelogue/11405390"; $html = file_get_contents($url,false,$context); $dom = new DOMDocument; @$dom->loadHTML( mb_convert_encoding($html, 'HTML-ENTITIES', 'ASCII,JIS,UTF-8,eucJP-win,SJIS-win'), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD ); $xpath = new DOMXPath($dom); $body_text = $xpath->query('//body/*[not(self::header)]')->item(0)->nodeValue; //$body_text = $xpath->query('//body')->item(0)->nodeValue; echo $body_text;

試したこと

$body = $xpath->query('//body/*[not(self::header)]->item(0)->nodeValue;

でやってみたのですが、<header>タグが消えてませんでした。

補足情報(FW/ツールのバージョンなど)

ubuntu18.04
Apache/2.4.29
PHP 7.2.5

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

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

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

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

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

guest

回答2

0

これでいかがでしょうか。

//body/*[not(self::header)]で確かにheaderタグはスキップしているのをChromeで確認できたので、あとはぐるぐる回して文字列を連結していけばいいです。

PHP

1$body_text = ""; 2foreach ($xpath->query('//body/*[not(self::header)]') as $row) { 3 $body_text .= $row->nodeValue; 4} 5 6print($body_text);

投稿2018/11/04 11:23

moonphase

総合スコア6621

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

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

0

ベストアンサー

XPathでは無理では?
headerノードをremoveChildするのでしょうね。

#追記

headerタグを抜いた状態のbodyタグを抽出したい

ではなく、

bodyタグの子要素のうちheaderタグ以外のタグを抽出したい

ということで。

PHP

1 $all = $xpath->query('//body/*'); 2 $not_header = $xpath->query('//body/*[not(self::header)]'); 3 4 var_dump($all); 5 var_dump($not_header);

で、

Plain

1object(DOMNodeList)#28 (1) { 2 ["length"]=> 3 int(25) 4} 5object(DOMNodeList)#29 (1) { 6 ["length"]=> 7 int(24) 8}

になるので、ちゃんと1件除外されて、24件抽出できているようです。
#追記2
item(0)nodeValueは空で正常でしょう。
item(0)->nodeValueからitem(23)->nodeValueまでを繋ぎます。

PHP

1$body = $xpath->query('//body/*[not(self::header)]'); 2$nodevalue=""; 3for($i=0; $i<$body->length; $i++){ 4 $nodevalue .= $body->item($i)->nodeValue; 5} 6echo($nodevalue);

scriptタグの内容がじゃまな気がします。

投稿2018/10/23 07:41

編集2018/10/31 11:32
otn

総合スコア84423

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

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

otn

2018/10/23 12:02

もしかして、 > headerタグを抜いた状態のbodyタグを抽出したい ではなく、 > bodyタグの子要素のうちheaderタグ以外のタグを抽出したい でしょうか? であれば、 "//body/*[not(self::header)]" で良いはずです。 書かれているコードにはエラーがありますが、タイプミスしているのでは?
agep31

2018/10/25 02:55

bodyタグの子要素のうちheaderタグ以外のタグの要素を抽出したいです。"//body/*[not(self::header)]"としてやってみたのですが、何も抽出できませんでした。 プログラムのソースを載せます。
agep31

2018/10/25 05:41

こちらでもvar_dumpで確認したところ、1件減っていました。ただ、テキストが抽出できないです。
otn

2018/10/25 08:30 編集

それは、XPathじゃなくて、->item(0)->nodeValue の問題ですね。 何を得たいのでしょうか?var_dump(~~->item(n))してみるとか。
agep31

2018/10/31 02:10

返信遅れてしまい申し訳ありません。得たいものは<header>タグを除いた<body>タグの中身(テキスト)です。 var_dump($xpath->query('//body/*[not(self::header)]')->item(0)); としてやってみたのですが["nodeValue"]=> string(0)となっておりテキストが入っていないと思われます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問