เครื่องมือทดสอบ 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
กรณีการใช้งานเครื่องมือทดสอบ XPath
ตารางอ้างอิง XPath Axis
Axis กำหนดทิศทางการนำทางสัมพัทธ์กับโหนดปัจจุบัน (context node) ไวยากรณ์เต็มรูปคือ axis::node-test[predicate] แม้นักพัฒนาส่วนใหญ่จะใช้รูปแบบย่อ (//, @, ..) เป็นประจำ ตารางนี้แสดง axis ทั้งหมดของเวอร์ชัน 1.0 พร้อมตัวอย่างที่ใช้งานได้จริง
| Axis | ตัวอย่าง | คำอธิบาย |
|---|---|---|
| child | child::book | Direct children named "book" |
| descendant | descendant::title | All "title" elements at any depth |
| parent | parent::* | The parent of the current node |
| ancestor | ancestor::catalog | All ancestors named "catalog" |
| following-sibling | following-sibling::book | Siblings after the current node |
| preceding-sibling | preceding-sibling::book | Siblings before the current node |
| attribute | attribute::lang | The "lang" attribute of the node |
| self | self::book | The current node if it is "book" |
| descendant-or-self | //title | Shorthand: any "title" in the tree |
| ancestor-or-self | ancestor-or-self::* | Current node plus all ancestors |
ฟังก์ชัน XPath 1.0
ภาษานี้กำหนด 27 ฟังก์ชันในตัวใน 4 หมวดหมู่ ได้แก่ node set, string, number และ boolean นี่คือฟังก์ชันที่คุณจะใช้บ่อยที่สุดเมื่อเขียนคิวรี ทั้งหมดได้รับการรองรับโดยเครื่องมือทดสอบนี้และทุก implementation ที่สอดคล้องมาตรฐาน
| ฟังก์ชัน | หมวดหมู่ | คำอธิบาย |
|---|---|---|
| text() | Node test | Selects text content of a node |
| position() | Numeric | Returns 1-based position in node set |
| last() | Numeric | Returns size of current node set |
| count() | Numeric | Counts nodes: count(//book) |
| contains() | String | contains(@class, "active") — substring match |
| starts-with() | String | starts-with(title, "The") — prefix match |
| normalize-space() | String | Strips leading/trailing whitespace |
| string-length() | Numeric | Returns character count of a string |
| sum() | Numeric | sum(//price) — totals numeric values |
| not() | Boolean | not(@disabled) — negation |
| name() | String | Returns element or attribute name |
ตัวอย่างโค้ด
ตัวอย่างเหล่านี้แสดงวิธีประเมินนิพจน์โดยใช้โปรแกรม แต่ละตัวอย่างใช้โครงสร้าง catalog.xml เดียวกัน เพื่อให้คุณเปรียบเทียบความแตกต่างของ API ในแต่ละภาษาได้
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.98from 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) # → Trueimport 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# 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