XPath(検索)とは?基礎から実践まで完全マスター

プログラミング・IT

「膨大なXMLファイルから、必要な情報だけを効率的に取り出せたら…」

そんな願いを叶えてくれるのが、XPath(エックスパス)です。

XPathを使えば、複雑な階層構造を持つXML文書から、ピンポイントで目的のデータを取得できます。

この記事では、XPathの基礎から実践的なテクニックまで、誰でも使いこなせるように解説していきますね。


スポンサーリンク

XPathの基本概念を理解しよう

XPathって何?

XPath(XML Path Language)は、XML文書内の要素や属性を指定するための言語です。

ファイルシステムのパスと似た考え方で、XMLの階層構造を辿っていきます。

例えば、「書店の中の本の中のタイトル」というように、目的地までの道筋を指定するイメージですね。

XPathが活躍する場面

Webスクレイピング

HTMLページから特定の情報を抽出する際に大活躍します。

データ処理

XMLファイルから必要なデータだけを取り出して加工できます。

テスト自動化

SeleniumなどのツールでWeb要素を特定する時に使われますね。

XSLT変換

XML文書を別の形式に変換する際、XPathで要素を選択します。

様々な開発現場で必須のスキルになっています。


基本的なパス式の書き方

絶対パスと相対パス

XPathには、2種類のパス指定方法があります。

絶対パス(/で始まる)

ルート要素から辿っていく方法です。

/bookstore/book/title

この例は、「ルートのbookstoreの中のbookの中のtitle」を指します。

相対パス(/で始まらない)

現在位置を基準にして辿る方法です。

book/title

どこから始めるかによって、結果が変わってきますね。

ノードの種類

XPathで扱えるのは、要素だけではありません。

要素ノード

<book><title>などのタグで囲まれた部分です。

属性ノード

要素に付いている属性を指します。

/bookstore/book/@isbn

@記号で属性を表現するのがポイントです。

テキストノード

タグに囲まれた実際の文字列データを取得できます。

/bookstore/book/title/text()

text()関数で、要素内のテキストだけを取り出せますよ。


ワイルドカードを使った柔軟な検索

アスタリスク(*)の活用

すべての要素にマッチするワイルドカードです。

/bookstore/*/title

bookstoreの直下にあるすべての要素の中のtitleを取得します。

要素名が分からない場合や、複数の異なる要素を対象にしたい時に便利ですね。

ダブルスラッシュ(//)で深い階層へ

どの階層にある要素でも選択できる強力な記法です。

//title

文書内のすべてのtitle要素を取得します。

階層の深さに関係なく検索できるのが魅力です。

ノードテスト

特定の種類のノードだけを選択できます。

//node()  # すべてのノード
//text()  # すべてのテキストノード
//@*      # すべての属性

ノードの種類で絞り込めるので、目的のデータに素早くアクセスできますね。


述語(Predicate)で条件を指定する

基本的な述語の使い方

角括弧[ ]で条件を指定します。

//book[price > 1000]

価格が1000円を超える本だけを選択できるんですね。

位置による選択

要素の順番を指定して取得できます。

//book[1]        # 最初の本
//book[last()]   # 最後の本
//book[position() < 3]  # 最初の2冊

インデックスは1から始まる点に注意しましょう。

属性による絞り込み

特定の属性を持つ要素だけを選択します。

//book[@category='fiction']
//book[@isbn]  # isbn属性を持つすべての本

属性の有無や値で、簡単にフィルタリングできますよ。

複数条件の組み合わせ

AND条件やOR条件も記述可能です。

//book[price > 1000 and @category='fiction']
//book[price < 500 or @discount='true']

andor演算子で、複雑な条件を表現できますね。


軸(Axis)を使った高度な選択

軸とは何か

軸は、現在のノードを基準にした方向を表します。

これを使うことで、親や兄弟など、様々な関係にあるノードを選択できるんですね。

よく使う軸の種類

child軸(子要素)

/bookstore/child::book

デフォルトの軸なので、通常は省略されます。

parent軸(親要素)

//title/parent::book

title要素の親であるbook要素を取得します。

ancestor軸(先祖要素)

//price/ancestor::book

priceより上位にあるすべてのbook要素が対象になりますね。

following-sibling軸(後続の兄弟)

//book[1]/following-sibling::book

最初の本の後に続く、すべての兄弟book要素を選択します。

preceding-sibling軸(先行する兄弟)

//book[last()]/preceding-sibling::book

最後の本より前にある兄弟要素を取得できます。

軸の実践的な使い方

親要素の属性を条件にする例です。

//title[parent::book/@category='science']

「カテゴリーがscienceの本のタイトル」を選択できますよ。


XPath関数を活用しよう

文字列関数

テキスト処理に便利な関数群です。

contains()関数

//book[contains(title, 'Java')]

タイトルに「Java」という文字列を含む本を検索します。

部分一致検索ができるので、とても便利ですね。

starts-with()関数

//book[starts-with(title, '入門')]

「入門」で始まるタイトルの本を抽出します。

string-length()関数

//book[string-length(title) > 20]

タイトルが20文字を超える本を選択できます。

normalize-space()関数

//book[normalize-space(title)='XMLガイド']

前後の空白を削除してから比較するので、正確なマッチングが可能です。

数値関数

数値データの処理に使えます。

sum()関数

sum(//book/price)

すべての本の価格を合計します。

count()関数

count(//book)

book要素の総数を取得できますね。

number()関数

//book[number(price) > 1000]

文字列を数値に変換してから比較します。

論理関数

真偽値を扱う関数です。

not()関数

//book[not(@discount)]

discount属性を持たない本を選択します。

否定条件を簡潔に書けるのが魅力ですね。

true()とfalse()関数

//book[@available=true()]

論理値の比較に使用できます。


実践的なXPathの例

Eコマースサイトでの商品検索

実際の使用例を見ていきましょう。

特定価格帯の商品

//product[price >= 1000 and price <= 5000]

1000円以上5000円以下の商品を抽出します。

在庫ありで評価4以上

//product[@inStock='true' and rating >= 4]

複数の条件を組み合わせて、最適な商品を見つけられますね。

カテゴリー内で最安値

//product[@category='electronics'][price = min(//product[@category='electronics']/price)]

電化製品の中で最も安い商品を特定できます。

ニュースサイトでの記事検索

今日の記事

//article[contains(date, '2025-10-21')]

日付で記事を絞り込めます。

特定の著者の記事

//article[author='山田太郎']

お気に入りの著者の記事だけを集められますね。

HTML構造の解析

特定のクラスを持つ要素

//div[@class='container']

WebスクレイピングでHTMLから情報を抽出する際の基本パターンです。

リンクのURL取得

//a/@href

ページ内のすべてのリンク先を一括取得できますよ。


プログラミング言語でXPathを使う

Javaでの実装

Javaには標準でXPath機能が組み込まれています。

import javax.xml.xpath.*;
import org.w3c.dom.*;

XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();

String expression = "//book[@category='fiction']/title";
NodeList nodes = (NodeList) xpath.evaluate(
    expression, 
    document, 
    XPathConstants.NODESET
);

for (int i = 0; i < nodes.getLength(); i++) {
    System.out.println(nodes.item(i).getTextContent());
}

XPathの式をそのまま文字列として渡せるので簡単です。

Pythonでの実装

Pythonのlxmlライブラリが便利です。

from lxml import etree

tree = etree.parse('books.xml')
titles = tree.xpath('//book[@category="fiction"]/title/text()')

for title in titles:
    print(title)

わずか数行で実装できますね。

JavaScriptでの実装

ブラウザでも使えます。

let result = document.evaluate(
    '//div[@class="content"]',
    document,
    null,
    XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
    null
);

for (let i = 0; i < result.snapshotLength; i++) {
    console.log(result.snapshotItem(i));
}

動的なWebページの要素取得に活用できますよ。


XPathのパフォーマンス最適化

効率的な検索パターン

パフォーマンスを意識した書き方を心がけましょう。

避けるべきパターン

//*[contains(@id, 'button')]  # 遅い

すべての要素を検査するため、処理時間がかかります。

推奨パターン

//button[contains(@id, 'submit')]  # 速い

要素名を指定することで、検索範囲が絞り込まれますね。

インデックスの活用

位置指定は慎重に使いましょう。

(//book)[1]      # すべてのbookから1番目
//book[1]        # 各親要素内の1番目のbook

括弧の位置で意味が変わるので、注意が必要です。

キャッシュの利用

同じXPath式を繰り返し使う場合は、コンパイル済みの式を再利用しましょう。

XPathExpression expr = xpath.compile("//book/title");
// 複数回使用できる

パフォーマンスが大幅に向上しますよ。


XPathのデバッグ方法

ブラウザの開発者ツール

ChromeやFirefoxの開発者コンソールで、XPathを直接試せます。

$x('//div[@class="container"]')

この関数で、即座に結果を確認できますね。

オンラインツールの活用

XPath専用のテストサイトが多数あります。

XMLとXPath式を入力すれば、マッチする要素がハイライト表示されます。

試行錯誤しながら学習するのに最適です。

エラーの読み方

よくあるエラーメッセージを理解しましょう。

Invalid expression

構文エラーです。括弧の閉じ忘れやスペルミスをチェックしてください。

Empty node set

該当する要素が見つからなかった場合です。

パスが正しいか、XMLの構造を再確認しましょう。


XPathとCSSセレクタの比較

それぞれの特徴

両方ともHTML/XML要素を選択できますが、違いがあります。

XPathの強み:

  • 親要素や先祖要素を選択できる
  • テキスト内容で検索できる
  • 複雑な条件を柔軟に指定できる
  • XML文書の処理に最適

CSSセレクタの強み:

  • 書き方がシンプル
  • 実行速度が速い
  • Webデザイナーにとって馴染み深い
  • スタイル適用との親和性が高い

使い分けの目安

HTMLのスクレイピングでは、CSSセレクタの方が簡潔に書けることが多いですね。

一方、XMLデータの複雑な検索や、親要素へのアクセスが必要な場合は、XPathが適しています。

両方の特性を理解して、状況に応じて使い分けましょう。


よくある間違いと解決方法

名前空間の扱い

名前空間付きのXML文書では、特別な対応が必要です。

NamespaceContext nsContext = new NamespaceContext() {
    public String getNamespaceURI(String prefix) {
        if ("bs".equals(prefix)) {
            return "http://example.com/bookstore";
        }
        return null;
    }
};
xpath.setNamespaceContext(nsContext);

String expression = "//bs:book/bs:title";

名前空間を正しく設定しないと、要素が見つかりません。

大文字小文字の区別

XPathは大文字と小文字を区別します。

//Book  # NG
//book  # OK

要素名は正確に記述する必要がありますね。

属性と要素の混同

//book/@title    # title属性
//book/title     # title子要素

@の有無で意味が変わるので、注意しましょう。


高度なテクニック

ユニオン演算子

複数のパスを同時に指定できます。

//book/title | //book/author

titleとauthorの両方を一度に取得できますね。

変数の使用

XSLT内では、変数を使った動的なXPathも可能です。

$bookPrice > 1000

プログラム的な柔軟性が増します。

複雑な述語のネスト

条件を入れ子にして、詳細な絞り込みができます。

//book[author[name='山田太郎' and @country='Japan']]/title

著者が日本在住の山田太郎さんの本のタイトルを取得します。


まとめ:XPathをマスターしてデータ検索を効率化

XPathは、XML/HTMLからデータを抽出する強力なツールです。

基本的な構文から始めて、徐々に高度なテクニックを習得していきましょう。

この記事の重要ポイント:

  • XPathはXML文書内の要素を指定するパス言語
  • 絶対パスと相対パスの使い分けが基本
  • 述語で条件を指定して絞り込みができる
  • 軸を使えば親や兄弟など様々な関係の要素を選択可能
  • 豊富な関数で柔軟なデータ処理が実現できる
  • パフォーマンスを意識した書き方が重要
  • 主要なプログラミング言語で標準サポートされている
  • デバッグツールを活用して効率的に学習できる

まずは簡単なXPath式から試してみましょう。

ブラウザの開発者ツールで実際に動かしながら学ぶと、理解が深まりますよ。

コメント

タイトルとURLをコピーしました