2011-01-19 5 views
6

Dada la siguiente página HTML:WatiN: Al encontrar texto, ¿cómo obtengo una referencia a su elemento contenedor?

<html> 
<head> 
    <title>WatiN Test</title> 
</head> 
<body> 
<div> 
    <p>Hello World!</p> 
</div> 
</body> 
</html> 

Me gustaría ser capaz de buscar un texto (digamos "World"), y obtener una referencia a su elemento padre (en este caso el elemento <p>).


Si intento esto:

var element = ie.Element(Find.ByText(t => t.Contains("World"))) 

o esto:

var element = ie.Element(e => e.Text != null && e.Text.Contains("World")); 

le regreso el elemento <html>. Esto es consistente con la documentación WatiN para Element.Text que dice: "Obtiene el texto interno de este elemento (y el texto interno de todos los elementos contenidos en este elemento)".

Dado que todo el texto dentro de la página está dentro del elemento <html>, siempre recuperaré esto en lugar del padre inmediato.


¿Hay alguna manera de obtener solo el texto inmediatamente debajo de un elemento (no el texto dentro de los elementos que contiene)?

¿Hay alguna otra forma de hacerlo?

Muchas gracias.

Respuesta

2

código de fuelle se encuentra en el interior del primer elemento <body/> con el texto que contiene "Mundial". Los elementos que se clasifican como contenedores de elementos y tienen elementos secundarios se omitirán.

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; 
}); 

Nota: Usted puede preguntarse por qué escribí ie.ElementOfType<Body>(Find.First()).Element en lugar de sólo ie.Element. Esto debería funcionar, pero no es así. Creo que es un error. Escribí una publicación sobre ella en la lista de correo de WatiN y actualizaré esta respuesta cuando reciba la respuesta.

+0

solución de Niza, gracias! Realmente necesitaría que funcione si el HTML se modificó para ser '

Hola ¡Mundo!

'pero no lo dije en la pregunta, por lo que esta respuesta es correcta. Es justo que lo marque como la respuesta aceptada por el momento. :) –

+0

Sí, lo pensé más tarde, pero creo que esta respuesta es un buen comienzo para algo más grande;) – prostynick

1

He encontrado algo que funciona, pero es un poco raro y muy ineficiente.

Esto esencialmente funciona sobre la base de que el elemento más profundo que contiene tendrá el más corto InnerHtml. Es decir, todos los demás elementos que contienen el padre inmediato también incluirán su HTML y, por lo tanto, ¡serán más largos!

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; 
} 
3

Usted podría utilizar Find.BySelector

var element = ie.Element(Find.BySelector("p:contains('World')")); 
Cuestiones relacionadas