빠른 참조

XPath 치트시트

XPath 1.0/2.0 종합 참조 가이드: CSS 선택자 비교, 축(Axes), 조건자(Predicates), 함수 및 노드 탐색 표현식을 정리합니다.

· 게시일

XPath(XML Path Language)는 XML 또는 HTML 문서에서 노드를 선택하기 위한 표현식 언어입니다.

테스트

XPath 테스트베드

대화형으로 XPath 표현식을 테스트하고 실험해 보세요:

브라우저 콘솔

$x("//div")

Chrome, Edge 및 Firefox 개발자 도구 콘솔에서 바로 사용할 수 있습니다.

선택자

하위 요소 선택자

CSS XPath 참조
h1 //h1 ?
div p //div//p ?
ul > li //ul/li ?
ul > li > a //ul/li/a
div > * //div/*
:root / ?
:root > body /body

속성 선택자

CSS XPath 참조
#id //*[@id="id"] ?
.class //*[@class="class"] ?
input[type="submit"] //input[@type="submit"]
a#abc[for="xyz"] //a[@id="abc"][@for="xyz"] ?
a[rel] //a[@rel]
a[href^='/'] //a[starts-with(@href, '/')] ?
a[href$='pdf'] //a[ends-with(@href, '.pdf')]
a[href*='://'] //a[contains(@href, '://')]
a[rel~='help'] //a[contains(@rel, 'help')] ?

순서 및 인덱스 선택자

CSS XPath 참조
ul > li:first-of-type //ul/li[1] ?
ul > li:nth-of-type(2) //ul/li[2]
ul > li:last-of-type //ul/li[last()]
li#id:first-of-type //li[1][@id="id"] ?
a:first-child //*[1][name()="a"]
a:last-child //*[last()][name()="a"]

형제 요소

CSS XPath 참조
h1 ~ ul //h1/following-sibling::ul ?
h1 + ul //h1/following-sibling::ul[1]
h1 ~ #id //h1/following-sibling::*[@id="id"]

jQuery 대응 표현

jQuery XPath 참조
$('ul > li').parent() //ul/li/.. ?
$('li').closest('section') //li/ancestor-or-self::section
$('a').attr('href') //a/@href ?
$('span').text() //span/text()

조건 및 논리

조건 XPath 참조
h1:not([id]) //h1[not(@id)] ?
텍스트 정확 일치 //button[text()="Submit"] ?
텍스트 부분 일치 //button[contains(text(),"Go")]
산술 조건 //product[@price > 2.50]
임의의 자식 요소를 가짐 //ul[*]
특정 자식 요소를 가짐 //ul[li]
OR 논리 //a[@name or @href] ?
합집합(집합 병합) //a | //div ?

클래스 검사

//div[contains(concat(' ',normalize-space(@class),' '),' foobar ')]

XPath 1.0에는 공백으로 구분된 토큰 일치 연산자가 없으므로, 이 표준 우회 방법으로 전체 클래스명을 안전하게 비교합니다.

표현식

단계와 축

표현식의 구조:

// ul / a[@id='link']
축 단계 축 단계

접두사

접두사 예제 의미
// //hr[@class='edge'] 문서 내 모든 위치
./ ./a 현재 컨텍스트 기준 상대 위치
/ /html/body/div 루트 요소부터

표현식은 이러한 접두사 중 하나로 시작할 수 있습니다.

축

축 예제 의미
/ //ul/li/a 직계 자식 노드
// //*[@id="list"]//a 모든 하위 노드

각 단계는 /로 구분됩니다. 모든 하위 수준을 일치시키려면 //를 사용하세요.

단계

//div
//div[@name='box']
//*[@id='link']

단계는 태그 이름과 조건자([...])를 포함할 수 있으며 둘 다 선택 사항입니다. 노드 값을 직접 대상으로 삼을 수도 있습니다:

//a/text()     #=> "Go home"
//a/@href      #=> "index.html"
//a/*          #=> All children of <a>

조건자(Predicates)

조건자(Predicates)

//div[true()]
//div[@class="head"]
//div[@class="head"][@id="top"]

조건이 일치할 때 노드 집합을 필터링합니다. 조건자는 연속해서 체이닝할 수 있습니다.

연산자

# Comparison
//a[@id = "xyz"]
//a[@id != "xyz"]
//a[@price > 25]
# Logic (and/or)
//div[@id="head" and position()=2]
//div[(x and y) or not(z)]

조건자 내부에서 노드 사용

# Inside functions
//ul[count(li) > 2]
//ul[count(li[@class='hide']) > 0]
# Returns <ul> only if it has an <li> child
//ul[li]

인덱싱

//a[1]                  # First <a> (1-based index)
//a[last()]             # Last <a>
//ol/li[2]              # Second <li>
//ol/li[position()=2]   # Same as above
//ol/li[position()>1]   # All except the first

연결 순서

a[1][@href='/']
a[@href='/'][1]

순서가 중요합니다. 첫 번째 식은 1번 항목의 href를 검사하고, 두 번째 식은 먼저 href로 필터링한 뒤 첫 번째 결과를 고릅니다.

중첩된 조건자

//section[.//h1[@id='hi']]

id='hi'를 가진 <h1> 하위 요소를 포함하는 <section> 요소를 반환합니다.

함수

노드 함수

name()                     # Starts with: //[starts-with(name(), 'h')]
text()                     # Exact match: //button[text()="Submit"]
                           # Value: //button/text()
lang(str)
namespace-uri()
count()                    # //table[count(tr)=1]
position()                 # //ol/li[position()=2]

불리언 함수

not(expr)                  # //button[not(starts-with(text(),"Submit"))]

문자열 함수

contains()                 # //span[contains(@class,"head")]
starts-with()              # //span[starts-with(@class,"head")]
ends-with()                # //span[ends-with(@class,"head")]
concat(x, y)
substring(str, start, len)
substring-before("01/02", "/")  #=> "01"
substring-after("01/02", "/")   #=> "02"
translate()
normalize-space()
string-length()

타입 변환

string()
number()
boolean()

축

축 사용하기

//ul/li                       # ul > li
//ul/child::li                # ul > li (explicit child axis)
//ul/following-sibling::li    # ul ~ li
//ul/descendant-or-self::li   # ul li
//ul/ancestor-or-self::li     # $('ul').closest('li')

축 문법:

// ul /child:: li
축 단계 축 단계

기타 축

축 단축 표기 설명
ancestor 상위(조상) 요소
ancestor-or-self 컨텍스트 노드와 그 조상
attribute @ @href는 attribute::href의 단축형
child 기본 축: div는 child::div와 같음
descendant 자손(하위) 노드
descendant-or-self // //는 /descendant-or-self::node()/의 단축형
namespace 네임스페이스 노드
self . .은 self::node()의 단축형
parent .. ..은 parent::node()의 단축형
following 닫는 태그 이후의 모든 노드
following-sibling 현재 노드 뒤의 형제 노드
preceding 여는 태그 이전의 모든 노드
preceding-sibling 현재 노드 앞의 형제 노드

합집합(Unions)

//a | //span

두 개 이상의 노드 집합을 하나로 합칠 때는 |를 사용하세요.

예제

자주 쓰이는 쿼리 패턴

//*                 # All elements
count(//*)          # Count all elements
(//h1)[1]/text()    # Text of the very first h1 heading in document
//li[span]          # Find <li> containing a <span> child
//ul/li/..          # Navigate back to parent <ul>

상위(부모) 요소 찾기

//section[h1[@id='section-name']]

직계 자식 h1#section-name을 포함하는 <section>을 찾습니다.

//section[.//h1[@id='section-name']]

모든 하위 요소 중 h1#section-name을 포함하는 <section>을 찾습니다.

관련 주제