• PHP Help PHP Coding
  • Parse XML, working script with a very strange error that will kill me -- PLEASE HELP!

This will kill me - I have to check more than a 1000 data points every 10min, every working day - so my visitors don't notice the errors, and my site looses credibility...
I will definitely go crazy if somebody doesn't help me solve this...

BACKGROUND:
I have a financial website that display's Stock Market Data from my country's stock exchange.
Stock Market Data is read from an XML file and written to a database.
Data is refreshed every ten minutes (around 40 times per day), for 200+ stocks.

PROBLEM:
Most of the time everything works fine, but, several times each day, during a refresh, a data for a random stock, usually only one, is read only partialy.
(for example. instead of HighPrice=320.99, to a database is written HighPrice=99, or, instead of DailyLow=4270.01, database contains DailyLow=70.01 )

PROBLEM SCRIPTS:
XML.class.php - parses XML data and places it in a structured PHP array (I think the error is somewhere here)
ZSE.class.php - reads the data and writes it to a database.

Potentially important facts:

  • XML is allways clean of errors.

  • Time of data collection(refresh) is not important, sometimes the error appears at 10:25, sometimes at 12:35, sometimes at 15:45, etc...

  • Usually the error is limitied to only one stock out of 200+, rarely two or three of them have errors.

  • Data is collected for several fields - but only one has an error: High Price, Low Price, Closing Price, Buy Price, Sell Price, Volume, Average Price. But every time the data is read partially it is limited to only one field. For example, sometimes the Closing price has an error (to a database is written 16 instead of 316), sometimes some other price like daily low price or average price.

  • Dellimiter is not an issue, the data is read partially independent of it. For e.g. sometimes instead of Average Price=24.49 to a database is written only the decimal part 49, sometimes instead of SellPrice=3420 database contains SellPrice=20.

Example:
http://img638.imageshack.us/i/errortuho.png/][img]http://img638.imageshack.us/img638/8433/errortuho.th.png
(Zoom in after opening page)

XML.class.php

<?php

/**
* This class parses XML data and places it in a structured PHP array. Array keys are equal to XML tags and each array element
* can either be a scalar value or an array. In the former case, this is the data found inside the XML tags in question and in the
* latter the array will have numeric keys, each of which as a value has an array that conforms to the same rules as the whole 
* outer array. 
* The typical piece of data can be retrieved as $resultingArray['level1node'][2]['level2node'][6]['level3node'][0]...
*/
class XML {

	var $_fileName;
	var $_xmlpath = array();
	var $_values = array();
	var $_levelsNumbering = array();
	var $_currentDepth = 0;

	/**
	* Common PHP XML function for proccessing opening tags. It updates breadcrumbs arrays by adding new element to the existing node
	* list or initialising new node list if needed.
	*/
	function startElement($parser, $name, $attributes){

		$this->_currentDepth++;
		$this->_xmlpath[$this->_currentDepth] = $name;

		if (isset($this->_levelsNumbering[$this->_currentDepth][$name])) {
			$this->_levelsNumbering[$this->_currentDepth][$name]++;
		}
		else {
			$this->_levelsNumbering[$this->_currentDepth][$name] = 0;
		}

	}

	/**
	* Common PHP XML function for proccessing closing tags. It updates breadcrumbs arrays by removing an element from the node
	* list and removes all finished branches of XML paths (once the node is closed, it's children list is finalized).
	*/
	function endElement($parser, $name){

		$this->_currentDepth--;
		unset($this->_levelsNumbering[$this->_currentDepth + 2]);

		array_pop($this->_xmlpath);
	}

	/**
	* Common PHP XML function for proccessing intratag data. It uses breadcrumbs arrays to construct the resulting array's structure
	* for each piece of data found in the XML.
	* 
	*/
	function characterData($parser, $data) {

		$data = trim($data);

		if ($data != '') {

			$reference = &$this->_values;
			for ($i = 1; $i <= $this->_currentDepth; $i++) {

				$name = $this->_xmlpath[$i];

				if (!isset($reference[$name])) {
					$reference[$name] = array();
				}

				if ($i == $this->_currentDepth) {
					$reference[$name][$this->_levelsNumbering[$i][$name]] = $data;
				}
				else {
					if (!isset($reference[$name][$this->_levelsNumbering[$i][$name]])) {
						$reference[$name][$this->_levelsNumbering[$i][$name]] = array();
					}
				}

				$reference = &$reference[$name][$this->_levelsNumbering[$i][$name]];
			}
		}
	}

	function parse($_xmlLocation) {

		$this->_fileName = $_xmlLocation;

		$xml_parser = xml_parser_create();
		xml_set_object($xml_parser, $this);
		xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, false);
		xml_set_element_handler($xml_parser, 'startElement', 'endElement');
		xml_set_character_data_handler($xml_parser, 'characterData');
		if (!($fp = fopen($this->_fileName, 'r'))) {
			die('could not open XML input');
		}

		while ($file_content = fread($fp, 4096)) {
			if (!xml_parse($xml_parser, $file_content, feof($fp))) {
				die(sprintf("XML error: %s at line %d", xml_error_string(xml_get_error_code($xml_parser)), xml_get_current_line_number($xml_parser)));
			}
		}
		xml_parser_free($xml_parser);

		return $this->_values;
	}

}


?>

    You can find ZSE.class.php in the attachment.

    I'dont think that the error is here, it is probably in XML.class.php.
    I suspect that only one function could be an issue - getMarketTradingData (on lines 167-209), everything above that just writes to the database.

      Write a Reply...