| 1 | <?php | 
|---|
| 2 | /*================================================================================ | 
|---|
| 3 | Esta clase implementa funciones de utilidad para tratar ficheros XML | 
|---|
| 4 |  | 
|---|
| 5 | Parametros del constructor: | 
|---|
| 6 | fxml=Fichero XML que contiene los atributos de los nodos | 
|---|
| 7 | fileocade=Indica si el dato anterior es un fichero o una variable con el contenido del árbol: | 
|---|
| 8 | 0: Es una cadena | 
|---|
| 9 | 1: Es un fichero | 
|---|
| 10 |  | 
|---|
| 11 | Especificaciones: | 
|---|
| 12 | Se le llama información del nodo al nombre del nodo + sus atributos eliminando los marcadores | 
|---|
| 13 | de comienzo:"<" y fin:">" | 
|---|
| 14 | ================================================================================*/ | 
|---|
| 15 | class XmlPhp{ | 
|---|
| 16 | var $buffer; | 
|---|
| 17 | var $nptr; | 
|---|
| 18 |  | 
|---|
| 19 | function __construct($fxml, $fileocade){ // Constructor | 
|---|
| 20 | if ($fileocade==0){ | 
|---|
| 21 | $this->nptr=1; | 
|---|
| 22 | $this->buffer=trim($fxml); | 
|---|
| 23 | } | 
|---|
| 24 | else{ | 
|---|
| 25 | $tbuffer=filesize($fxml); // Calcula tamaño del fichero | 
|---|
| 26 | if ($tbuffer>0){ // EL fichero tiene contenido | 
|---|
| 27 | $fd=fopen($fxml, "r"); | 
|---|
| 28 | $this->buffer=fread ($fd,$tbuffer); | 
|---|
| 29 | fclose ($fd); | 
|---|
| 30 | $this->nptr=1; | 
|---|
| 31 | $this->buffer=trim($this->buffer); | 
|---|
| 32 | } | 
|---|
| 33 | } | 
|---|
| 34 | $this->buffer=preg_replace("/[\n\r\t]/"," ", $this->buffer ); | 
|---|
| 35 | } | 
|---|
| 36 | /* ------------------------------------------------------------------------------------------- | 
|---|
| 37 | Recupera la información del primer nodo (nodo raiz) del arbol.Devuelve false en caso de que | 
|---|
| 38 | no tenga hijos o bien no exista documento XML que analizar. | 
|---|
| 39 | ---------------------------------------------------------------------------------------------*/ | 
|---|
| 40 | function InfoNodoRaiz(){ | 
|---|
| 41 | if (!$this->NodoRaiz()) // No existe documento XML | 
|---|
| 42 | return(false); | 
|---|
| 43 | return($this->Infonodo()); | 
|---|
| 44 | } | 
|---|
| 45 | /* ------------------------------------------------------------------------------------------- | 
|---|
| 46 | Establece el puntero de nodos al primer nodo del árbol (nodo raiz). Devuelve  false en caso | 
|---|
| 47 | de que no exista documento XML que analizar. | 
|---|
| 48 | ---------------------------------------------------------------------------------------------*/ | 
|---|
| 49 | function NodoRaiz(){ | 
|---|
| 50 | if ($this->buffer==null) return(false); // No existe documento XML | 
|---|
| 51 | $this->nptr=0; | 
|---|
| 52 | while ($this->nptr<strlen($this->buffer)) | 
|---|
| 53 | if ('<'==substr($this->buffer,$this->nptr++,1)) return(true); | 
|---|
| 54 | return(false); | 
|---|
| 55 | } | 
|---|
| 56 | /* ------------------------------------------------------------------------------------------- | 
|---|
| 57 | Recupera la información del primer nodo hijo del nodo actual. Devuelve false en caso de que | 
|---|
| 58 | no tenga hijos o bien no exista documento XML que analizar. | 
|---|
| 59 | ---------------------------------------------------------------------------------------------*/ | 
|---|
| 60 | function InfoPrimerNodoHijo(){ | 
|---|
| 61 | if (!$this->PrimerNodoHijo()) // No tiene hijos o no existe documento XML | 
|---|
| 62 | return(false); | 
|---|
| 63 | return($this->Infonodo()); | 
|---|
| 64 | } | 
|---|
| 65 | /* ------------------------------------------------------------------------------------------- | 
|---|
| 66 | Establece el puntero de nodos al primer nodo hijo del nodo actual. Devuelve  false en caso | 
|---|
| 67 | de que no tenga hijos o bien no exista documento XML que analizar. | 
|---|
| 68 | ---------------------------------------------------------------------------------------------*/ | 
|---|
| 69 | function PrimerNodoHijo(){ | 
|---|
| 70 | if ($this->buffer==null) return(false); // No existe documento XML | 
|---|
| 71 | $gnptr=$this->nptr; | 
|---|
| 72 | while ($this->nptr<strlen($this->buffer)) | 
|---|
| 73 | if ('<'==substr($this->buffer,$this->nptr++,1)) break; | 
|---|
| 74 | $lon=$this->nptr; | 
|---|
| 75 | if ('/'==substr($this->buffer,$lon,1)){ // No tiene hijos | 
|---|
| 76 | $this->nptr=$gnptr; | 
|---|
| 77 | return(false); | 
|---|
| 78 | } | 
|---|
| 79 | return(true); | 
|---|
| 80 | } | 
|---|
| 81 | /* ------------------------------------------------------------------------------------------- | 
|---|
| 82 | Recupera la información del siguiente nodo hermano del actual. Devuelve false en caso de que | 
|---|
| 83 | el nodo actual sea el último de sus hermanos o bien no exista documento XML que analizar. | 
|---|
| 84 | ---------------------------------------------------------------------------------------------*/ | 
|---|
| 85 | function InfoSiguienteNodoHermano(){ | 
|---|
| 86 | if (!$this->SiguienteNodoHermano()) // No tiene hermanos o no existe documento XML | 
|---|
| 87 | return(false); | 
|---|
| 88 | return($this->Infonodo()); | 
|---|
| 89 | } | 
|---|
| 90 | /* ------------------------------------------------------------------------------------------- | 
|---|
| 91 | Establece el puntero de nodos al siguiente nodo hermano del nodo actual. Devuelve  false en | 
|---|
| 92 | caso de que el nodo actual sea el último de los hermanos o bien no exista documento XML que analizar. | 
|---|
| 93 | ---------------------------------------------------------------------------------------------*/ | 
|---|
| 94 | function SiguienteNodoHermano(){ | 
|---|
| 95 | if ($this->buffer==null) return(false); // No existe documento XML | 
|---|
| 96 | $gnptr=$this->nptr; | 
|---|
| 97 | $resul=$this->_siguiente_hermano(); | 
|---|
| 98 | if (!$resul){ | 
|---|
| 99 | $this->nptr=$gnptr; // Es el último hermano | 
|---|
| 100 | return(false); | 
|---|
| 101 | } | 
|---|
| 102 | return(true); | 
|---|
| 103 | } | 
|---|
| 104 | /* ------------------------------------------------------------------------------------------- | 
|---|
| 105 | Establece el puntero de nodos al siguiente nodo hermano del actual | 
|---|
| 106 | ---------------------------------------------------------------------------------------------*/ | 
|---|
| 107 | function _siguiente_hermano(){ | 
|---|
| 108 | $lon=$this->nptr; | 
|---|
| 109 | $sw=1; | 
|---|
| 110 | $nombrenodo=$this->NombreNodo(); | 
|---|
| 111 | while (1){ | 
|---|
| 112 | $lon = strpos($this->buffer,'<',++$lon); | 
|---|
| 113 | if (substr($this->buffer,++$lon,1)=='/') | 
|---|
| 114 | $sw--; | 
|---|
| 115 | else | 
|---|
| 116 | $sw++; | 
|---|
| 117 | if ($sw==0){ | 
|---|
| 118 | while ($lon<strlen($this->buffer)){ | 
|---|
| 119 | if (substr($this->buffer,$lon++,1)=='<'){ | 
|---|
| 120 | if (substr($this->buffer,$lon,1)=='/') | 
|---|
| 121 | return(false); // Es el último hermano | 
|---|
| 122 | else{ | 
|---|
| 123 | $this->nptr=$lon; | 
|---|
| 124 | return(true); | 
|---|
| 125 | } | 
|---|
| 126 | } | 
|---|
| 127 | } | 
|---|
| 128 | return(false); // Se trata del nodo raiz | 
|---|
| 129 | } | 
|---|
| 130 | } | 
|---|
| 131 | } | 
|---|
| 132 | /* ------------------------------------------------------------------------------------------- | 
|---|
| 133 | Recupera el número de hijos del nodo actual | 
|---|
| 134 | ---------------------------------------------------------------------------------------------*/ | 
|---|
| 135 | function NumerodeHijos(){ | 
|---|
| 136 | $gnptr=$this->nptr; | 
|---|
| 137 | $nh=0; | 
|---|
| 138 | if ($this->PrimerNodoHijo()){ | 
|---|
| 139 | $nh++; | 
|---|
| 140 | while ($this->SiguienteNodoHermano()) $nh++; | 
|---|
| 141 | } | 
|---|
| 142 | $this->nptr=$gnptr; | 
|---|
| 143 | return($nh); | 
|---|
| 144 | } | 
|---|
| 145 | /* ------------------------------------------------------------------------------------------- | 
|---|
| 146 | Devuelve true si el nodo es el último de sus hermanos | 
|---|
| 147 | ---------------------------------------------------------------------------------------------*/ | 
|---|
| 148 | function EsUltimoHermano(){ | 
|---|
| 149 | $gnptr=$this->nptr; | 
|---|
| 150 | if (!$this->SiguienteNodoHermano()){ | 
|---|
| 151 | $this->nptr=$gnptr; | 
|---|
| 152 | return(true); | 
|---|
| 153 | } | 
|---|
| 154 | $this->nptr=$gnptr; | 
|---|
| 155 | return(false); | 
|---|
| 156 | } | 
|---|
| 157 | /* ------------------------------------------------------------------------------------------- | 
|---|
| 158 | Devuelve los atributos del nodo. | 
|---|
| 159 | Parámetros: | 
|---|
| 160 | Si se aporta el puntero del nodo se devolverán los atributos del nodo apuntado | 
|---|
| 161 | pero si no se especifican argumentos se devuelven los atributos del nodo actual. | 
|---|
| 162 | ---------------------------------------------------------------------------------------------*/ | 
|---|
| 163 | function Atributos($ptrnodo=-1){ | 
|---|
| 164 | if ($ptrnodo!=-1) | 
|---|
| 165 | $this->_setnodo($ptrnodo); | 
|---|
| 166 | $atributosHTML=""; | 
|---|
| 167 | $info=$this->Infonodo(); | 
|---|
| 168 | $pos=strpos($info," "); | 
|---|
| 169 | if ($pos) // El nodo tiene atributos | 
|---|
| 170 | $atributosHTML=" ".substr($info,$pos); | 
|---|
| 171 | return($atributosHTML); | 
|---|
| 172 | } | 
|---|
| 173 | /* ------------------------------------------------------------------------------------------- | 
|---|
| 174 | Posiciona el puntero de nodos | 
|---|
| 175 | ---------------------------------------------------------------------------------------------*/ | 
|---|
| 176 | function _setnodo($ptrnodo){ | 
|---|
| 177 | $this->nptr=$ptrnodo; | 
|---|
| 178 | } | 
|---|
| 179 | /* ------------------------------------------------------------------------------------------- | 
|---|
| 180 | Devuelve el puntero del nodo actual | 
|---|
| 181 | ---------------------------------------------------------------------------------------------*/ | 
|---|
| 182 | function Nodo(){ | 
|---|
| 183 | return($this->nptr); | 
|---|
| 184 | } | 
|---|
| 185 | /* ------------------------------------------------------------------------------------------- | 
|---|
| 186 | Recupera el nombre del nodo | 
|---|
| 187 | ---------------------------------------------------------------------------------------------*/ | 
|---|
| 188 | function NombreNodo(){ | 
|---|
| 189 | $infonodo=$this->Infonodo(); | 
|---|
| 190 | $trozos=explode(" ",$infonodo); | 
|---|
| 191 | return ($trozos[0]); | 
|---|
| 192 | } | 
|---|
| 193 | /* ------------------------------------------------------------------------------------------- | 
|---|
| 194 | Recupera la información del nodo actual | 
|---|
| 195 | ---------------------------------------------------------------------------------------------*/ | 
|---|
| 196 | function Infonodo(){ | 
|---|
| 197 | if ($this->buffer==null) return(false); // No existe documento XML | 
|---|
| 198 | $lon=$this->nptr; | 
|---|
| 199 | while ($lon<strlen($this->buffer)) | 
|---|
| 200 | if ('>'==substr($this->buffer,++$lon,1)) break; | 
|---|
| 201 | $info=trim(substr($this->buffer,$this->nptr,$lon-$this->nptr)); | 
|---|
| 202 | $info=str_replace("[","<",$info); | 
|---|
| 203 | $info=str_replace("]",">",$info); | 
|---|
| 204 | return $info; | 
|---|
| 205 | } | 
|---|
| 206 | /* ------------------------------------------------------------------------------------------- | 
|---|
| 207 | Recorre el arbol de nodos del documento XML y para cada nodo genera un evento que se | 
|---|
| 208 | puede capturar a través de una funcion que tiene esta forma: | 
|---|
| 209 | fNodoXML(nivel,infonodo) donde: | 
|---|
| 210 | - nivel es el nivel de profundidad del nodo (en base 0) | 
|---|
| 211 | - infonodo es toda la información contenida en el nodo. | 
|---|
| 212 | ---------------------------------------------------------------------------------------------*/ | 
|---|
| 213 | function RecorreArboXML(){ | 
|---|
| 214 | if (!$this->NodoRaiz()) return; // No existe documento XML que analizar | 
|---|
| 215 | $this->_arbolXmlrecur(0); | 
|---|
| 216 | } | 
|---|
| 217 | // ------------------------------------------------------------------------------------- | 
|---|
| 218 | // Recorrido recursivo del arbol XML | 
|---|
| 219 | // ------------------------------------------------------------------------------------- | 
|---|
| 220 | function _arbolXmlrecur($nivel){ | 
|---|
| 221 | do{ | 
|---|
| 222 | $infonodo=$this->Infonodo(); | 
|---|
| 223 | fNodoXML($nivel,$infonodo); | 
|---|
| 224 | $gnptr=$this->nptr; | 
|---|
| 225 | if ($this->PrimerNodoHijo()) | 
|---|
| 226 | $this->_arbolXmlrecur($nivel+1); | 
|---|
| 227 | $this->nptr=$gnptr; | 
|---|
| 228 | }while($this->SiguienteNodoHermano()); | 
|---|
| 229 | } | 
|---|
| 230 | /*------------------------------------------------------------------------------------------------ | 
|---|
| 231 | Elimina un atributo de la información del nodo | 
|---|
| 232 | Parametros: | 
|---|
| 233 | - nombreatributo:El nombre del atributo | 
|---|
| 234 | - info: La información del Nodo | 
|---|
| 235 | ------------------------------------------------------------------------------------------------*/ | 
|---|
| 236 | function EliminaAtributo($nombreatributo,$info){ | 
|---|
| 237 | $nada=""; | 
|---|
| 238 | return($this->TomaAtributo($nombreatributo,$nada,$info,true)); | 
|---|
| 239 | } | 
|---|
| 240 | /*------------------------------------------------------------------------------------------------ | 
|---|
| 241 | Recupera el valor del atributo y lo elimina de la información del nodo | 
|---|
| 242 | Parametros: | 
|---|
| 243 | - nombreatributo:El nombre del atributo | 
|---|
| 244 | - puntero: Referencia a la variable que contendrá el valor del atributo | 
|---|
| 245 | - info: La información del Nodo | 
|---|
| 246 | ------------------------------------------------------------------------------------------------*/ | 
|---|
| 247 | function TomaAtributoEspecial($nombreatributo,&$puntero,$info){ | 
|---|
| 248 | return($this->TomaAtributo($nombreatributo,$puntero,$info,true)); | 
|---|
| 249 | } | 
|---|
| 250 | /*------------------------------------------------------------------------------------------------ | 
|---|
| 251 | Recupera el valor del atributo | 
|---|
| 252 | Parametros: | 
|---|
| 253 | - nombreatributo:El nombre del atributo | 
|---|
| 254 | - puntero: Referencia a la variable que contendrá el valor del atributo | 
|---|
| 255 | - info: La información del Nodo | 
|---|
| 256 | - sw: Si vale true el atributo se eliminará de la información del nodo | 
|---|
| 257 | ------------------------------------------------------------------------------------------------*/ | 
|---|
| 258 | function TomaAtributo($nombreatributo,&$puntero,$info,$swkill=false){ | 
|---|
| 259 | $doblescomillas='"'; | 
|---|
| 260 | $strAtributo=" ".$nombreatributo."="; | 
|---|
| 261 | $pos=strpos($info,$strAtributo); | 
|---|
| 262 | if (!$pos){ | 
|---|
| 263 | $puntero=null; | 
|---|
| 264 | return($info); | 
|---|
| 265 | } | 
|---|
| 266 | $pos+=strlen($strAtributo);  // Avanza hasta el signo igual | 
|---|
| 267 | $posa=$pos; // Primera posición del valor del atributo | 
|---|
| 268 | $swcomillas=false; | 
|---|
| 269 | while ($pos<strlen($info)){ | 
|---|
| 270 | if ($doblescomillas==substr($info,$pos,1)) $swcomillas=!$swcomillas; | 
|---|
| 271 | if (' '==substr($info,$pos,1) || '> '==substr($info,$pos,1)) | 
|---|
| 272 | if (!$swcomillas) break; | 
|---|
| 273 | $pos++; | 
|---|
| 274 | } | 
|---|
| 275 | $posb=$pos; | 
|---|
| 276 | $valoratributo=substr($info,$posa,$posb-$posa); | 
|---|
| 277 | if ($swkill) // Eliminar el atributo de la la cadena | 
|---|
| 278 | $info=str_replace($strAtributo.$valoratributo,"",$info); // Elimina el atributo de la información | 
|---|
| 279 | if ($doblescomillas==substr($valoratributo,0,1)) // Elimina las comillas | 
|---|
| 280 | $valoratributo=str_replace($doblescomillas,"",$valoratributo); | 
|---|
| 281 | $puntero=$valoratributo; | 
|---|
| 282 | return($info); | 
|---|
| 283 | } | 
|---|
| 284 | } // Fin de la clase | 
|---|
| 285 |  | 
|---|