آزمایشگر XPath
عبارات XPath را روی XML آزمایش کنید و همه گرههای منطبق را ببینید
ورودی XML
XPath چیست؟
XPath (زبان مسیر XML) یک زبان پرسوجو برای انتخاب گرهها از یک سند XML است. این زبان توسط W3C به عنوان بخشی از استاندارد XSLT تعریف شده است. XPath یک سند XML را به صورت درختی از گرهها در نظر میگیرد و نحوی مبتنی بر مسیر برای پیمایش آن درخت فراهم میکند. عبارتی مانند //book[@category="fiction"]/title هر عنصر title درون عنصر book که ویژگی category آن برابر با "fiction" است را انتخاب میکند. نسخه XPath 1.0 که توسط تمام مرورگرهای اصلی و بیشتر کتابخانههای XML پشتیبانی میشود، در سال ۱۹۹۹ به عنوان توصیه W3C منتشر شد و همچنان پرکاربردترین نسخه است.
عبارات XPath یکی از چهار نوع نتیجه را بازمیگردانند: مجموعهگره، رشته، عدد یا بولی. مجموعهگره رایجترین نتیجه است و شامل صفر یا چند گره XML (عناصر، ویژگیها، گرههای متنی، نظرات یا دستورالعملهای پردازشی) میشود. نتایج رشته، عدد و بولی از توابع XPath مانند count()، sum()، contains() و مقایسههای بولی به دست میآیند. این سیستم نوع، XPath را هم برای استخراج داده و هم برای نوشتن منطق شرطی در صفحات سبک XSLT و اثباتهای XML Schema مناسب میسازد.
عبارات نسخه 1.0 در همه جا کار میکنند: document.evaluate() در JavaScript، lxml و ElementTree در Python، javax.xml.xpath در Java، DOMXPath در PHP، و ابزارهای خط فرمان مانند xmllint. نسخههای 2.0 و 3.1 سیستمهای نوع و توابع غنیتری اضافه میکنند اما به موتورهای اختصاصی مانند Saxon نیاز دارند. به طور پیشفرض از نسخه 1.0 استفاده کنید. تنها زمانی به 2.0 یا 3.1 بروید که به دنبالهها، عبارات منظم یا توابع مرتبه بالاتر نیاز دارید — و وابستگی به Saxon یا BaseX را بپذیرید.
چرا از آزمایشگر XPath آنلاین استفاده کنیم؟
نوشتن عبارات صحیح نیازمند درک ساختار سند و آزمایش روی داده واقعی است. این ابزار یک محیط تعاملی فراهم میکند تا بدون راهاندازی پروژه یا نوشتن کد تکراری، روی عبارات تکرار کنید.
موارد استفاده آزمایشگر XPath
مرجع محورهای XPath
یک محور جهت پیمایش را نسبت به گره فعلی (زمینه) تعریف میکند. نحو کامل axis::node-test[predicate] است، هرچند بیشتر توسعهدهندگان از اشکال کوتاهشده (//, @, ..) به صورت روزانه استفاده میکنند. این جدول تمام محورهای نسخه 1.0 را با مثالهای کاربردی فهرست میکند.
| محور | مثال | توضیح |
|---|---|---|
| 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
این زبان ۲۷ تابع داخلی را در چهار دسته تعریف میکند: مجموعهگره، رشته، عدد و بولی. اینها توابعی هستند که هنگام نوشتن پرسوجوها بیشتر از همه استفاده خواهید کرد. همه آنها توسط این آزمایشگر و هر پیادهسازی سازگار پشتیبانی میشوند.
| تابع | دسته | توضیح |
|---|---|---|
| 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