ToolDeck

XPath 테스터

XPath 식을 XML에 대해 테스트하고 일치하는 모든 노드 표시

예시 시도

XML 입력

로컬에서 실행 · 시크릿 붙여넣기 안전

XPath란?

XPath(XML Path Language)는 XML 문서에서 노드를 선택하기 위한 쿼리 언어입니다. W3C가 XSLT 표준의 일부로 정의한 XPath는 XML 문서를 노드 트리로 취급하고, 해당 트리를 탐색하기 위한 경로 기반 문법을 제공합니다. //book[@category="fiction"]/title 같은 XPath 식은 category 속성이 "fiction"인 book 요소 내의 모든 title 요소를 선택합니다. 모든 주요 브라우저와 대부분의 XML 라이브러리가 지원하는 XPath 1.0은 1999년 W3C 권고안으로 발표되어 현재까지 가장 널리 사용되는 버전입니다.

XPath 식은 네 가지 결과 유형 중 하나를 반환합니다: 노드 세트, 문자열, 숫자, 부울. 노드 세트는 가장 일반적인 결과로, 0개 이상의 XML 노드(요소, 속성, 텍스트 노드, 주석, 처리 명령)를 포함합니다. 문자열, 숫자, 부울 결과는 count(), sum(), contains() 같은 XPath 함수와 부울 비교에서 나옵니다. 이 타입 시스템 덕분에 XPath는 데이터 추출뿐만 아니라 XSLT 스타일시트와 XML Schema 어설션의 조건부 논리 작성에도 적합합니다.

XPath 1.0 식은 어디서나 동작합니다: JavaScript의 document.evaluate(), Python의 lxml과 ElementTree, Java의 javax.xml.xpath, PHP의 DOMXPath, 그리고 xmllint 같은 커맨드라인 도구에서도 사용할 수 있습니다. XPath 2.0과 3.1은 더 풍부한 타입 시스템과 함수를 추가하지만 Saxon 같은 전용 엔진이 필요합니다. 기본적으로 XPath 1.0을 사용하세요. 시퀀스, 정규 표현식, 고차 함수가 필요할 때만 2.0이나 3.1을 고려하되, Saxon 또는 BaseX에 대한 의존성을 감수해야 합니다.

온라인 XPath 테스터를 사용하는 이유

올바른 식을 작성하려면 문서 구조를 이해하고 실제 데이터로 테스트해야 합니다. 이 도구는 프로젝트를 설정하거나 상용구 코드를 작성하지 않고도 식을 반복적으로 수정할 수 있는 대화형 환경을 제공합니다.

즉각적인 식 테스트
XML을 붙여넣고 식을 입력하면 일치하는 노드를 실시간으로 확인할 수 있습니다. 컴파일 단계도, REPL 설정도, 설치할 의존성도 없습니다.
🔒
개인정보 우선 처리
모든 XML 파싱과 쿼리 평가는 브라우저의 기본 DOMParser와 document.evaluate() API를 사용하여 브라우저에서 실행됩니다. XML 데이터가 기기를 벗어나지 않습니다.
🔍
복잡한 쿼리를 단계별로 디버깅
각 축(axis)과 조건자(predicate)를 개별적으로 테스트하여 긴 식을 분해하세요. 각 단계에서 어떤 노드가 일치하는지 정확히 확인하여 오류를 격리할 수 있습니다.
📋
결과를 문서화에 복사
일치하는 노드나 스칼라 결과를 한 번의 클릭으로 복사하세요. 버그 리포트, 테스트 어설션, 데이터 추출 스크립트에 붙여넣기에 유용합니다.

XPath 테스터 활용 사례

프론트엔드 개발자
document.evaluate()를 호출하는 JavaScript 코드에 임베드하기 전에 SVG 조작이나 XML 기반 설정에 사용할 XPath 선택자를 테스트합니다.
백엔드 엔지니어
Python, Java, Go로 추출 로직을 작성하기 전에 SOAP 응답이나 XML API 페이로드에 대한 쿼리를 검증합니다.
DevOps / 인프라
Maven pom.xml, Spring beans, CI 파이프라인 설정 같은 XML 설정 파일을 쿼리하여 파일을 편집하지 않고 의존성 버전을 추출하거나 설정을 확인합니다.
QA / 테스트 자동화
테스트 스크립트에 추가하기 전에 Selenium이나 Playwright용 XPath 로케이터를 작성하고 검증합니다. 누락된 속성이나 네임스페이스 접두사 같은 엣지 케이스를 테스트합니다.
데이터 엔지니어
ETL 파이프라인에 연결하기 전에 XML 데이터 피드(RSS, Atom, XBRL 재무 보고서)에 대한 쿼리를 프로토타입으로 만듭니다.
학생 / 학습자
샘플 XML로 XPath 축, 조건자, 함수를 실험해 보세요. 결과를 즉시 확인하여 트리 탐색 패턴에 대한 직관을 쌓을 수 있습니다.

XPath 축 참조

축은 현재(컨텍스트) 노드를 기준으로 탐색 방향을 정의합니다. 전체 문법은 axis::node-test[predicate]이지만, 대부분의 개발자는 일상적으로 축약 형태(//, @, ..)를 사용합니다. 이 표는 모든 XPath 1.0 축을 실용적인 예시와 함께 나열합니다.

예시설명
childchild::bookDirect children named "book"
descendantdescendant::titleAll "title" elements at any depth
parentparent::*The parent of the current node
ancestorancestor::catalogAll ancestors named "catalog"
following-siblingfollowing-sibling::bookSiblings after the current node
preceding-siblingpreceding-sibling::bookSiblings before the current node
attributeattribute::langThe "lang" attribute of the node
selfself::bookThe current node if it is "book"
descendant-or-self//titleShorthand: any "title" in the tree
ancestor-or-selfancestor-or-self::*Current node plus all ancestors

XPath 1.0 함수

이 언어는 노드 세트, 문자열, 숫자, 부울의 네 가지 범주에 걸쳐 27개의 내장 함수를 정의합니다. 다음은 쿼리를 작성할 때 가장 자주 사용하게 될 함수들입니다. 모두 이 테스터와 모든 표준 준수 구현체에서 지원됩니다.

함수범주설명
text()Node testSelects text content of a node
position()NumericReturns 1-based position in node set
last()NumericReturns size of current node set
count()NumericCounts nodes: count(//book)
contains()Stringcontains(@class, "active") — substring match
starts-with()Stringstarts-with(title, "The") — prefix match
normalize-space()StringStrips leading/trailing whitespace
string-length()NumericReturns character count of a string
sum()Numericsum(//price) — totals numeric values
not()Booleannot(@disabled) — negation
name()StringReturns element or attribute name

코드 예시

다음 예시는 프로그래밍 방식으로 식을 평가하는 방법을 보여줍니다. 각 코드 조각은 동일한 catalog.xml 구조를 사용하므로 언어 간 API 차이를 비교할 수 있습니다.

JavaScript (browser)
const xml = `<catalog>
  <book id="1"><title>1984</title><price>7.99</price></book>
  <book id="2"><title>Dune</title><price>12.99</price></book>
</catalog>`

const parser = new DOMParser()
const doc = parser.parseFromString(xml, 'application/xml')

// Select all book titles
const result = doc.evaluate('//book/title', doc, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null)
let node = result.iterateNext()
while (node) {
  console.log(node.textContent) // → "1984", "Dune"
  node = result.iterateNext()
}

// Get a numeric value
const sum = doc.evaluate('sum(//price)', doc, null, XPathResult.NUMBER_TYPE, null)
console.log(sum.numberValue) // → 20.98
Python (lxml)
from lxml import etree

xml = """<catalog>
  <book id="1"><title>1984</title><price>7.99</price></book>
  <book id="2"><title>Dune</title><price>12.99</price></book>
</catalog>"""

tree = etree.fromstring(xml.encode())

# Select elements by attribute
books = tree.xpath('//book[@id="1"]/title/text()')
print(books)  # → ['1984']

# Use predicates with position
first = tree.xpath('//book[1]/title/text()')
print(first)  # → ['1984']

# Boolean check
has_cheap = tree.xpath('boolean(//price[. < 10])')
print(has_cheap)  # → True
Java (javax.xml.xpath)
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.*;
import org.w3c.dom.*;

var factory = DocumentBuilderFactory.newInstance();
var builder = factory.newDocumentBuilder();
var doc = builder.parse(new java.io.File("catalog.xml"));

var xpath = XPathFactory.newInstance().newXPath();

// Select node set
NodeList titles = (NodeList) xpath.evaluate(
    "//book/title", doc, XPathConstants.NODESET
);
for (int i = 0; i < titles.getLength(); i++) {
    System.out.println(titles.item(i).getTextContent());
    // → "1984", "Dune"
}

// Evaluate to number
double total = (double) xpath.evaluate(
    "sum(//price)", doc, XPathConstants.NUMBER
);
System.out.println(total); // → 20.98
CLI (xmllint)
# Select all book titles
xmllint --xpath '//book/title/text()' catalog.xml
# → 1984Dune

# Select by attribute
xmllint --xpath '//book[@id="2"]/title' catalog.xml
# → <title>Dune</title>

# Count nodes
xmllint --xpath 'count(//book)' catalog.xml
# → 2

# Using xmlstarlet for formatted output
xmlstarlet sel -t -v '//book/title' -n catalog.xml
# → 1984
# → Dune

자주 묻는 질문

XPath 1.0과 XPath 3.1의 차이점은 무엇인가요?
XPath 1.0은 네 가지 데이터 타입(노드 세트, 문자열, 숫자, 부울)과 27개의 함수를 갖습니다. XPath 3.1은 시퀀스, 맵, 배열, 날짜/시간 타입, 정규 표현식, 고차 함수, JSON 지원을 추가합니다. 브라우저와 대부분의 표준 라이브러리는 XPath 1.0만 구현합니다. XPath 3.1은 Saxon 같은 전용 엔진이 필요합니다.
특정 속성 값을 가진 노드를 선택하려면 어떻게 하나요?
속성 축의 축약 표기인 @를 사용하여 조건자를 작성하세요. 예를 들어 //book[@category="fiction"]은 category 속성이 "fiction"인 모든 book 요소를 선택합니다. 여러 조건자를 조합할 수도 있습니다: //book[@category="fiction"][@year > 2000].
XML에 일치하는 요소가 있는데도 XPath가 결과를 반환하지 않는 이유는 무엇인가요?
가장 흔한 원인은 XML 네임스페이스입니다. XML이 기본 네임스페이스(xmlns="...")를 선언하면 요소는 접두사 없이도 해당 네임스페이스에 속합니다. XPath 1.0에서는 네임스페이스를 등록하고 식에 접두사를 사용해야 합니다. 브라우저 JavaScript에서는 document.evaluate()의 세 번째 인수로 네임스페이스 리졸버를 전달하세요.
XPath로 XML 내용을 수정할 수 있나요?
아니요. XPath는 읽기 전용 쿼리 언어입니다. 노드를 선택하고 평가할 수 있지만 삽입, 삭제, 수정은 불가능합니다. XML을 수정하려면 XSLT 변환, DOM 조작 메서드, 또는 편집을 위한 별도 API를 제공하는 Python의 lxml 같은 라이브러리를 사용하세요.
XPath에서 이중 슬래시(//)는 무엇을 의미하나요?
이중 슬래시는 descendant-or-self 축의 축약 표기입니다. //title 식은 "문서 트리의 어느 깊이에서든 모든 title 요소를 선택"함을 의미합니다. /descendant-or-self::node()/title의 전체 형태와 동일합니다. 식의 시작에서 //를 사용하면 전체 문서를 검색하고, 중간 경로에서 사용하면(예: /catalog//title) 특정 노드의 하위 항목을 검색합니다.
요소 노드 대신 텍스트 내용을 선택하려면 어떻게 하나요?
식에 /text()를 추가하세요. 예를 들어 //book/title/text()는 요소 노드가 아닌 각 title 요소의 텍스트 내용을 문자열 노드로 반환합니다. 코드에서는 text()를 사용하지 않고 반환된 요소 노드에서 .textContent에 접근할 수도 있습니다.
XML 쿼리 시 XPath가 CSS 선택자보다 빠른가요?
CSS 선택자는 브라우저에서 HTML과 DOM 탐색에 최적화되어 있습니다. XPath는 더 표현력이 풍부합니다: 부모 탐색, 형제 축, 숫자 조건자, CSS 선택자로는 표현할 수 없는 내장 함수를 지원합니다. HTML의 경우 CSS 선택자(querySelector)가 일반적으로 더 빠릅니다. XML의 경우 대부분의 서버 측 라이브러리는 XPath만 노출하며, CSS 선택자는 옵션 자체가 없습니다.