Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Galera, estou realizando uma busca no xml com o Xpath, o problema, é que tem que escrever da exata forma que está no xml para retornar alguma coisa... Até maiusculo e minúscula faz difença... como eu faço para a busca retornar mais resultados... Por exemplo... pesquiso pela Cidade de "São Paulo" usando somente "São"?
Quem consegue ajudar ai??
Código atual:
$sxe = simplexml_load_file("http://www.hotelurbano.com.br/xml?layout=default&cmp=696&utm_campaign=parceria-xml&utm_source=mundialturismo_mundialturismo&utm_medium=parceria-xml&utm_content=");
foreach($sxe->xpath('//oferta') as $item) {
$row = simplexml_load_string($item->asXML());
$busca = addslashes($_POST['pesquisa']);
$v = $row->xpath("//cidade[. ='$busca']");hmmm... Brigado ai... agora o problema é adaptar isso ao xpath... Alguma sugestão?
Um teste rápido:
$similaridade;
similar_text( 'São Paulo', 'Sao Paulo', $similaridade );
echo $similaridade;
me retornou o seguinte resultado:
84.210526315789
Presumo que seja uma similaridade de 84%.
Entretanto, pode não ser a melhor alternativa para o seu caso (para o meu é... 'mardito' TCC XD).
--------------------------------------
@Edit:
Com mais alguns testes:
$similaridade;
similar_text( 'Gabriel Bertolini Heming', 'Gabriel Heming', $similaridade );
echo $similaridade.'<br/>';
similar_text( 'Gabriel Heming', 'Gabriel', $similaridade );
echo $similaridade.'<br/>';
similar_text( 'Gabriel', 'Gabriel Heming', $similaridade );
echo $similaridade.'<br/>';
similar_text( 'Gabriel Bertolini', 'Gabriel Heming', $similaridade );
echo $similaridade.'<br/>';
similar_text( 'gnimeH leirbaG', 'Gabriel Heming', $similaridade );
echo $similaridade.'<br/>';
similar_text( 'Gabriel Heming', 'gnimeH leirbaG', $similaridade );
echo $similaridade.'<br/>';
Resultados:
>
73.684210526316
66.666666666667
66.666666666667
70.967741935484
7.1428571428571
7.1428571428571
Bem interessante a relevância de cada palavra com sua similaridade. Tentei buscar o autor do algoritmo, que apenas está referido como 'Oliver [1993]' e não consigo encontrar nada. Há outros sites que também buscam alguma referência, e a mais antiga está para http://forums.codeguru.com/showthread.php?t=41089
Veja se isso ajuda.
Não é fácil, mas também não é difícil de implementar. É que agora estou sem tempo pra montar a query completa :yay:
Tá.... segui esse link, bruno, só que agora todos os resultados estão sendo retornados.
$v = $row->xpath("//cidade[translate('$busca', 'abcedfeghijklmnopqrstuvwxyz', 'ABCEDFGHIJKLMNOPQRSTUVWXYZ')]");
Alguma solução?? '-'
Eu deveria me sentir envergonhado por sugerir uma coisa que eu não conseguir implementar.
Mas também, esses truques avançados com XPath são difíceis pra caramba. Credo! :o
Vamos tentar de uma forma mais simples, usando as próprias funções do PHP. O único inconveniente é que requer a DOM que mais complicadinha do que a SimpleXML.
Isso é possível por registrar um namespace XPath do PHP ao objeto DOM e, então, registrar as funções que serão usadas ou liberar todas.
<?php
$string = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book>
<title>PHP Basics</title>
<author>Jim Smith</author>
<author>Jane Smith</author>
</book>
<book>
<title>PHP Secrets</title>
<author>Jenny Smythe</author>
</book>
<book>
<title>XML basics</title>
<author>Joe Black</author>
</book>
</books>
XML;
// Aquilo que será buscado
$search = 'xml';
$dom = new DOMDocument;
$dom -> loadXML( $string );
$xpath = new DOMXPath( $dom );
// Registrando o NameSpace (obrigatório)
$xpath -> registerNamespace("php", "http://php.net/xpath");
/**
* Registrando as funções PHP.
* Se este argumento for vazio, registra TODAS
* Se quiser limitar informe uma string para UMA função ou um array com
* todas as permitidas
*/
$xpath -> registerPHPFunctions();
/**
* Invocando stripos() dentro do XPath a ser avaliado
*
* Cuidado com as aspas aqui. Se inverter as duplas com as simples não vai funcionar
*/
$nodes = $xpath -> query( "//book[php:functionString('stripos', title, '$search')]" );
// Mostrando...
printf(
'Encontrados %d livros contendo o termo <strong>%s</strong>:<br /><br />',
$nodes -> length, $search
);
foreach( $nodes as $node ) {
printf( '- %s por %s<br />',
$node -> getElementsByTagName( 'title' ) -> item( 0 ) -> nodeValue,
$node -> getElementsByTagName( 'author' ) -> item( 0 ) -> nodeValue
);
}
A saída é:
Encontrados 1 livros contendo o termo xml:
Porém com o negrito adicionado ^_^
Fiquei muito tempo nesse tópico demorando pra responder só por causa daquele "Cuidado" que adicionei num comentário. <_<
Existe várias formas. Uma delas é remover caracteres e transformar em lowercase.
Há também uma que encontrei hoje, estava olhando algumas funções e encontrei essa:
similar_text
Ela calcula a similaridade entre duas strings. Talvez possa te ajudar. Não tive tempo para testar.
Mas, pelo que li na documentação, ela retorna, em porcentagem, a similaridade das duas strings.
Com uma pequena suposição, eu retornaria as palavras com um certo grau de similaridade.
'São Paulo' é diferente de 'Sao Paulo'. Mas são similares, a unica coisa, seria verificar qual o grau.