Declaración XPath para encontrar al hermano precedente más cercano

c# html-agility-pack xpath

Pregunta

Estoy usando el HTMLAgilityPack en una aplicación C # WPF para recorrer algunas etiquetas de anclaje en una página HTML local y extraer el atributo href. Esto funciona muy bien, pero luego necesito encontrar el título en el que se encuentra el ancla dentro del documento HTML (que también es una etiqueta de ancla). Esto debería ser bastante fácil de hacer con XPath, pero parece que no puedo obtener una declaración que funcione para todos los escenarios.

Aquí hay una muestra de mi HTML (sobre el que no tengo control):

<html>
    <body>
        <table>
            <tr>
                <td><div><a href="#maintitle" class="title">maintitle</a></div></td>
            </tr>
            <tr>
                <td><div><a href="#subtitle1" class="subtitle">subtitle1</a></div></td>
            </tr>
            <tr>
                <td><div><a href="link1.pdf">link1</a></div></td>
            </tr>
            <tr>
                <td><div><a href="link2.pdf">link2</a></div></td>
            </tr>
            <tr>
                <td><div><a href="link3.pdf">link3</a></div></td>
            </tr>
            <tr>
                <td><div><a href="#subtitle2" class="subtitle">subtitle2</a></div></td>
            </tr>
            <tr>
                <td><div><a href="link4.pdf">link4</a></div></td>
            </tr>
            <tr>
                <td><div><a href="link5.pdf">link5</a></div></td>
            </tr>
        </table>
    </body>
</html>

Después de encontrar el enlace1, quiero encontrar el subtítulo1. Igualmente para link2 y link3. Pero para link4 y link5, quiero encontrar subtítulo2. Estoy usando esta declaración XPath (la primera sección está ahí solo para simular la selección de una etiqueta de anclaje, que he estado usando con un evaluador de XPath en línea https://www.freeformatter.com/xpath-tester.html ) :

//a[@href='link4.pdf']/ancestor::tr/preceding-sibling::tr//a[@class='subtitle']

Esto funciona para link1 to link3, pero para link4 y link5 devuelve tanto el subtítulo1 como el subtítulo2. Agregar [1] a preced preceding-sibling::t corrige para link4, pero lo rompe para link2, link3 y link5:

//a[@href='link4.pdf']/ancestor::tr/preceding-sibling::tr[1]//a[@class='subtitle']

También he intentado agregar last() a preceding-sibling::t , pero esto no permite que se encuentre nada en ninguno de los enlaces:

//a[@href='link4.pdf']/ancestor::tr/preceding-sibling::tr[last()]//a[@class='subtitle']

Estoy seguro de que hay una solución simple, pero de ninguna manera soy competente con XPath, así que estoy luchando. ¿Cómo obtengo mi declaración XPath original para devolver al hermano más cercano?

Respuesta aceptada

localizador para obtener subtítulos por texto de enlace ('link4')

(//a[text()='link5']/preceding::tr[.//a[@class='subtitle']])[last()]

lógica:

//a[text()='link4'] - obtiene el elemento mediante texto vinculado

//a[text()='link4']/preceding::tr - busca todos los padres tr

[.//a[@class='subtitle']] - obtén el primer padre que contiene la etiqueta a con la clase' subtitle '

(someLocator)[last()] : obtenga el último localizador de coincidencia de elementos, en nuestro caso, obtenga la última etiqueta principal que contiene la etiqueta a con el subtitle clase

otra opción - inicialmente buscar tr lugar de a elemento

(//tr[.//a[text()='link5']]/preceding-sibling::tr//a[contains(@class,'subtitle')])[last()]

Esperemos que ayude a cualquiera a obtener los localizadores lógicos de construcción ob


Respuesta popular

Trate de usar el xpath:

//a[@href='<your_input>']/preceding-sibling::tr[.//a[@class='subtitle']][1]

donde <your_input> podría ser link1.pdf to link5.pdf



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué