WatiN:在查找文本时,如何获取其包含元素的引用?

时间:2011-01-19 14:05:05

标签: c# watin

给出以下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>元素中,因此我将始终将其取回而不是直接父级。


有没有办法直接在元素下面获取文本(而不是它所包含的元素中的文本)?

还有另一种方法吗?

非常感谢。

3 个答案:

答案 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;
}