Qual é o XPath correto para escolher atributos que contêm "foo"?

176

Dado esse XML, o XPath retorna todos os elementos cujo propatributo contém Foo(os três primeiros nós):

<bla>
 <a prop="Foo1"/>
 <a prop="Foo2"/>
 <a prop="3Foo"/>
 <a prop="Bar"/>
</bla>
ripper234
fonte
1
Por que todo mundo está olhando para o atributo "prop"? Perdi alguma coisa? Diz apenas obter os três primeiros nós.
6
Todo mundo está olhando para o atributo prop, porque foi isso que foi perguntado. Obtenha todos os nós em que prop contém "Foo". Adicionar <a prop="Foo5" /> e você vai ver por que ele não é apenas "os primeiros três nós" ..
erlando
A pergunta no corpo é mal formulada, independentemente do título. Você pode realmente estar em qualquer atributo de suporte ou deseja apenas os três primeiros nós?
3
Sim, consulte o título, por favor (e fique à vontade para editar).
Ripper234
Se você precisa de maiúsculas e minúsculas comparação see achado-an-elemento cujo atributo-contém-a-texto caso insensível
Michael Freidgeim

Respostas:

307
//a[contains(@prop,'Foo')]

Funciona se eu usar esse XML para obter resultados de volta.

<bla>
 <a prop="Foo1">a</a>
 <a prop="Foo2">b</a>
 <a prop="3Foo">c</a>
 <a prop="Bar">a</a>
</bla>

Edit: Outra coisa a observar é que, enquanto o XPath acima retornará a resposta correta para esse xml específico, se você quiser garantir que você obtenha apenas os elementos "a" no elemento "bla", você deve, como outros usuários mencionaram, usar

/bla/a[contains(@prop,'Foo')]

Isso pesquisará todos os elementos "a" em todo o documento xml, independentemente de estar aninhado em um elemento "blah"

//a[contains(@prop,'Foo')]  

Eu adicionei isso por uma questão de rigor e no espírito do stackoverflow. :)

evilhomer
fonte
3
xmlme.comagora redireciona para outro host e não parece hospedar a ferramenta ou algo parecido.
jpmc26
26

Este XPath fornecerá todos os nós que possuem atributos contendo 'Foo', independentemente do nome do nó ou do nome do atributo:

//attribute::*[contains(., 'Foo')]/..

Obviamente, se você estiver mais interessado no conteúdo do atributo, e não necessariamente no nó pai, basta soltar o botão / ..

//attribute::*[contains(., 'Foo')]
Alex Beynenson
fonte
2
Para todos os nós//@*[contains(., 'Foo')]
aliopi 17/03/17
16
descendant-or-self::*[contains(@prop,'Foo')]

Ou:

/bla/a[contains(@prop,'Foo')]

Ou:

/bla/a[position() <= 3]

Dissecado:

descendant-or-self::

The Axis - pesquise todos os nós abaixo e o próprio nó. Geralmente é melhor dizer isso do que //. Eu encontrei algumas implementações em que // significa qualquer lugar (descendente ou eu do nó raiz). O outro usa o eixo padrão.

* or /bla/a

A tag - uma correspondência curinga e / bla / a é um caminho absoluto.

[contains(@prop,'Foo')] or [position() <= 3]

A condição dentro de []. @prop é uma abreviação de attribute :: prop, pois attribute é outro eixo de pesquisa. Como alternativa, você pode selecionar os 3 primeiros usando a função position ().

1729
fonte
6

John C é o mais próximo, mas o XPath faz distinção entre maiúsculas e minúsculas; portanto, o XPath correto seria:

/bla/a[contains(@prop, 'Foo')]
Metro Smurf
fonte
4

Você já tentou algo como:

// a [contém (@prop, "Foo")]

Eu nunca usei a função contains antes, mas suspeito que ela funcione conforme anunciado ...

toddk
fonte
@toddk ... você segmentou um atributo inexistente: @foo. Você deseja segmentar @prop ;-)
Metro Smurf
4

Se você também precisar corresponder ao conteúdo do link, use text ():

//a[contains(@href,"/some_link")][text()="Click here"]

SomeDudeSomewhere
fonte
2

/ bla / a [contém (@prop, "foo")]

David Hill
fonte
1

Para o código acima ... // * [contains (@ prop, 'foo')]

digiguru
fonte
isto é para qualquer elemento com foo, mas o atributo deve ser "prop"
digiguru
1

tente isto:

// a [contém (@ prop, 'foo')]

que deve funcionar para qualquer tag "a" no documento

Dani Duran
fonte