XPath中contains()功能解析及表格行匹配异常问题咨询
Hey there! Let's tackle your XPath questions step by step.
contains() function do in XPath? The contains() function is a core XPath tool for checking if one string includes another substring. It returns a boolean value (true or false) based on this check. Here's how it works:
- Syntax:
contains(string_to_search, substring_to_find) - Example 1:
contains('XPath is useful', 'useful')returnstruebecause the first string includes the substring "useful". - Example 2: A common real-world use case is targeting elements by partial attribute values, like finding all buttons with a class that includes "btn":
//button[contains(@class, 'btn')]
Just note: contains() is case-sensitive, so contains('Hello', 'hello') would return false.
Let's break down what's happening with your expressions, because the issue comes down to how you're using . (the current node) and contains() with nodes instead of strings.
The problem with your first XPath: //table//tbody//tr[position()=1 and contains(.,input)]
You’re trying to select the first row of tables that have an <input> tag, but here’s where you went wrong:
contains()expects two strings as arguments. When you writecontains(., input), theinputpart isn’t a string—it’s a relative XPath query that looks for<input>nodes inside the current<tr>node.- XPath automatically converts node sets to strings: if the
<tr>has an<input>, it uses that input’s text content; if there’s no<input>, it converts the empty node set to an empty string (''). - The kicker:
contains(any_string, '')always returnstrue—every string includes the empty substring! So for Table #2’s first row (which has no<input>),contains(., input)evaluates tocontains(tr_text, ''), which istrue. Combine that withposition()=1, and it gets selected too.
Why your second XPath works: //table//tbody//tr[position()=1]//input
This expression does two things correctly:
- It first finds the first
<tr>in every table’s<tbody>. - Then it looks for
<input>nodes inside those rows. Since Table #2’s first row has no<input>, nothing gets returned from that table.
The fix you need
If you want to select only the first row of tables that actually contain an <input> tag, use this XPath instead:
//table//tbody//tr[position()=1 and .//input]
Here, .//input checks if the current <tr> has any <input> descendants (it returns true if the node set is non-empty, false otherwise)—no contains() needed here, since you’re checking for the existence of a node, not a substring in text.
内容的提问来源于stack exchange,提问作者ephemeris

