<?php
/*
Script_name : xmldata.php
Source_code : http://www.thaiall.com/xml/
Version 2.2560-08-21
###########################
Update Description
- ปรับให้ทำงานกับทั้ง education.xml ที่ได้จาก truehits.net  และ ผ่าน url กับ entertain.xml
- ปรับให้ทำงานกับ employees.xml ที่สร้างขึ้นเอง http://www.thaiall.com/xml/employees.xml
- ทดสอบบน Xampp 3.2.2 เมื่อ 21 สิงหาคม 2560 สามารถใช้งานได้ทั้ง 3 กรณี
http://localhost/xmldata.php?file=education.xml (ข้อมูลจาก truehits.net)
http://localhost/xmldata.php?file=employees.xml (สร้างขึ้นมาเพื่อทดสอบ)
http://localhost/xmldata.php?file=http://truehits.net/xml/entertain.xml
########################### */
/* Section 1 : Configuration */
if(isset($_REQUEST["file"])) $file_name = $_REQUEST["file"];
if(!isset($file_name) || strlen($file_name) < 4) { $file_name = "employees.xml"; }
$total_column = 999;		# เก็บจำนวน column ใน endElement ที่กำหนด 999 เพราะรองแรกไม่รู้จำนวน แต่ต้องใช้
$cnt_working_col = 1;		# ใช้นับ column ในแต่ละระเบียน จึง reset
$count_record = 0;			# ใช้นับ record ทั้งหมด
$count_column = 0;			# ใช้นับจำนวน column ทั้งหมด
$last_field = null; 		# สำหรับตรวจ last field
$xml_name = array();
/* Section 2 : Main Process */
if (!in_array($file_name, array("education.xml", "employees.xml"))) {
	die("Filename : limited");
}
if (!(list($xml_parser, $handle) = new_xml_parser($file_name))) {
	die("Could not open XML file");
}
// while ($read_data = fread($handle, filesize($file_name))) { // filesize ใช้กับ fopen จาก url ไม่ได้
while ($read_data = fread($handle, 8192)) {	
	if (!xml_parse($xml_parser, $read_data, feof($handle))) {
		die(sprintf("XML error: %s at line %dn",
		xml_error_string(xml_get_error_code($xml_parser)),
		xml_get_current_line_number($xml_parser)));
	}
}
print_data();
xml_parser_free($xml_parser);
/* Section 3 : Function Stock */
function print_data () {
	global $count_column, $count_record, $data, $xml_name, $data_attribs;	
	echo "<pre>[ record: $count_record column: ". ($count_column - 2) ."] \n"; 
	// หากนับเฉพาะตัวข้อมูล ก็จะไม่นับ <employee> กับ  <empl> จึงลบจำนวน $count_column ออกไป 2 ก็จะเหลือ 3
	// ที่ข้อมูลแสดงมา 4 column เพราะนำ attribute department ของ <empl> มาแสดง
	if(isset($data_attribs[0])) {
		// ใช้กรณีมี attribs ตั้งแต่ column แรก มีตัวอย่างใน education.xml
		for($i=0;$i<=count($data_attribs);$i++) { 
			echo $data_attribs[0][$i] . "\n";	
		}
	}
	for ($i=1;$i<count($xml_name);$i++) { echo " [ $xml_name[$i] ] "; }
	echo "<br/>";
	for ($i=1;$i<=$count_record;$i++) {
		// ใช้กรณีมี attribs ใน column ที่คุมระเบียน  หรือ ก่อนเข้า field
		if(isset($data_attribs[$i][0])) echo $data_attribs[$i][0]; else echo "null";
		echo " | "; // department
		for ($j=1;$j<$count_column;$j++) { 
			if(isset($data[$i][$j])) echo $data[$i][$j]. " : "; 
		}
		echo "\n";
	}
}
// เข้าฟังก์ชันนี้ เมื่อพบการเปิด <Tag ..> เปิดเท่าใดก็เรียกใช้เท่านั้น 
function startElement($parser, $name, $attribs) {
	global $count_column,$count_record,$xml_name,$last_field,$data_attribs,$total_column;
	if (isset($xml_name[0]) && (!isset($xml_name[1]) || $xml_name[1] == $name)) {
		$count_record++; // สำหรับนับ record
	}		
	if (count($attribs) > 0) { // ถ้ามี attribs ก็จะเก็บข้อมูลไว้เรียกใช้ภายหลัง
		$cnt_attribs = 0;
		foreach($attribs as $key => $value) { 
			$data_attribs[$count_record][$cnt_attribs++] = "$key:$value"; 	// department:sale
		}	
	}	
	if ($last_field == null ) {
		if(!in_array($name,$xml_name)) {
			$xml_name[$count_column] = $name;		
			$count_column = $count_column + 1; // สำหรับนับ column
		}
	}
	if (isset($xml_name[1]) && $xml_name[1] == $name && $count_column > $total_column) {
		$last_field = $name;
	}
}
// เข้าฟังก์ชันนี้ เมื่อพบการปิด </Tag> ปิดเท่าใดก็เรียกใช้เท่านั้น
function endElement($parser, $name) {
	global $xml_name,$cnt_working_col,$total_column;
	if ($name == $xml_name[1]) {
		$total_column = $cnt_working_col; // บันทึกจำนวน column ที่มากที่สุด คือ จำนวน column
		$cnt_working_col = 1; // บันทึกว่าปัจจุบันทำงาน columnn ที่เท่าใด เริ่ม reset ใหม่เมื่อปิด Tag
	}
}
// เข้าฟังก์ชันนี้ หลังเปิด  หรือ หลังปิด Tag แต่หยุดเข้าหลังปิด Tag ตัวสุดท้าย
function characterData($parser, $read_data) {
	global $data,$count_record,$cnt_working_col;
	if (strlen($read_data) > 1) {
		$data[$count_record][$cnt_working_col++] = $read_data;
	}
}
function new_xml_parser($file_name) {
	global $parser_file;
	$xml_parser = xml_parser_create(); // ผู้แยกคำ = parser
	xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 0);
	xml_set_element_handler($xml_parser, "startElement", "endElement");
	xml_set_character_data_handler($xml_parser, "characterData");
	if (!($handle = @fopen($file_name, "r"))) { return false; }
	if (!is_array($parser_file)) { settype($parser_file, "array"); }
	$parser_file[$xml_parser] = $file_name;
	return array($xml_parser, $handle);	
}
?>