给出以下HTML页面:
<html>
<head>
<title>WatiN Test</title>
</head>
<body>
<div>
<p>Hello World!</p>
</div>
</body>
</html>
我希望能够搜索一些文本(比如"World"
),并获得对其父元素的引用(在本例中为<p>
元素)。
如果我试试这个:
var element = ie.Element(Find.ByText(t => t.Contains("World")))
或者这个:
var element = ie.Element(e => e.Text != null && e.Text.Contains("World"));
我找回了<html>
元素。这与Element.Text
的WatiN文档一致,其中指出:“获取此元素的innertext(以及此元素中包含的所有元素的innertext)”。
由于页面中的所有文本都包含在<html>
元素中,因此我将始终将其取回而不是直接父级。
有没有办法直接在元素下面获取文本(而不是它所包含的元素中的文本)?
还有另一种方法吗?
非常感谢。
答案 0 :(得分:3)
您可以使用Find.BySelector
var element = ie.Element(Find.BySelector("p:contains('World')"));
答案 1 :(得分:2)
Bellow代码会在<body/>
内找到包含“World”的文本的第一个元素。分类为元素容器且具有子元素的元素将被省略。
var element = ie.ElementOfType<Body>(Find.First()).Element(e =>
{
if (e.Text != null && e.Text.Contains("World"))
{
var container = e as IElementContainer;
if (container == null || container.Elements.Count == 0)
return true;
}
return false;
});
注意:您可能想知道为什么我写ie.ElementOfType<Body>(Find.First()).Element
而不仅仅是ie.Element
。这应该有效,但事实并非如此。我认为这是一个错误。我在WatiN邮件列表上写了一篇关于它的帖子,当我收到答案时会更新这个答案。
答案 2 :(得分:1)
我想出了一些有用的东西,但它有点笨拙且非常低效。
这基本上是基于最深的包含元素将具有最短InnerHtml
。也就是说,包含直接父级的所有其他元素也将包含它的HTML,因此更长!
public static Element FindElementContaining(IElementsContainer ie, string text)
{
Element matchingElement = null;
foreach (Element element in ie.Elements)
{
if (element.Text == null) continue;
if (!element.Text.ToLower().Contains(text.ToLower())) continue;
// If the element found has more inner html than the one we've already matched, it can't be the immediate parent!
if (matchingElement != null && element.InnerHtml.Length > matchingElement.InnerHtml.Length) continue;
matchingElement = element;
}
return matchingElement;
}