Page 1 of 1

XML Parser (PHP)

Posted: Tue Jan 04, 2011 11:36 am
by nyquist
Hi guys,
This is my first post in the comunity and I want to say hello ! Hope to learn tons of things here.

I'm pretty new with PHP.. (and with general programming too). I'm trying to get some data from an XML and then show it in a table.

After read many tutorials, expat and php parser documentation, after analyze some "PHP XML to HTML table" samples, I decided to use the following functions to make the trick.

Code: Select all

<?php
     $cdata = '';
     $cur_elem = '';
     $simbolo_precio = '';
     $vencimiento_precio = '';
     $hora_precio = '';
     $variacion_precio = '';
     $precioultimo_precio = '';
     $preciocierreanterior_precio = '';
     $precioapertura_precio = '';
     $preciomaximo_precio = '';
     $preciominimo_precio = '';
     $volumennominal_precio = '';
     $montonegociado_precio = '';
     $nrooperaciones_precio = '';
   
     $hdr_row   = '<tr><td colspan="2">%s</td></tr>' . "\n";
     $data_row  = '<tr><td >%s</td><td>%s</td></tr>' . "\n";
     $empty_row = '<tr><td colspan="2">&nbsp;</td></tr>' . "\n";
   
     function start_elem ($parser, $name, $attrs) {
          global $cur_elem;
          $cur_elem = $name;
          if ($name == 'precios')
               print ("<table cellspacing=0 border=1>\n");
     }
     function end_elem ($parser, $name) {
          global $cdata, $cur_elem, $hdr_row, $data_row, $empty_row,
                 $simbolo_precio, $vencimiento_precio, $hora_precio,
		 $variacion_precio, $precioultimo_precio,
		 $preciocierreanterior_precio, $precioapertura_precio,
		 $preciomaximo_precio, $preciominimo_precio,
		 $volumennominal_precio, $montonegociado_precio,
		 $nrooperaciones_precio;
          $cdata = trim ($cdata);
          switch ($name)
          {
               case ("precios"):
                    print ("</table>\n"); break;
               case ("simbolo"):
               		print (sprintf ($hdr_row,"$simbolo_precio"));
                    $simbolo_precio = ''; break;
               case ("vencimiento"):
               		print (sprintf ($data_row, "Vencimiento", $cdata));
                    $vencimiento_precio = ''; break;
               case ("hora"):
               		print (sprintf ($data_row, "Hora", $cdata));
                    $hora_precio = ''; break;
               case ("variacion"):
                    print (sprintf ($data_row, "Variacion", $cdata));
                    $variacion_precio = ''; break;
               case ("precioultimo"):
                    print (sprintf ($data_row, "Precio Ultimo", $cdata));
                    $precioultimo_precio = ''; break;
               case ("preciocierreanterior"):
                    print (sprintf ($data_row, "Precio Cierre Anterior", $cdata));
                    $preciocierreanterior_precio = ''; break;
               case ("precioapertura"):
			   		print (sprintf ($data_row, "Precio Apertura", $cdata));
                    $precioapertura_precio = ''; break;
               case ("preciomaximo"):
			   		print (sprintf ($data_row, "Precio Maximo", $cdata));
                    $preciomaximo_precio = ''; break;
               case ("preciominimo"):
			   		print (sprintf ($data_row, "Precio Minimo", $cdata));
                    $preciominimo_precio = ''; break;
               case ("volumennominal"):
			   		print (sprintf ($data_row, "Volumen Nominal", $cdata));
                    $volumennominal_precio = ''; break;
               case ("montonegociado"):
			   		print (sprintf ($data_row, "Monto Negociado", $cdata));
                    $montonegociado_precio = ''; break;
               case ("nrooperaciones"):
			   		print (sprintf ($data_row, "Nro de Operaciones", $cdata));
                    $nrooperaciones_precio = ''; break;
			   case ("precio"):
			   		print ($empty_row); break;            	
          }
          $cdata = '';
     }
     function cdata ($parser, $data) {
          global $cdata, $cur_elem, $simbolo_precio, $vencimiento_precio,
		   $hora_precio, $variacion_precio, $precioultimo_precio,
		   $preciocierreanterior_precio, $precioapertura_precio,
		   $preciomaximo_precio, $preciominimo_precio,
		   $volumennominal_precio, $montonegociado_precio,
		   $nrooperaciones_precio;
          $data = trim ($data);
          switch ($cur_elem)
          {
               case ("simbolo"):
                    $simbolo_precio .= $data; break;
               case ("vencimiento"):
                    $vencimiento_precio .= $data; break;
               case ("hora"):
                    $hora_precio .= $data; break;
               case ("variacion"):
                    $variacion_precio .= $data; break;
               case ("precioultimo"):
                    $precioultimo_precio .= $data; break;
               case ("preciocierreanterior"):
                    $preciocierreanterior_precio .= $data; break;
               case ("precioapertura"):
                    $precioapertura_precio .= $data; break;
               case ("preciomaximo"):
                    $preciomaximo_precio .= $data; break;
               case ("preciominimo"):
                    $preciominimo_precio .= $data; break;
               case ("volumennominal"):
                    $volumennominal_precio .= $data; break;
               case ("montonegociado"):
                    $montonegociado_precio .= $data; break;
               case ("nrooperaciones"):
                    $nrooperaciones_precio .= $data; break; 
               default:
                  $cdata .= $data;
          }
     }
     $file = "actions.xml";
     $parser = xml_parser_create ();
     xml_parser_set_option ($parser, XML_OPTION_CASE_FOLDING, false);
     xml_set_element_handler ($parser, "start_elem", "end_elem");
     xml_set_character_data_handler ($parser, "cdata");
     $fp = fopen ($file, "r");

     if (!$fp){
          die ("Couldn't open $file for reading");
     }
     while ($xml_input = fread ($fp, filesize($file))) {
          $ok = xml_parse ($parser, $xml_input, feof ($fp));
          if (!$ok){
               die (sprintf ("Error in $file: '%s' at line %d",
                             xml_error_string (xml_get_error_code ($parser)),
                             xml_get_current_line_number ($parser)));
          }
     }
     xml_parser_free ($parser);
?>
Now.. almost everything is working fine, but cdata function.

The table is draw, the left column is populated with the "capitalized xml tag name", but the right column is not being populated.

This is the XML I'm trying to parse.
[text]<precios>
<precio>
<simbolo>APBR</simbolo>
<emisor/>
<vencimiento>4</vencimiento>
<hora>16:58</hora>
<variacion>2.394</variacion>
<precioultimo>77.000</precioultimo>
<preciocierreanterior>75.200</preciocierreanterior>
<precioapertura>76.000</precioapertura>
<preciomaximo>77.500</preciomaximo>
<preciominimo>75.550</preciominimo>
<volumennominal>101,548</volumennominal>
<montonegociado>7,749,666</montonegociado>
<nrooperaciones>225</nrooperaciones>
</precio>
<precio>
<simbolo>BMA</simbolo>
<emisor/>
<vencimiento>4</vencimiento>
<hora>16:59</hora>
<variacion>-1.043</variacion>
<precioultimo>5.690</precioultimo>
<preciocierreanterior>5.750</preciocierreanterior>
<precioapertura>5.750</precioapertura>
<preciomaximo>5.750</preciomaximo>
<preciominimo>5.600</preciominimo>
<volumennominal>398,256</volumennominal>
<montonegociado>2,250,775</montonegociado>
<nrooperaciones>87</nrooperaciones>
</precio>
<precio>
<simbolo>BPAT</simbolo>
<emisor/>
<vencimiento>4</vencimiento>
<hora>17:00</hora>
<variacion>0.000</variacion>
<precioultimo>1.580</precioultimo>
<preciocierreanterior>1.580</preciocierreanterior>
<precioapertura>1.570</precioapertura>
<preciomaximo>1.580</preciomaximo>
<preciominimo>1.540</preciominimo>
<volumennominal>205,443</volumennominal>
<montonegociado>323,969</montonegociado>
<nrooperaciones>51</nrooperaciones>
</precio>
<precio>
<simbolo>EDN</simbolo>
<emisor/>
<vencimiento>4</vencimiento>
<hora>16:59</hora>
<variacion>-0.971</variacion>
<precioultimo>1.020</precioultimo>
<preciocierreanterior>1.030</preciocierreanterior>
<precioapertura>1.020</precioapertura>
<preciomaximo>1.030</preciomaximo>
<preciominimo>1.000</preciominimo>
<volumennominal>857,912</volumennominal>
<montonegociado>870,381</montonegociado>
<nrooperaciones>99</nrooperaciones>
</precio>
<precio>
<simbolo>ERAR</simbolo>
<emisor/>
<vencimiento>4</vencimiento>
<hora>16:55</hora>
<variacion>-1.596</variacion>
<precioultimo>9.250</precioultimo>
<preciocierreanterior>9.400</preciocierreanterior>
<precioapertura>9.550</precioapertura>
<preciomaximo>9.550</preciomaximo>
<preciominimo>9.250</preciominimo>
<volumennominal>39,005</volumennominal>
<montonegociado>363,131</montonegociado>
<nrooperaciones>59</nrooperaciones>
</precio>
<precio>
<simbolo>FRAN</simbolo>
<emisor/>
<vencimiento>4</vencimiento>
<hora>16:59</hora>
<variacion>-4.673</variacion>
<precioultimo>5.100</precioultimo>
<preciocierreanterior>5.350</preciocierreanterior>
<precioapertura>5.300</precioapertura>
<preciomaximo>5.300</preciomaximo>
<preciominimo>5.060</preciominimo>
<volumennominal>227,960</volumennominal>
<montonegociado>1,164,731</montonegociado>
<nrooperaciones>136</nrooperaciones>
</precio>
<precio>
<simbolo>GGAL</simbolo>
<emisor/>
<vencimiento>4</vencimiento>
<hora>16:57</hora>
<variacion>1.770</variacion>
<precioultimo>1.150</precioultimo>
<preciocierreanterior>1.130</preciocierreanterior>
<precioapertura>1.130</precioapertura>
<preciomaximo>1.160</preciomaximo>
<preciominimo>1.110</preciominimo>
<volumennominal>1,601,176</volumennominal>
<montonegociado>1,817,510</montonegociado>
<nrooperaciones>156</nrooperaciones>
</precio>
<precio>
<simbolo>PAMP</simbolo>
<emisor/>
<vencimiento>4</vencimiento>
<hora>16:58</hora>
<variacion>0.000</variacion>
<precioultimo>1.140</precioultimo>
<preciocierreanterior>1.140</preciocierreanterior>
<precioapertura>1.140</precioapertura>
<preciomaximo>1.160</preciomaximo>
<preciominimo>1.130</preciominimo>
<volumennominal>1,486,893</volumennominal>
<montonegociado>1,706,582</montonegociado>
<nrooperaciones>141</nrooperaciones>
</precio>
<precio>
<simbolo>PBE</simbolo>
<emisor/>
<vencimiento>4</vencimiento>
<hora>17:00</hora>
<variacion>-3.097</variacion>
<precioultimo>2.190</precioultimo>
<preciocierreanterior>2.260</preciocierreanterior>
<precioapertura>2.280</precioapertura>
<preciomaximo>2.280</preciomaximo>
<preciominimo>2.190</preciominimo>
<volumennominal>635,695</volumennominal>
<montonegociado>1,411,003</montonegociado>
<nrooperaciones>71</nrooperaciones>
</precio>
<precio>
<simbolo>TECO2</simbolo>
<emisor/>
<vencimiento>4</vencimiento>
<hora>16:59</hora>
<variacion>-1.967</variacion>
<precioultimo>8.970</precioultimo>
<preciocierreanterior>9.150</preciocierreanterior>
<precioapertura>9.300</precioapertura>
<preciomaximo>9.350</preciomaximo>
<preciominimo>8.900</preciominimo>
<volumennominal>254,769</volumennominal>
<montonegociado>2,329,740</montonegociado>
<nrooperaciones>159</nrooperaciones>
</precio>
<precio>
<simbolo>TS</simbolo>
<emisor/>
<vencimiento>4</vencimiento>
<hora>16:59</hora>
<variacion>1.692</variacion>
<precioultimo>51.100</precioultimo>
<preciocierreanterior>50.250</preciocierreanterior>
<precioapertura>51.500</precioapertura>
<preciomaximo>52.200</preciomaximo>
<preciominimo>51.000</preciominimo>
<volumennominal>248,289</volumennominal>
<montonegociado>12,797,297</montonegociado>
<nrooperaciones>612</nrooperaciones>
</precio>
</precios>
<emisor/>
<vencimiento>4</vencimiento>
<hora>16:59</hora>
<variacion>1.692</variacion>
<precioultimo>51.100</precioultimo>
<preciocierreanterior>50.250</preciocierreanterior>
<precioapertura>51.500</precioapertura>
<preciomaximo>52.200</preciomaximo>
<preciominimo>51.000</preciominimo>
<volumennominal>248,289</volumennominal>
<montonegociado>12,797,297</montonegociado>
<nrooperaciones>513</nrooperaciones>
</precio>
</precios>[/text]


Which could be my error here?

Regards!
Nyquist

Re: XML Parser (PHP)

Posted: Tue Jan 04, 2011 2:05 pm
by Darhazer
Wow, so many global variables :crazy:

In the end_elem function you are using = instead of .= - maybe this is the cause of the problem.
If not, try using SimpleXML - it's much easier.