recomendación de Gordon utilizar una función de PHP desde XPath resultará más flexible en caso que quiera usar eso. Sin embargo, contrariamente a su respuesta, la función de cadena translate
es disponible en XPath 1.0, lo que significa que puede usarla; su problema es cómo.
En primer lugar, está el error evidente que Charles señaló en su comentario a la pregunta. Luego está la lógica de cómo estás tratando de hacer coincidir los valores de texto.
En forma de la palabra, que está pidiendo ahora, "¿El texto contiene la forma minúscula de la palabra clave?" Esto no es realmente lo que quiere estar preguntando. En su lugar, pregunte, "qué el texto en minúsculas contienen la palabra clave en minúsculas?" Traslación (perdón por el juego de palabras) que de nuevo en XPath-tierra sería:
(Nota: alfabetos truncados para facilitar la lectura)
//line[contains(translate(text(),'ABC...Z','abc...z'),'chicago')]
Lo anterior minora el texto contenido en el nodo line
y luego verifica que (el texto en minúscula) contiene la palabra clave chicago
.
Y ahora para el fragmento de código obligatorio (pero en realidad, lo anterior idea es lo que realmente necesita para llevar a casa):
$xml = simplexml_load_file($data);
$search = strtolower($keyword);
$nodes = $xml->xpath("//line[contains(translate(text(), 'ABCDEFGHJIKLMNOPQRSTUVWXYZ', 'abcdefghjiklmnopqrstuvwxyz'), '$search')]");
echo 'Got ' . count($nodes) . ' matches!' . PHP_EOL;
foreach ($nodes as $node){
echo $node . PHP_EOL;
}
Editar después dijon's comment
Dentro del foreach, puede acceder al número de línea, número de capítulo y nombre del libro, como ser bajo.
Número de línea - esto es solo un atributo en el elemento <line>
que hace que acceder a él sea muy fácil. Hay dos formas, con SimpleXML, de acceder a ella: $node['number']
o $node->attributes()->number
(prefiero la primera).
Número de capítulo - para llegar a esto, como bien dice, tenemos que atravesar el árbol. Si utilizáramos las clases DOM, tendríamos una útil propiedad $node->parentNode
que nos llevaría directamente al <chapter>
(ya que es el antecesor inmediato de nuestro <line>
). SimpleXML no tiene una propiedad tan práctica, pero podemos usar una consulta relativa de XPath para obtenerla. El parent axis nos permite atravesar el árbol.
Dado que xpath()
devuelve una matriz, podemos hacer trampa y usar current()
para acceder al primer elemento (y único) de la matriz devuelta. Entonces solo se trata de acceder al atributo number
como se indica arriba.
// In the near future we can use: current(...)['number'] but not yet
$chapter = current($node->xpath('./parent::chapter'))->attributes()->number;
nombre de libro - el proceso para esto es el mismo que el de acceso al número de capítulo. Una consulta XPath relativa del <line>
podría hacer uso del ancestor axis como ./ancestor::book
(o ./parent:chapter/parent::book
). Con suerte, puede averiguar cómo acceder a su atributo name
.
Parece tener una cotización individual extra frente a 'translate' en su último ejemplo de código. – Charles