问题
Given the following HTML page:
<html>
<head>
<title>WatiN Test</title>
</head>
<body>
<div>
<p>Hello World!</p>
</div>
</body>
</html>
I would like to be able to search for some text (lets say "World"
), and get a reference to its parent element (in this case the <p>
element).
If I try this:
var element = ie.Element(Find.ByText(t => t.Contains("World")))
or this:
var element = ie.Element(e => e.Text != null && e.Text.Contains("World"));
I get back the <html>
element. This is consistent with the WatiN documentation for Element.Text
which states: "Gets the innertext of this element (and the innertext of all the elements contained in this element)".
Since all text within the page is contained within the <html>
element, I'll always get this back instead of the immediate parent.
Is there a way to get just the text immediately beneath an element (not the text within the elements contained by it)?
Is there another way of doing this?
Many thanks.
回答1:
Bellow code will find first element inside the <body/>
with text containing "World". Elements which are classified as element containers and has child elements will be omitted.
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;
});
Note: You may wonder why I wrote ie.ElementOfType<Body>(Find.First()).Element
instead of just ie.Element
. This should work, but it doesn't. I think it's a bug. I wrote a post about it on WatiN mailing list and will update this answer when I receive the answer.
回答2:
You could use Find.BySelector
var element = ie.Element(Find.BySelector("p:contains('World')"));
回答3:
I've come up with something that works, but it's a bit hacky and very inefficient.
This essentially works on the basis that the deepest containing element will have the shortest InnerHtml
. That is, all other elements which contain the immediate parent will include it's HTML as well, and therefore be longer!
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;
}
来源:https://stackoverflow.com/questions/4736111/watin-when-finding-text-how-do-i-get-a-reference-to-its-containing-element