public static function xml2tree($string, $depth = 999) {
		$parser = xml_parser_create();
		$vals = array();
		$index = array();

		xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
		xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0);
		xml_parse_into_struct($parser, $string, $vals, $index);

		if (xml_get_error_code($parser)) {
			return 'Line ' . xml_get_current_line_number($parser) . ': ' . xml_error_string(xml_get_error_code($parser));
		}
		xml_parser_free($parser);

		$stack = array(array());
		$stacktop = 0;
		$startPoint = 0;

		$tagi = array();
		foreach ($vals as $key => $val) {
			$type = $val['type'];

				// open tag:
			if ($type == 'open' || $type == 'complete') {
				$stack[$stacktop++] = $tagi;

				if ($depth == $stacktop) {
					$startPoint = $key;
				}

				$tagi = array('tag' => $val['tag']);

				if (isset($val['attributes'])) {
					$tagi['attrs'] = $val['attributes'];
				}
				if (isset($val['value'])) {
					$tagi['values'][] = $val['value'];
				}
			}
				// finish tag:
			if ($type == 'complete' || $type == 'close') {
				$oldtagi = $tagi;
				$tagi = $stack[--$stacktop];
				$oldtag = $oldtagi['tag'];
				unset($oldtagi['tag']);

				if ($depth == ($stacktop + 1)) {
					if ($key - $startPoint > 0) {
						$partArray = array_slice(
							$vals,
								$startPoint + 1,
								$key - $startPoint - 1
						);
						$oldtagi['XMLvalue'] = self::xmlRecompileFromStructValArray($partArray);
					} else {
						$oldtagi['XMLvalue'] = $oldtagi['values'][0];
					}
				}

				$tagi['ch'][$oldtag][] = $oldtagi;
				unset($oldtagi);
			}
				// cdata
			if ($type == 'cdata') {
				$tagi['values'][] = $val['value'];
			}
		}
		return $tagi['ch'];
	}