我想选择所有包含文本的节点。
在此示例中,不应选择外部shouldBeIgnored
标记:
<shouldBeIgnored>
<span>
the outer Span should be selected
</span>
</shouldBeIgnored>
其他一些帖子提示如下://*/text()
。
但是,这在firefox中不起作用。
这是一个重现问题的小型UnitTest:
public class XpathTest {
final WebDriver webDriver = new FirefoxDriver();
@Test
public void shouldNotSelectIgnoredTag() {
this.webDriver.get("http://www.s2server.de/stackoverflow/11773593.html");
System.out.println(this.webDriver.getPageSource());
final List<WebElement> elements = this.webDriver.findElements(By.xpath("//*/text()"));
for (final WebElement webElement : elements) {
assertEquals("span", webElement.getTagName());
}
}
@After
public void tearDown() {
this.webDriver.quit();
}
}
答案 0 :(得分:6)
如果要选择包含文本的所有节点,则可以使用
//*[text()]
在xpath之上将查找包含文本的任何元素。请注意text()
函数,该函数用于确定当前节点是否包含文本。
在您的情况下,它会选择<span>
标记,因为它包含文字。
答案 1 :(得分:1)
你可以调用一个javascript函数,它将返回文本节点:
function GetTextNodes(){
var lastNodes = new Array();
$("*").each(function(){
if($(this).children().length == 0)
lastNodes.push($(this));
});
return lastNodes;
}
Selenium WebDriver代码:
IJavaScriptExecutor jscript = driver as IJavaScriptExecutor;
List<IWebElement> listTextNodes = jscript.ExecuteScript("return GetTextNodes();");
仅供参考:有些事可能适合你。
答案 2 :(得分:1)
我认为没有理由不这样做 (通过java)
text = driver.findElement(By.xpath("//span")).getText()
如果在奇怪的情况下不起作用:
text = driver.findElement(By.xpath("//span")).getAttribute("innerHTML")
答案 3 :(得分:1)
最后我发现用xpath无法做到这一点(因为XPath text()
也选择了节点的innerText)。作为解决方法,我必须注入Java脚本,该脚本返回由XPath选择的具有一些文本的所有元素。
像这样:
public class XpathTest
{
//@formatter:off
final static String JS_SCRIPT_GET_TEXT = "function trim(str) { " +
" return str.replace(/^\s+|\s+$/g,''); " +
"} " +
" " +
"function extractText(element) { " +
" var text = ''; " +
" for ( var i = 0; i < element.childNodes.length; i++) { " +
" if (element.childNodes[i].nodeType === Node.TEXT_NODE) { " +
" nodeText = trim(element.childNodes[i].textContent); " +
" " +
" if (nodeText) { " +
" text += element.childNodes[i].textContent + ' '; " +
" } " +
" } " +
" } " +
" " +
" return trim(text); " +
"} " +
" " +
"function selectElementsHavingTextByXPath(expression) { " +
" " +
" result = document.evaluate(\".\" + expression, document.body, null, " +
" XPathResult.ANY_TYPE, null); " +
" " +
" var nodesWithText = new Array(); " +
" " +
" var node = result.iterateNext(); " +
" while (node) { " +
" if (extractText(node)) { " +
" nodesWithText.push(node) " +
" } " +
" " +
" node = result.iterateNext(); " +
" } " +
" " +
" return nodesWithText; " +
"} " +
"return selectElementsHavingTextByXPath(arguments[0]);";
//@formatter:on
final WebDriver webDriver = new FirefoxDriver();
@Test
public void shouldNotSelectIgnoredTag()
{
this.webDriver.get("http://www.s2server.de/stackoverflow/11773593.html");
final List<WebElement> elements = (List<WebElement>) ((JavascriptExecutor) this.webDriver).executeScript(JS_SCRIPT_GET_TEXT, "//*");
assertFalse(elements.isEmpty());
for (final WebElement webElement : elements)
{
assertEquals("span", webElement.getTagName());
}
}
@After
public void tearDown()
{
this.webDriver.quit();
}
}
我修改了示例testable的UnitTest。
答案 4 :(得分:1)
定位文本节点的一个问题是即使空字符串也被视为有效的文本节点(例如
)<tag1><tag2/></tag1>
没有文字节点,但
<tag1> <tag2/> </tag1>
有2个文本节点,一个有2个空格,另一个有4个空格
如果您只想要具有非空文本的文本节点,可以采用以下方法之一:
//text()[string-length(normalize-space(.))>0]
或获取他们的父元素
//*[text()[string-length(normalize-space(.))>0]]