XPath para selecionar Elemento pelo valor do atributo

193

Eu tenho o seguinte XML.

<?xml version="1.0" encoding="UTF-8"?>
<Employees>
    <Employee id="3">
        <age>40</age>
        <name>Tom</name>
        <gender>Male</gender>
        <role>Manager</role>
    </Employee>
    <Employee id="4">
        <age>25</age>
        <name>Meghna</name>
        <gender>Female</gender>
        <role>Manager</role>
    </Employee>
</Employees>

Eu quero selecionar o elemento Employee com id = "4".

Estou usando a expressão XPath abaixo, que não está retornando nada.

//Employee/[@id='4']/text()

Eu verifiquei em http://chris.photobooks.com/xml/default.htm e diz xpath inválido, não tenho certeza de onde está o problema.

Pankaj
fonte

Respostas:

274

Você precisa remover o /antes do [. Predicados (as partes [ ]) não devem ter barras imediatamente antes deles. Além disso, para selecionar o próprio elemento Employee, você deve deixar de fora /text()no final, caso contrário, basta selecionar os valores de texto em espaço em branco imediatamente abaixo do elemento Employee.

//Employee[@id='4']

Editar: como Jens aponta nos comentários, //pode ser muito lento porque procura no documento inteiro por nós correspondentes. Se a estrutura dos documentos com os quais você está trabalhando for consistente, é melhor usar um caminho completo, por exemplo:

/Employees/Employee[@id='4']
JLRishe
fonte
3
Observe que //seleciona e pesquisa em todos os nós do documento que podem ser lentos. Em vez disso, se a estrutura do documento for conhecida, use um caminho adequado, como sugerido na resposta de Gilles abaixo.
Jens
@ Jens Sim, isso é absolutamente verdade. Editei minha resposta para adicionar um adendo.
JLRishe
12

Tente fazer isso:

/Employees/Employee[@id=4]/*/text()
Gilles Quenot
fonte
xmllint carrega o arquivo xml inteiro na memória antes de procurar os IDs ?. Eu tenho um arquivo xml de 46 GB e estou procurando IDs nele #
Hani Goc 15/10/2015
arquivo xml de 46 GB - existe o problema.
Gurwinder Singh
12

A seguir, você pode selecionar "todos os nós com um atributo específico" como este:

//*[@id='4']
rogerdpack
fonte