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

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

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

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

XPath(XML Path)

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

Q&A

解決済

1回答

2473閲覧

XPath|全てのh2、h3、h4要素を上から順番に取得したい(入れ子は維持したい)

QOOSO

総合スコア10

XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

XPath(XML Path)

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

0グッド

0クリップ

投稿2020/01/25 02:06

質問をご覧いただきありがとうございます。

タイトルの通り、見出しタグを上から順番に全て取得したいです。

H2だけ全部、H3だけ全部の取得については、
下記の記事を参考にしながら取得することはできました。

xPath

1//h2[not(.=preceding::h2)]

参考記事

https://techblog.zozo.com/entry/xpath

&条件などを使うのだろうと想定はできているのですが、
記述にうまく落とし込めません。

どなたか有識者の方のお力添えをいただけますと幸いです。

どうぞよろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

こんにちは

ちょっと長いですが、以下のようになるかなと思います。

XPath

1//*[self::h2 and not(.=preceding::h2) or self::h3 and not(.=preceding::h3) or self::h4 and not(.=preceding::h4)]

以下、サンプルです。

html

1<html><body> 2 3<h1 id="header11">AAA</h1> 4<h2 id="header21">BBB</h2> 5<h3 id="header31">CCC</h3> 6<h4 id="header41">DDD</h4> 7 8<h1 id="header12">AAA</h1> 9<h2 id="header22">BBB</h2> 10<h3 id="header32">EEE</h3> 11<h4 id="header42">FFF</h4> 12 13<h1 id="header13">AAA</h1> 14<h2 id="header23">GGG</h2> 15<h3 id="header33">EEE</h3> 16<h4 id="header43">HHH</h4> 17 18<h1 id="header14">AAA</h1> 19<h2 id="header24">GGG</h2> 20<h3 id="header34">III</h3> 21<h4 id="header44">HHH</h4> 22 23</body></html>

上記の HTML から、先のXPathで要素を取得し、タグ名および内容のテキストでソートした順に表示するプログラムをPythonで書きました。

python3

1import lxml.html 2 3 4html = '''<html><body> 5 6<h1 id="header11">AAA</h1> 7<h2 id="header21">BBB</h2> 8<h3 id="header31">CCC</h3> 9<h4 id="header41">DDD</h4> 10 11<h1 id="header12">AAA</h1> 12<h2 id="header22">BBB</h2> 13<h3 id="header32">EEE</h3> 14<h4 id="header42">FFF</h4> 15 16<h1 id="header13">AAA</h1> 17<h2 id="header23">GGG</h2> 18<h3 id="header33">EEE</h3> 19<h4 id="header43">HHH</h4> 20 21<h1 id="header14">AAA</h1> 22<h2 id="header24">GGG</h2> 23<h3 id="header34">III</h3> 24<h4 id="header44">HHH</h4> 25 26</body></html>''' 27 28 29dom = lxml.html.fromstring(html) 30 31h234s = dom.xpath( 32 '//*[self::h2 and not(.=preceding::h2) or self::h3 and not(.=preceding::h3) or self::h4 and not(.=preceding::h4)]' 33) 34 35for h in sorted(h234s, key=lambda e: f'{e.tag}#{e.text}'): 36 print(h.tag, h.text, h.attrib['id']) 37

上記を実行すると以下が出力されます。

h2 BBB header21

h2 GGG header23
h3 CCC header31
h3 EEE header32
h3 III header34
h4 DDD header41
h4 FFF header42
h4 HHH header43

以上、参考になれば幸いです。

投稿2020/01/25 04:35

jun68ykt

総合スコア9058

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

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

QOOSO

2020/01/25 10:49

ありがとうございます!想定通りの挙動となりました。 感謝申し上げます。
jun68ykt

2020/01/25 11:26

どういたしまして。 > 想定通りの挙動となりました。 とのことで、よかったです????
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問