O documento XML:
<Home>
<Addr>
<Street>ABC</Street>
<Number>5</Number>
<Comment>BLAH BLAH BLAH <br/><br/>ABC</Comment>
</Addr>
</Home>
A expressão XPath:
//*[contains(text(), 'ABC')]
//*corresponde a qualquer elemento descendente do nó raiz . Ou seja, qualquer elemento, exceto o nó raiz.
[...]é um predicado , filtra o conjunto de nós. Retorna nós para os quais ...é true:
Um predicado filtra um conjunto de nós [...] para produzir um novo conjunto de nós. Para cada nó no conjunto de nós a ser filtrado, o PredicateExpr é avaliado [...]; se PredicateExpr for avaliado como verdadeiro para esse nó, o nó será incluído no novo conjunto de nós; caso contrário, não está incluído.
contains('haystack', 'needle')retorna truese haystack contém needle :
Função: boolean contém (string, string)
A função contém retornará verdadeiro se a primeira sequência de argumentos contiver a segunda sequência de argumentos e, caso contrário, retornará falso.
Mas contains()usa uma string como seu primeiro parâmetro. E são nós passados. Para lidar com isso, todos os nós ou conjuntos de nós transmitidos como o primeiro parâmetro são convertidos em uma cadeia de caracteres pela string()função:
Um argumento é convertido no tipo string como se chamando a função string.
string()retornos string-valueda função do primeiro nó :
Um conjunto de nós é convertido em uma cadeia de caracteres retornando o valor da cadeia de nós no conjunto de nós que é o primeiro na ordem do documento. Se o conjunto de nós estiver vazio, uma sequência vazia será retornada.
string-valuede um nó do elemento :
O valor da sequência de um nó do elemento é a concatenação dos valores da sequência de todos os descendentes do nó de texto do nó do elemento na ordem do documento.
string-valuede um nó de texto :
O valor da sequência de um nó de texto são os dados dos caracteres.
Portanto, basicamente, string-valuetodo o texto está contido em um nó (concatenação de todos os nós de texto descendentes).
text() é um teste de nó que corresponde a qualquer nó de texto:
O texto de teste do nó () é verdadeiro para qualquer nó de texto. Por exemplo, child :: text () selecionará os filhos do nó de texto do nó de contexto.
Dito isto, //*[contains(text(), 'ABC')]corresponde a qualquer elemento (exceto o nó raiz), cujo primeiro nó de texto contém ABC. Desde text()retorna um conjunto de nós que contém todos os nós de texto filho do nó de contexto (em relação aos quais uma expressão é avaliada). Mas contains()leva apenas o primeiro. Portanto, para o documento acima, o caminho corresponde ao Streetelemento.
A expressão a seguir //*[text()[contains(., 'ABC')]]corresponde a qualquer elemento (exceto o nó raiz), que possui pelo menos um nó de texto filho, que contém ABC. .representa o nó de contexto. Nesse caso, é um nó de texto filho de qualquer elemento, exceto o nó raiz. Portanto, para o documento acima, o caminho corresponde Streetaos Commentelementos e.
Agora, //*[contains(., 'ABC')]corresponde a qualquer elemento (exceto o nó raiz) que contém ABC(na concatenação dos nós de texto descendentes). Para o documento acima, ele corresponde aos elementos the Home, the Addr, the Streete Comment. Como tal, //*[contains(., 'BLAH ABC')]coincide com os Home, os Addr, e os Commentelementos.
//*[contains(text(),'ABC')]retorna apenas o<Street>elemento. Não retorna nenhum ancestral de<Street>ou<Comment>.