ToolDeck

เครื่องมือทดสอบ XPath

ทดสอบนิพจน์ XPath กับ XML และดูโหนดที่ตรงกันทั้งหมด

ลองตัวอย่าง

ป้อนข้อมูล XML

ประมวลผลในเครื่อง · ปลอดภัยในการวางข้อมูลลับ

XPath คืออะไร?

XPath (XML Path Language) คือภาษาคิวรีสำหรับเลือกโหนดจากเอกสาร XML ซึ่งกำหนดโดย W3C เป็นส่วนหนึ่งของมาตรฐาน XSLT โดย XPath จะมองเอกสาร XML เป็นโครงสร้างแบบต้นไม้ของโหนด และให้ไวยากรณ์แบบ path สำหรับนำทางในต้นไม้นั้น ตัวอย่างเช่น นิพจน์ //book[@category="fiction"]/title จะเลือกทุก element title ที่อยู่ภายใน element book ซึ่ง attribute category มีค่าเท่ากับ "fiction" XPath 1.0 ซึ่งเป็นเวอร์ชันที่รองรับโดยเบราว์เซอร์หลักทุกตัวและไลบรารี XML ส่วนใหญ่ ได้รับการเผยแพร่เป็น W3C Recommendation ในปี 1999 และยังคงเป็นเวอร์ชันที่ใช้กันแพร่หลายที่สุด

นิพจน์ XPath ส่งคืนผลลัพธ์หนึ่งใน 4 ประเภท ได้แก่ ชุดโหนด สตริง ตัวเลข หรือค่าบูลีน ชุดโหนดเป็นผลลัพธ์ที่พบบ่อยที่สุด และประกอบด้วยโหนด XML ตั้งแต่ศูนย์โหนดขึ้นไป (element, attribute, โหนดข้อความ, คอมเมนต์ หรือ processing instruction) ผลลัพธ์ประเภทสตริง ตัวเลข และบูลีนมาจากฟังก์ชัน XPath เช่น count(), sum(), contains() และการเปรียบเทียบแบบบูลีน ระบบชนิดข้อมูลนี้ทำให้ XPath เหมาะสำหรับทั้งการดึงข้อมูลและการเขียน conditional logic ใน XSLT stylesheet และ XML Schema assertion

นิพจน์ในเวอร์ชัน 1.0 ทำงานได้ทุกที่ ไม่ว่าจะเป็น document.evaluate() ใน JavaScript, lxml และ ElementTree ใน Python, javax.xml.xpath ใน Java, DOMXPath ใน PHP หรือเครื่องมือ command-line อย่าง xmllint เวอร์ชัน 2.0 และ 3.1 เพิ่มระบบชนิดข้อมูลและฟังก์ชันที่หลากหลายขึ้น แต่ต้องใช้ engine เฉพาะอย่าง Saxon ใช้เวอร์ชัน 1.0 เป็นค่าเริ่มต้น เลือก 2.0 หรือ 3.1 เฉพาะเมื่อต้องการ sequence, regular expression หรือ higher-order function — และยอมรับการพึ่งพา Saxon หรือ BaseX

ทำไมต้องใช้เครื่องมือทดสอบ XPath ออนไลน์?

การเขียนนิพจน์ที่ถูกต้องต้องอาศัยความเข้าใจโครงสร้างเอกสารและการทดสอบกับข้อมูลจริง เครื่องมือนี้ให้สภาพแวดล้อมแบบ interactive สำหรับปรับปรุงนิพจน์โดยไม่ต้องตั้งค่าโปรเจกต์หรือเขียน boilerplate code

ทดสอบนิพจน์ได้ทันที
วาง XML พิมพ์นิพจน์ และดูโหนดที่ตรงกันแบบ real time ไม่มีขั้นตอน compile ไม่ต้องตั้งค่า REPL ไม่ต้องติดตั้ง dependency
🔒
ประมวลผลโดยให้ความเป็นส่วนตัวก่อน
การแยกวิเคราะห์ XML และการประเมินคิวรีทั้งหมดทำงานในเบราว์เซอร์โดยใช้ DOMParser และ document.evaluate() API ที่มีอยู่ในตัว ข้อมูล XML ของคุณจะไม่ออกจากเครื่องของคุณเลย
🔍
ดีบักคิวรีที่ซับซ้อนทีละขั้นตอน
แยกนิพจน์ที่ยาวโดยทดสอบแต่ละ axis และ predicate แยกกัน ดูว่าโหนดใดตรงกันในแต่ละขั้นตอนเพื่อระบุข้อผิดพลาด
📋
คัดลอกผลลัพธ์สำหรับเอกสาร
คัดลอกโหนดที่ตรงกันหรือผลลัพธ์แบบสเกลาร์ด้วยคลิกเดียว มีประโยชน์สำหรับการวางในรายงานบั๊ก test assertion หรือสคริปต์ดึงข้อมูล

กรณีการใช้งานเครื่องมือทดสอบ XPath

นักพัฒนา frontend
ทดสอบตัวเลือก XPath สำหรับการจัดการ SVG หรือไฟล์ config ที่ใช้ XML ก่อนนำไปฝังในโค้ด JavaScript ที่เรียก document.evaluate()
วิศวกร backend
ตรวจสอบคิวรีกับ SOAP response หรือ XML API payload ก่อนเขียน extraction logic ใน Python, Java หรือ Go
DevOps / โครงสร้างพื้นฐาน
คิวรีไฟล์ config XML (Maven pom.xml, Spring beans, CI pipeline config) เพื่อดึงเวอร์ชัน dependency หรือตรวจสอบการตั้งค่าโดยไม่ต้องแก้ไขไฟล์
QA / การทดสอบอัตโนมัติ
สร้างและตรวจสอบ XPath locator สำหรับ Selenium หรือ Playwright ก่อนเพิ่มในสคริปต์ทดสอบ ทดสอบ edge case เช่น attribute ที่หายไปหรือ namespace prefix
วิศวกรข้อมูล
สร้างต้นแบบคิวรีสำหรับ XML data feed (RSS, Atom, XBRL financial report) ก่อนนำไปเชื่อมต่อกับ ETL pipeline
นักเรียน / ผู้เริ่มต้น
ทดลองใช้ XPath axis, predicate และฟังก์ชันด้วย XML ตัวอย่าง ดูผลลัพธ์ทันทีเพื่อสร้างความเข้าใจเกี่ยวกับรูปแบบการนำทางในต้นไม้

ตารางอ้างอิง XPath Axis

Axis กำหนดทิศทางการนำทางสัมพัทธ์กับโหนดปัจจุบัน (context node) ไวยากรณ์เต็มรูปคือ axis::node-test[predicate] แม้นักพัฒนาส่วนใหญ่จะใช้รูปแบบย่อ (//, @, ..) เป็นประจำ ตารางนี้แสดง axis ทั้งหมดของเวอร์ชัน 1.0 พร้อมตัวอย่างที่ใช้งานได้จริง

Axisตัวอย่างคำอธิบาย
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 ฟังก์ชันในตัวใน 4 หมวดหมู่ ได้แก่ node set, string, number และ boolean นี่คือฟังก์ชันที่คุณจะใช้บ่อยที่สุดเมื่อเขียนคิวรี ทั้งหมดได้รับการรองรับโดยเครื่องมือทดสอบนี้และทุก implementation ที่สอดคล้องมาตรฐาน

ฟังก์ชันหมวดหมู่คำอธิบาย
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 คืออะไร?
เวอร์ชัน 1.0 มีชนิดข้อมูล 4 ประเภท (node set, string, number, boolean) และ 27 ฟังก์ชัน เวอร์ชัน 3.1 เพิ่ม sequence, map, array, ชนิดวันที่และเวลา, regular expression, higher-order function และรองรับ JSON เบราว์เซอร์และไลบรารีมาตรฐานส่วนใหญ่ implement เฉพาะเวอร์ชัน 1.0 เวอร์ชัน 3.1 ต้องใช้ engine เฉพาะอย่าง Saxon
จะเลือกโหนดที่มีค่า attribute เฉพาะได้อย่างไร?
ใช้ predicate ร่วมกับตัวย่อ @ สำหรับ attribute axis ตัวอย่างเช่น //book[@category="fiction"] เลือก element book ทั้งหมดที่ attribute category มีค่าเท่ากับ "fiction" คุณสามารถรวม predicate หลายตัวได้: //book[@category="fiction"][@year > 2000]
ทำไม XPath ถึงไม่คืนผลลัพธ์ทั้งที่ XML มี element ที่ตรงกัน?
สาเหตุที่พบบ่อยที่สุดคือ XML namespace หาก XML ของคุณประกาศ default namespace (xmlns="...") element จะอยู่ใน namespace นั้นแม้ไม่มี prefix ในเวอร์ชัน 1.0 คุณต้องลงทะเบียน namespace และใช้ prefix ในนิพจน์ ใน browser JavaScript ให้ส่ง namespace resolver เป็น argument ที่สามให้กับ document.evaluate()
XPath สามารถแก้ไขเนื้อหา XML ได้หรือไม่?
ไม่ได้ XPath เป็นภาษาคิวรีแบบอ่านอย่างเดียว ใช้เลือกและประเมินโหนดเท่านั้น ไม่สามารถแทรก ลบ หรืออัปเดตโหนดได้ หากต้องการแก้ไข XML ให้ใช้ XSLT transformation, DOM manipulation method หรือไลบรารีอย่าง lxml ใน Python ที่มี API แยกต่างหากสำหรับการแก้ไข
double slash (//) ใน XPath หมายความว่าอะไร?
Double slash คือตัวย่อของ descendant-or-self axis นิพจน์ //title หมายถึง "เลือก element title ทั้งหมดในต้นไม้เอกสาร ไม่ว่าจะอยู่ในระดับความลึกใด" ซึ่งเทียบเท่ากับรูปแบบเต็ม /descendant-or-self::node()/title การใช้ // ที่ต้นนิพจน์จะค้นหาตลอดทั้งเอกสาร การใช้กลางเส้นทาง (เช่น /catalog//title) จะค้นหาเฉพาะใน descendant ของโหนดที่ระบุ
จะเลือกเนื้อหาข้อความแทนที่จะเป็นโหนด element ได้อย่างไร?
ต่อท้ายนิพจน์ด้วย /text() ตัวอย่างเช่น //book/title/text() คืนเนื้อหาข้อความของแต่ละ element title เป็น text node แทนที่จะเป็น element node เอง ในโค้ด คุณยังสามารถเข้าถึง .textContent บน element node ที่ได้รับคืนโดยไม่ต้องใช้ text()
XPath เร็วกว่า CSS selector สำหรับการคิวรี XML หรือไม่?
CSS selector ได้รับการปรับแต่งสำหรับ HTML และการนำทาง DOM ในเบราว์เซอร์ XPath มีความสามารถแสดงออกมากกว่า รองรับการนำทางขึ้นสู่ parent, sibling axis, numeric predicate และฟังก์ชันในตัวที่ CSS selector ไม่สามารถแสดงออกได้ สำหรับ HTML, CSS selector (querySelector) มักจะเร็วกว่า สำหรับ XML, ไลบรารี server-side ส่วนใหญ่เปิดให้ใช้เฉพาะ XPath เท่านั้น — CSS selector ไม่ใช่ตัวเลือกเลย