XPath: diferença entre ponto e texto ()
a minha pergunta é sobre os detalhes do uso do dot e text()
em XPath
. Por exemplo, a seguir às linhas find_element
devolve o mesmo elemento:
driver.get('http://stackoverflow.com/')
driver.find_element_by_xpath('//a[text()="Ask Question"]')
driver.find_element_by_xpath('//a[.="Ask Question"]')
Qual é a diferença? Quais são os benefícios e desvantagens do uso de .
e text()
?
2 answers
Existe uma diferença entre .
e text()
, mas esta diferença pode não aparecer por causa do seu documento de entrada.
Se o seu documento de entrada se assemelhasse (o documento mais simples que se pode imaginar, dadas as suas expressões do XPath)
Exemplo 1
<html>
<a>Ask Question</a>
</html>
Então //a[text()="Ask Question"]
e //a[.="Ask Question"]
realmente retornam exatamente o mesmo resultado. Mas considere um documento de entrada diferente que se pareça com
Exemplo 2
<html>
<a>Ask Question<other/>
</a>
</html>
Onde o elemento a
também tem um elemento criança other
que se segue imediatamente após "perguntar". Dado este segundo documento de entrada, {[6] } ainda devolve o elemento a
, enquanto //a[.="Ask Question"]
não devolve nada!
Isto é porque o significado dos dois predicados (tudo entre [
e ]
) é diferente. [text()="Ask Question"]
realmente significa: return true se qualquer um dos nós de texto de um elemento contém exatamente o texto "pergunte". Por outro lado, [.="Ask Question"]
significa: retornar verdadeiro se o texto value of an element is identical to "Ask Question".
No modelo XPath, o texto dentro dos elementos XML pode ser dividido num número de nós de texto se outros elementos interferirem com o texto, como em Exemplo 2} acima. Lá, o elemento other
está entre "perguntar" e um personagem newline que também conta como conteúdo de texto.
Para dar um exemplo ainda mais claro, considere como um documento de entrada:
Exemplo 3
<a>Ask Question<other/>more text</a>
Aqui, o elemento a
realmente contém dois nós de texto, "pergunta" e "mais texto", Uma vez que ambos são filhos diretos de a
. Você pode testar isso executando //a/text()
neste documento, que irá retornar (os resultados individuais separados por ----
):
Ask Question
-----------------------
more text
Assim, em tal cenário, text()
retorna um conjunto de nós individuais, enquanto .
em um predicado avalia a concatenação de cadeia de todos os nós de texto. Mais uma vez, você pode testar esta alegação com o caminho expressão //a[.='Ask Questionmore text']
que irá devolver com sucesso o elemento a
.
Finalmente, tenha em mente que algumas funções XPath só podem ter uma única cadeia de caracteres como entrada. Como LarsH tem apontado nos comentários, se tal função XPath (por exemplo contains()
) é dada uma sequência de nós, ele só vai processar o primeiro nó e silenciosamente ignorar o resto.
Há uma grande diferença entre dot (".")
e text()
:-
O
dot (".")
emXPath
é chamado de "expressão do item de contexto" porque se refere ao item de contexto. Isto pode ser compatível com um nó (como umelement
,attribute
, outext node
) ou um valor Atómico (como umstring
,number
, ouboolean
). Enquantotext()
se refere a corresponder apenaselement text
que está na formastring
.A notação
dot (".")
é o nó actual no DOM. Isto vai ser um objecto de digite o nó enquanto usa oXPath
texto da função () para obter o texto de um elemento só consegue o texto até o primeiro elemento interno. Se o texto que procura For depois do elemento interno , deve usar o nó actual para procurar o texto e não a funçãoXPath
text ().
Por exemplo : -
<a href="something.html">
<img src="filename.gif">
link
</a>
Aqui se quiser encontrar o elemento anchor a
usando o texto link, terá de usar dot (".")
. Porque se utilizar //a[contains(.,'link')]
encontra o elemento anchor a
, mas se usar //a[contains(text(),'link')]
a função text()
parece não a encontrar.