如何从父元素获取文本并从子元素中排除文本(C# Selenium)
How to get text from parent element and exclude text from children (C# Selenium)
在 Selenium 中是否可以仅从父元素而不是其子元素获取文本?
示例:
假设我有以下代码:
<div class="linksSection>
<a href="https://www.google.com/" id="google">Google Link
<span class="helpText">This link will take you to Google's home page.</span>
</a>
...
</div>
在 C#(或任何语言)中,我将有:
string linktext = driver.FindElement(By.CssSelector(".linksSection > a#google")).Text;
Assert.AreEqual(linkText, "Google Link", "Google Link fails text test.");
但是,链接文本将有 "Google LinkThis link will take you to Google's home page."
如果不进行一系列字符串操作(例如获取所有子元素的文本并从父元素的结果文本中减去该文本),是否有办法只从父元素获取文本?
这是 selenium
中的 common problem,因为您不能直接访问文本节点 - 换句话说,您的 XPath 表达式和 CSS 选择器必须指向实际元素。
以下是针对您的问题的可能解决方案列表:
- 获取 parent 元素的文本,对于每个 child,获取文本并将其从 parent 的文本中删除。您剩下的是所需的文本 -
Google Link
在您的情况下。
- 如果你想得到
Google Link
只是为了做出断言,你可以检查 parent 的文本 s 是否带有 Google Link
。参见 StringAssert.StartsWith()
。
获取 parent 文本的 outerHTML
并提供给 HTML 解析器,例如 Html Agility Pack
。沿着这些线的东西:
string outerHTML = driver.FindElement(By.CssSelector(".linksSection > a#google")).GetAttribute("outerHTML");
HtmlDocument html = new HtmlDocument();
html.LoadHtml(outerHTML);
HtmlAgilityPack.HtmlNode a = html.DocumentNode.SelectNodes("//a[@id='google']");
HtmlNode text = strong.SelectSingleNode("following-sibling::text()");
Console.WriteLine(text.InnerText.Trim());
可以通过三种方式完成这项工作。
- 将子节点中不需要的文本替换为'''',逻辑与其他答案一样。
- 使用 js :
private static String OWN_TEXT_JS = "arr=[];content=document.querySelector(arguments[0]);for(i=0,len=content.childNodes.length;i<len;i++){if(content.childNodes[i].nodeType===3){arr.push(content.childNodes[i].nodeValue);}}str=arr.join(\"\"); return str;";
Object result = ((JavascriptExecutor) WebDriver).executeScript(OWN_TEXT_JS, path);
if (!(result instanceof String))
return null;
else
return (String) result;
- 使用html解析器,在java中是jsoup。
element= webDriver.findElement...
String result = Jsoup.parse(element.getAttribute("outerHTML")).selectFirst(element.getTagName()).ownText();
WebElement webElement = webDriver.findElement(By.xpath("/html"));
Jsoup.parse(webElement.getAttribute("outerHTML")).selectFirst(csspath).ownText();
在 Selenium 中是否可以仅从父元素而不是其子元素获取文本?
示例: 假设我有以下代码:
<div class="linksSection>
<a href="https://www.google.com/" id="google">Google Link
<span class="helpText">This link will take you to Google's home page.</span>
</a>
...
</div>
在 C#(或任何语言)中,我将有:
string linktext = driver.FindElement(By.CssSelector(".linksSection > a#google")).Text;
Assert.AreEqual(linkText, "Google Link", "Google Link fails text test.");
但是,链接文本将有 "Google LinkThis link will take you to Google's home page."
如果不进行一系列字符串操作(例如获取所有子元素的文本并从父元素的结果文本中减去该文本),是否有办法只从父元素获取文本?
这是 selenium
中的 common problem,因为您不能直接访问文本节点 - 换句话说,您的 XPath 表达式和 CSS 选择器必须指向实际元素。
以下是针对您的问题的可能解决方案列表:
- 获取 parent 元素的文本,对于每个 child,获取文本并将其从 parent 的文本中删除。您剩下的是所需的文本 -
Google Link
在您的情况下。 - 如果你想得到
Google Link
只是为了做出断言,你可以检查 parent 的文本 s 是否带有Google Link
。参见StringAssert.StartsWith()
。 获取 parent 文本的
outerHTML
并提供给 HTML 解析器,例如Html Agility Pack
。沿着这些线的东西:string outerHTML = driver.FindElement(By.CssSelector(".linksSection > a#google")).GetAttribute("outerHTML"); HtmlDocument html = new HtmlDocument(); html.LoadHtml(outerHTML); HtmlAgilityPack.HtmlNode a = html.DocumentNode.SelectNodes("//a[@id='google']"); HtmlNode text = strong.SelectSingleNode("following-sibling::text()"); Console.WriteLine(text.InnerText.Trim());
可以通过三种方式完成这项工作。
- 将子节点中不需要的文本替换为'''',逻辑与其他答案一样。
- 使用 js :
private static String OWN_TEXT_JS = "arr=[];content=document.querySelector(arguments[0]);for(i=0,len=content.childNodes.length;i<len;i++){if(content.childNodes[i].nodeType===3){arr.push(content.childNodes[i].nodeValue);}}str=arr.join(\"\"); return str;";
Object result = ((JavascriptExecutor) WebDriver).executeScript(OWN_TEXT_JS, path);
if (!(result instanceof String))
return null;
else
return (String) result;
- 使用html解析器,在java中是jsoup。
element= webDriver.findElement...
String result = Jsoup.parse(element.getAttribute("outerHTML")).selectFirst(element.getTagName()).ownText();
WebElement webElement = webDriver.findElement(By.xpath("/html"));
Jsoup.parse(webElement.getAttribute("outerHTML")).selectFirst(csspath).ownText();