如何合并XPath谓词获取table的直接tr(含可选tbody包裹)?
Got it, let's sort out this XPath problem for you. Your original split expression works, but I totally get wanting a cleaner merged version—here's how to do it correctly, while making sure we exclude any deeply nested tr elements inside other tables:
Option 1: XPath 1.0 (Most Common Environments)
Since XPath 1.0 (used in most browsers and legacy tools) doesn't support grouping alternative paths within a single step directly, we can use a predicate to filter out unwanted nested trs:
//table[complex-predictor]//tr[count(ancestor::table) = 1]
How this works:
//table[complex-predictor]locates your target table(s)//trlooks for all tr descendants of that table, but the predicate[count(ancestor::table) = 1]removes any tr that has more than one table in its ancestor chain. Nested trs (like those inside/tbody/tr/td/table/tbody/tr) will have 2+ ancestor tables, so they get excluded automatically.- This covers both trs directly under the table and trs under a direct tbody child of the table—both only have your target table as their single table ancestor.
If you prefer to use only direct child steps (no //), you can stick with your original explicit version—it's totally valid, just not merged into a single path segment:
//table[complex-predictor]/tr | //table[complex-predictor]/tbody/tr
Option 2: XPath 2.0+ (Modern Tools)
If you're working with an environment that supports XPath 2.0 or later (like Saxon, XQuery, or some modern testing frameworks), you can use the grouped syntax you tried—with the correct parentheses placement:
//table[complex-predictor]/(tbody/tr | tr)
This directly combines the two paths into one, selecting:
- Trs that are direct children of your target table
- Trs that are direct children of a tbody which is itself a direct child of your target table
Since we're using direct child steps (/instead of//), no nested trs from inner tables will be picked up.
Why Your Original Merged Attempt Failed
Your try //table[complex-predictor](/tbody/tr | /tr) didn't work because XPath doesn't allow placing parentheses immediately after an element like that. In XPath 2.0+, the grouped alternative has to be part of the path step (inside the same level as the element), which is why the corrected version above works.
内容的提问来源于stack exchange,提问作者softwarevamp

