Quantcast
Channel: ...Microplagio... » SimpleXMLElement
Viewing all articles
Browse latest Browse all 4

Cómo hacer una búsqueda en un archivo XML con PHP

$
0
0

A veces leer, escribir o modificar archivos o cadenas XML no es suficiente, hay que hacer búsquedas dentro de los nodos y atributos. Hace un par de meses me vi en dicha necesidad: tenía un archivo XML con los datos de alumnos que deben mensualidades del colegio. Todos tenían un nombre de usuario asignado y un password. El script consistía en hacer una consulta enviando el nombre y password y después de buscar al alumno en el archivo, había que imprimir los meses o recibos que debía.

Este tipo de problemas se resuelven con XPath. Este lenguaje sirve para navegar por el documento XML como si fuera un árbol tomando en cuenta los elementos y atributos. En w3schools  hay un tutorial de XPath en inglés bastante sencillo. Su sintaxis es fácil de entender, mucho más que las expresiones regulares.

Si ya tienen una idea de qué es y cómo funciona XPath, les muestro a continuación cómo se efectúa una búsqueda sencilla para el problema anterior.

Primero, el XML estaba conformado de la siguiente manera (estoy omitiendo algunos atributos para mayor sencillez):

1
2
3
4
5
6
7
<?xml version="1.0">
    <recibos>
        <r Nc="9069" Alu="Perez Lopez Juan" FE="05-07-2012" Rc="JUN 2012" GGS="3C Sec" BB1="$4,690.00" Nrec="21956" Us="PELO9069" Pw="0901000"/>
        <r Nc="9084" Alu="Sanchez Garcia Ernesto" FE="05-07-2012" Rc="MAY 2012" GGS="3A Sec" BB1="$4,690.00" Nrec="21956" Us="SAGA9084" Pw="7768767"/>
        <r Nc="9034" Alu="Ibarra Quintero Jesus" FE="05-07-2012" Rc="JUN 2012" GGS="3A Sec" BB1="$4,690.00" Nrec="21956" Us="IBQU9034" Pw="3797998"/>
        <r Nc="9055" Alu="Miranda Reyes Agustin" FE="05-07-2012" Rc="ABR 2012" GGS="3B Sec" BB1="$4,690.00" Nrec="21956" Us="MIRE9055" Pw="3234768"/>
    </recibos>

Tengo que aclarar que por motivos muy particulares la contraseña estaba visible y sin encriptación. Esto es porque no se necesitaba de ninguna gestión de seguridad. Cada padre de familia podía acceder para ver los recibos pendientes de pago nada más. En caso de que alguien robara la contraseña de otro alumno, lo peor que podía pasar era que la otra persona pagara por nosotros lo cual sería muy bueno jajaja.

Como en este caso lo que necesito es validar los valores de los atributos “Us” y “Pw”, necesito usar la sintaxis:

//elemento[@atributo='valor']

En otras palabras, necesito buscar donde el usuario sea igual a algo y contraseña sea igual a algo. Así que ademas de usar la sintaxis mencionada tengo que usar un operador AND. De modo que el XPath real sería algo asi:

/recibos/r[(@Us='$user') and (@Pw='$psw')]

La expresión /recibos/r es para hace referencia a que estos en el elemento r que a su vez está dentro del elemento raíz recibos.

Ahora, ¿cómo usar XPath en PHP? Hace tiempo escribi vagamente sobre el uso básico de la clase SimpleXMLElement de PHP5. Pues esta clase también tiene una implementación de XPath. Tan solo hay que instanciarla con los atributos necesarios y luego llamar a la función SimpleXMLElement::xpath($path) con la sintaxis que necesitemos y nos regresará un objeto SimpleXMLElement para que podamos trabajarlo.

Veamos. Después de hacer un formulario para pedir nombre y contraseña, el script que recibe los datos del POST es algo así:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$user = (!empty($_POST['user']))? $_POST['user'] : null;
$psw = (!empty($_POST['psw']))? $_POST['psw'] : null;
if(is_null($u) || is_null($p)){
    show_error('No puede dejar ningun campo vacio');
}
// Llamamos a la funcion que buscara los recibos
find_receipts($user, $psw);

function find_receipts($u, $p){
    try {
        // Se instancia la clase con el archivo XML
        $xml = new SimpleXMLElement('http://example.com/recibos.xml', null, true);
        // Se ejecuta la busqueda xpath con la sintaxis apropiada
        $results = $xml-&gt;xpath("/recibos/r[(@Us='$u') and (@Pw='$p')]");
        if(empty($results)){
            // Si no hay resultados nos salimos
            return null;
        }
        // Mandamos llamar una funcion para mostrar los resultados
        show_receipts($results);
    }
    catch(Exception $e) { return; }
}

El objeto regresado contiene todos los elementos que coinciden en la busqueda. En mi caso, los alumnos pueden estar repetidos porque cada elemento es un recibo y cada alumno puede deber uno o más recibos. Así que en ocasiones el script me puede regresar un objeto hasta con 10 elementos o recibos que puedo mostrar con una lista de HTML con los enlaces correspondientes donde puedo mostrar los pormenores del recibo como el monto a pagar, la cuenta bancaria, el numero de recibo, etc.

Aunque mi script no tiene la menor importancia, lo describí para ser más claro al explicar la utilidad de XPath en este problema particular.

Puedes documentarte más sobre la sintaxis y los operadores que puedes usar. Hay mucho de donde leer, lo que casi no hay son ejemplos de cómo implementarlo con PHP. Y aquí les puse una pequeña muestra usando SimpleXMLElement.


Viewing all articles
Browse latest Browse all 4

Latest Images

Trending Articles





Latest Images