Quero selecionar apenas uma classe própria chamada .date
Por algum motivo, não consigo fazer isso funcionar. Se alguém souber o que há de errado com meu código, ficaria muito grato.
@$doc = new DOMDocument();
@$doc->loadHTML($html);
$xml = simplexml_import_dom($doc); // just to make xpath more simple
$images = $xml->xpath('//[@class="date"]');
foreach ($images as $img)
{
echo $img." ";
}
contains(@class, 'date')
Respostas:
Quero escrever a resposta canônica a esta pergunta porque a resposta acima tem um problema.
Nosso problema
O seletor CSS :
irá selecionar qualquer elemento que tenha a classe foo .
Como você faz isso no XPath?
Embora XPath seja mais poderoso que CSS, XPath não tem um equivalente nativo de um seletor de classe CSS . No entanto, existe uma solução.
A maneira certa de fazer isso
O seletor equivalente no XPath é:
A função normalize-space remove os espaços em branco à esquerda e à direita (e também substitui as sequências de caracteres de espaço em branco por um único espaço).
(Em um sentido mais geral), isso também é equivalente ao seletor CSS:
que corresponderá a qualquer elemento cujo valor de atributo de classe seja uma lista de valores separados por espaços em branco, um dos quais é exatamente igual a foo .
Algumas maneiras óbvias, mas erradas de fazer isso
O seletor XPath:
não funciona! porque não vai corresponder a um elemento que tem mais de uma classe, por exemplo
Também não corresponderá se houver algum espaço em branco extra ao redor do nome da classe:
O seletor XPath 'aprimorado'
também não funciona! porque corresponde erroneamente a elementos com a classe foobar , por exemplo
O crédito vai para este sujeito, que foi a primeira solução publicada para esse problema que encontrei na web: http://dubinko.info/blog/2007/10/01/simple-parsing-of-space-seprated-attributes- in-xpathxslt /
fonte
<div class="foo\tbar">
? Quero dizer, nomes de classes separados por uma guia.//*[contains(concat(" ", normalize-space(@class), " "), " foo ")]
?//[@class="date"]
não é um xpath válido.Experimente
//*[@class="date"]
, ou se você souber que é uma imagem,//img[@class="date"]
fonte
XPath 3.1 introduz uma função contém-token e, portanto, finalmente resolve isso 'oficialmente'. Ele é projetado para oferecer suporte a aulas .
Exemplo:
//*[contains-token(@class, "foo")]
Esta função garante que o espaço em branco (não apenas
(U + 0020)) seja tratado corretamente, funciona no caso de repetição do nome da classe e geralmente cobre os casos extremos.
Nota: A partir de hoje (2016-12-13), XPath 3.1 tem o status de Recomendação Candidata .
fonte
No XPath 2.0, você pode:
//*[count(index-of(tokenize(@class, '\s+' ), 'foo')) = 1]
conforme afirmado por Christian Weiske em: https://cweiske.de/tagebuch/XPath%3A%20Select%20element%20by%20class.htm
fonte
HTML permite nomes de elementos e atributos que não diferenciam maiúsculas de minúsculas e, em seguida, class é uma lista de nomes de classes separados por espaço. Aqui vamos nós para uma
img
tag e oclass
nomedate
:Veja também: Seletor CSS para conversão XPath
fonte
CUIDADO COM OS SINAIS DE MENOS NO MODELO !!! Se você estiver consultando "my-ownclass" no DOM:
fonte