XPath(XML Path Language)는 XML 문서 내에서 특정 요소나 속성을 찾아 탐색하기 위한 쿼리 언어입니다. HTML/XML 파싱, 웹 스크래핑, XSLT 변환 등 다양한 분야에서 필수적으로 사용됩니다.

XPath 기본 개념

XPath는 XML 문서의 노드를 탐색하기 위한 언어로, 파일 시스템의 경로와 유사한 문법을 사용합니다.

핵심 특징

  • XML 문서의 트리 구조를 탐색
  • 배열 인덱스는 1부터 시작 (0이 아님)
  • 다양한 조건과 필터를 통한 정밀한 노드 선택 가능

노드 선택 기본 문법

경로 표현식

표현식 설명 예시
nodename 해당 노드명을 가진 모든 노드 선택 book
/ 루트 노드부터 시작 (절대 경로) /bookstore/book
// 현재 노드의 모든 하위(descendant) 노드에서 검색 //book
. 현재 노드 .
.. 부모 노드 ../title
@ 속성(attribute) 선택 @lang

와일드카드

표현식 설명 예시
* 모든 요소 노드 /bookstore/* (북스토어의 모든 자식 노드)
@* 모든 속성 //title[@*] (속성이 하나라도 있는 모든 title 노드)
// 모든 노드 //*

경로 표현식 예시

bookstore//book      <!-- bookstore 내부 어디에든 있는 모든 book 노드 -->
/bookstore/*         <!-- bookstore 모든 직접 자식 노드 -->
//*                  <!-- 문서  모든 노드 -->
//title[@*]          <!-- 속성이 하나 이상 있는 모든 title 노드 -->

Predicates (조건절)

대괄호 []를 사용하여 노드 선택에 조건을 추가할 수 있습니다.

위치 기반 선택

/bookstore/book[1]           <!--  번째 book 노드 -->
/bookstore/book[last()]      <!-- 마지막 book 노드 -->
/bookstore/book[last()-1]    <!-- 마지막에서  번째 book 노드 -->
/bookstore/book[position()<3]  <!-- 처음 2개의 book 노드 -->

속성 기반 선택

//title[@lang]               <!-- lang 속성이 있는 모든 title 노드 -->
//title[@lang='en']          <!-- lang 속성값이 'en' title 노드 -->

값 기반 선택

/bookstore/book[price>35.00]        <!-- price 35.00보다  book 노드 -->
/bookstore/book[price>35.00]/title  <!--  조건의 book  title 노드 -->

여러 경로 선택 (Union)

파이프 연산자 |를 사용하여 여러 경로를 동시에 선택할 수 있습니다.

//book/title | //book/price  <!-- 모든 book title price 노드 -->
//book | //cd                <!-- 모든 book cd 노드 -->

XPath 연산자

비교 연산자

연산자 설명 예시
= 같음 price=9.80
!= 같지 않음 price!=9.80
< 작음 price<9.80
<= 작거나 같음 price<=9.80
> price>9.80
>= 크거나 같음 price>=9.80

논리 연산자

연산자 설명 예시
or 논리 OR price=9.80 or price=9.70
and 논리 AND price>9.00 and price<9.90

산술 연산자

연산자 설명 예시
+ 덧셈 6 + 4
- 뺄셈 6 - 4
* 곱셈 6 * 4
div 나눗셈 8 div 4
mod 나머지 5 mod 2

노드 연산자

연산자 설명 예시
\| 두 노드 집합의 합집합 //book \| //cd

Axis (축) 표현식

축을 사용하면 현재 노드를 기준으로 다양한 방향의 노드를 선택할 수 있습니다.

축 표현식 설명
child::book 현재 노드의 자식 중 book 노드
attribute::lang 현재 노드의 lang 속성
child::* 현재 노드의 모든 자식 요소
attribute::* 현재 노드의 모든 속성
child::text() 현재 노드의 모든 텍스트 자식 노드
child::node() 현재 노드의 모든 자식 노드
descendant::book 현재 노드의 모든 book 자손 노드
ancestor::book 현재 노드의 모든 book 조상 노드
ancestor-or-self::book book 조상 노드와 현재 노드(book인 경우)
child::*/child::price 현재 노드의 손자 중 price 노드

JavaScript에서 XPath 사용하기

Ajax를 통한 XML 로드 및 XPath 적용

var xhttp = new XMLHttpRequest();

xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        showResult(xhttp.responseXML);
    }
};

xhttp.open("GET", "books.xml", true);
xhttp.send();

function showResult(xml) {
    var txt = "";
    var path = "/bookstore/book/title";

    // 표준 브라우저 (Chrome, Firefox, Safari 등)
    if (xml.evaluate) {
        var nodes = xml.evaluate(
            path,
            xml,
            null,
            XPathResult.ANY_TYPE,
            null
        );
        var result = nodes.iterateNext();

        while (result) {
            txt += result.childNodes[0].nodeValue + "<br>";
            result = nodes.iterateNext();
        }
    }
    // Internet Explorer 지원 (레거시)
    else if (window.ActiveXObject || xhttp.responseType == "msxml-document") {
        xml.setProperty("SelectionLanguage", "XPath");
        var nodes = xml.selectNodes(path);

        for (var i = 0; i < nodes.length; i++) {
            txt += nodes[i].childNodes[0].nodeValue + "<br>";
        }
    }

    document.getElementById("demo").innerHTML = txt;
}

XPathResult 타입

document.evaluate() 메서드에서 사용할 수 있는 결과 타입:

타입 설명
ANY_TYPE 자동으로 적절한 타입 반환
NUMBER_TYPE 숫자 값 반환
STRING_TYPE 문자열 값 반환
BOOLEAN_TYPE 불리언 값 반환
ORDERED_NODE_ITERATOR_TYPE 순서대로 노드 반복
UNORDERED_NODE_ITERATOR_TYPE 순서 무관 노드 반복
ORDERED_NODE_SNAPSHOT_TYPE 순서대로 노드 스냅샷
UNORDERED_NODE_SNAPSHOT_TYPE 순서 무관 노드 스냅샷
FIRST_ORDERED_NODE_TYPE 첫 번째 노드만 반환

실전 예제

예시 XML

<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
    <book category="cooking">
        <title lang="en">Italian Cooking</title>
        <author>Giada De Laurentiis</author>
        <price>30.00</price>
    </book>
    <book category="programming">
        <title lang="en">Learning XML</title>
        <author>Erik T. Ray</author>
        <price>39.95</price>
    </book>
</bookstore>

XPath 쿼리 예제

<!-- 모든  제목 -->
//book/title

<!-- programming 카테고리의  -->
//book[@category='programming']

<!-- 가격이 35 이상인 책의 제목 -->
//book[price>=35]/title

<!-- 영어로  모든 제목 -->
//title[@lang='en']

<!--  번째 책의 저자 -->
/bookstore/book[1]/author

참고 자료