piapia123
ja

XPath / JSONPath テスター

テキスト

処理はすべてブラウザ内で完結します。データは送信されません

入力
ファイルをここにドロップすると読み込めます
出力

内容を貼り付けてパスを 1 行書くと、何が選ばれるかが分かります。よくある用途:`//a/@href` でリンク一覧、`//img/@src` で画像 URL 一覧、`//h2` で見出しのテキスト。あるいは `$.store.book[*].title` で API 応答から書名を全部、`$..id` で階層を問わず id を全部取り出せます。 2 つの構文を 1 ページにまとめている理由:どちらも形は同じ —— パス 1 本 + 文書 1 つ → 結果の一覧です。ツールを分けると、貼り付ける前に「手元にあるのは JSON か XML か」を先に判断させることになりますが、その判断は内容を貼る前には無意味です。上の選択で切り替えてください。 どちらも明確に定義されたサブセットです。 対応範囲は以下に記載しており、範囲外の書き方は「対応していません」と明示的にエラーにします —— 「実装されていない構文」と「本当に一致しなかった」は画面上で見分けがつかず、前者は正しいセレクターを延々見直させることになるからです。 JSONPath には事実上の標準がありません。これは先に知っておくべき点です:`$..book[?(@.price<10)]` は JavaScript・Python・Java の各 JSONPath ライブラリで結果が一致しません(スライスの境界、子孫検索が自分自身を含むかどうかで各実装が異なります)。RFC 9535 が決まったのは 2024 年です。ここでは RFC 9535 に従っているので、結果はローカルでのデバッグに向きます。コードに貼る前に、そのライブラリの挙動を確認してください。 XPath を完全実装にしない理由:13 の軸、名前空間、変数、多数の関数を扱うと数千行になります。ブラウザ標準の `document.evaluate` は手軽ですが、アルゴリズムが DOM に触る必要があり、当サイトの変換処理はすべて純関数(Node でテストできることが前提)です。そこでサイト内の軽量 HTML パーサーの上に、よく使う層だけを実装しています。 解析は寛容です:貼り付けられる HTML は閉じタグが無かったり引用符が抜けていたりしますが、それでクエリ全体が失敗してはいけません(HTML → Markdown と同じパーサーを使っています)。

機能

  • 1 つの画面で 2 つの構文:XPath は HTML / XML、JSONPath は JSON
  • XPath の軸:子 `/` と子孫 `//` —— 抽出作業で必要な 2 つ
  • XPath のノードテスト:タグ名、`*`、`@属性`、`text()`。大文字小文字は区別しません
  • XPath の述語:`[1]`、`[last()]`、`[@a]`、`[@a="v"]`、`[contains(@a,"v")]`、`[starts-with(@a,"v")]` など
  • JSONPath:`.key`、`["key"]`、`[*]`、`..` による子孫検索、`[0]` の添字と和集合、`[1:3]` のスライス
  • JSONPath のフィルター:`[?(@.price < 100)]`。`==` `!=` `<` `>` の比較、`&&`、`||`、括弧に対応
  • JSONPath は各結果の位置(`$` で始まるパス)も出力できます。コードにそのまま書けます
  • 4 種類の出力:テキスト / 値、HTML ソース、位置、件数のみ
  • 位置述語は XPath の標準どおり:`//a[1]` は「各親の下の最初の a」
  • 各結果に 1 始まりの番号が付き、行ごとにコピーできます。オブジェクトは整形された JSON でコピーされます
  • 一致が無いときは空欄ではなく一文で説明します
  • 範囲外の構文はエラーにするので、「一致なし」と混同しません
  • 不正な HTML でも解析でき、閉じタグ 1 つの欠落で失敗しません

使い方

  1. 構文を選びます:XPath(HTML / XML)か JSONPath(JSON)
  2. ソースまたは JSON を貼り付け、`//a/@href` や `$.store.book[*].title` のような式を書きます
  3. 出力を選びます:テキスト / 値、HTML ソース、位置、件数のみ
  4. 結果は即座に更新されます。行のコピーボタンで 1 件だけ取り出せます

よくある質問

どの XPath 構文に対応していますか?
軸は子 `/` と子孫 `//` のみ。ノードテストはタグ名、`*`、`@属性`、`text()`。述語は `[1]`、`[last()]`、`[@a]`、`[@a="v"]`、`[text()="v"]`、`[contains(@a,"v")]`、`[starts-with(@a,"v")]`、および `and` でつないだ 2 つ。関数は外側の `count(...)` のみです。この範囲外は「対応していません」と明示的にエラーにします —— 例えば `position()>1`、`!=` 比較、`ancestor::` などの軸、名前空間です。空の結果ではなくエラーにするのは、両者が画面上で同じに見えるためです。空だと、間違っていないセレクターを延々見直すことになります。
`//a[1]` で複数選ばれるのはなぜですか?
親ノードごとに最初の `a` を選んでいるからです(文書全体の最初の 1 つではありません)。これは XPath の仕様です(`//a` は「任意のノードの a 子要素」を意味し、位置述語は各グループ内で別々に数えます)。文書全体の最初の 1 つが欲しい場合は `(//a)[1]` と書きますが、このツールはその括弧記法には対応していません。代わりに結果の 1 行目を使ってください。XPath で最も誤解される点なので、便宜的に変えず標準の意味のままにしています。
リンクが抽出できないときは?
3 点を確認してください。属性名が正しいか(`link` ではなく `href`)。リンクが別の属性にないか(`data-href` や `onclick` を使うサイトもあります)。そして内容がスクリプトで描画されていないか —— このツールが解析するのは貼り付けたソースそのものです。JavaScript で描画されるページの「ソースを表示」から取った HTML には、そもそも要素が入っていません。開発者ツールの Elements パネルから描画後の HTML をコピーしてください。なお、このツールは URL を取得しに行きません(意図的です)。
JSONPath はどの構文に対応していますか?
ルート `$`(省略可)、子要素 `.key` と `['key']`、ワイルドカード `[*]` と `.*`、子孫検索 `..`、添字と和集合 `[0]` `[0,2]`、スライス `[1:3]`、フィルター式 `[?(@.price < 100)]`(存在判定、`==` `!=` `<` `<=` `>` `>=` の比較、`&&` `||`、括弧、否定 `!`)に対応します。それ以外はエラーにします:関数拡張(`length()`、`count()`、`match()`、`search()`、`value()`)、正規表現、フィルター内で `$` から始まる絶対パスです。
コード内のライブラリと結果が違うのはなぜですか?
JSONPath には今も単一の標準がないからです。RFC 9535 が登場したのは 2024 年で、それ以前は JavaScript の `jsonpath`、Python の `jsonpath-ng`、Java の Jayway がそれぞれ独自に実装し、3 点で食い違っていました:スライスの境界(`:3` は 3 番目を含むか)、子孫検索が自分自身を含むか(`$..a` が最上位の `a` を選べるか)、フィルターの比較が型をまたげるか(`@.price < "10"` で文字列と数値を比べるか)。ここではすべて RFC 9535 に従います:スライスは右開区間、子孫検索は自分自身を含む、型をまたぐ比較は false。したがってこのツールはローカルでパスが正しいか確認するのに向きます。コードに入れる前に、実際のデータで対象ライブラリの挙動を必ず確認してください。
「位置」の出力は何に使うのですか?
一致した各結果が文書内のどこにあるかを、`$.store.book[2].title` のようなパスで示します。実際には逆の流れがよくあります —— 値の見た目は分かっているが、構造の中での位置が分からないので、そこへのパスを書きたい、という場面です。値だけでは「いくつあるか」しか分かりませんが、位置なら「どこにあるか」が分かります。なお、特殊文字を含むキーは `['a.b']` の形で出力されます。これが `.a.b` との違いを保つ書き方です。

関連ツール