XPath: Como selecionar elementos com base em seu valor?

221

Eu sou novo no uso do XPath e isso pode ser uma pergunta básica. Por favor, tenha paciência comigo e me ajude a resolver o problema. Eu tenho um arquivo XML como este:

<RootNode>
  <FirstChild>
    <Element attribute1="abc" attribute2="xyz">Data</Element>
  <FirstChild>
</RootNode>

Posso validar a presença de uma <Element>tag com:

// Elemento [@ attribute1 = "abc" e @ attribute2 = "xyz"]

Agora também quero verificar o valor da tag quanto a string "Data". Para conseguir isso, disseram-me para usar:

// Elemento [@ attribute1 = "abc" e @ attribute2 = "xyz" e Data]

Quando uso a expressão posterior, obtenho o seguinte erro:

Mensagem de falha de asserção: nenhum nó correspondente //Element[@attribute1="abc" and @attribute2="xyz" and Data]

Por favor, forneça seu conselho se a expressão XPath que usei é válida. Caso contrário, qual será a expressão XPath válida?

vcosk
fonte

Respostas:

329

A condição abaixo:

//Element[@attribute1="abc" and @attribute2="xyz" and Data]

verifica a existência do elemento Data no Element e não no valor do elemento Data.

Em vez disso, você pode usar

//Element[@attribute1="abc" and @attribute2="xyz" and text()="Data"]
Usuário SO
fonte
25
//Element[@attribute1="abc" and @attribute2="xyz" and .="Data"]

A razão pela qual adiciono esta resposta é que quero explicar o relacionamento de .e text().

A primeira coisa é ao usar [], existem apenas dois tipos de dados:

  1. [number] para selecionar um nó do conjunto de nós
  2. [bool] filtrar um conjunto de nós do conjunto de nós

Nesse caso, o valor é avaliado como booleano por função boolean()e existe uma regra:

Os filtros são sempre avaliados em relação a um contexto.

Quando você precisa comparar text()ou .com uma sequência "Data", ela primeiro usa a string()função para transformá-las em tipo de sequência, e obtém um resultado booleano.

Existem duas regras importantes sobre string():

  1. A string()função converte um conjunto de nós em uma cadeia de caracteres retornando o valor da cadeia de caracteres do primeiro nó no conjunto de nós, o que, em alguns casos, pode gerar resultados inesperados.

    text()é o caminho relativo que retorna um conjunto de nós contém todo o nó de texto do nó atual (nó de contexto), como ["Data"]. Quando avaliado por string(["Data"]), ele retornará o primeiro nó do conjunto de nós, para que você obtenha "Dados" somente quando houver apenas um nó de texto no conjunto de nós.

  2. Se você deseja que a string()função concatene todo o texto filho, passe um único nó em vez de um conjunto de nós.

    Por exemplo, obtemos um conjunto de nós ['a', 'b'], você pode passar o nó pai para string(parent), isso retornará 'ab'e a causa string(.)no seu caso retornará uma string concatenada "Data".

Nos dois sentidos, o mesmo resultado será obtido apenas quando houver um nó de texto.

宏杰 李
fonte