ก่อนอื่นฉันต้องยอมรับว่าฉันชอบมาตรฐานคอมพิวเตอร์ หากทุกคนปฏิบัติตามมาตรฐานของอุตสาหกรรม อินเทอร์เน็ตจะเป็นสื่อที่ดีกว่า การใช้รูปแบบการแลกเปลี่ยนข้อมูลที่เป็นมาตรฐานทำให้โมเดลการประมวลผลแบบเปิดและไม่ขึ้นกับแพลตฟอร์มเป็นไปได้ นั่นเป็นเหตุผลว่าทำไมฉันถึงเป็นคนที่กระตือรือร้น XML
โชคดีที่ภาษาสคริปต์ที่ฉันชื่นชอบไม่เพียงแต่รองรับ XML เท่านั้น แต่ยังรองรับเพิ่มมากขึ้นอีกด้วย PHP ช่วยให้ฉันเผยแพร่เอกสาร XML บนอินเทอร์เน็ตได้อย่างรวดเร็ว รวบรวมข้อมูลทางสถิติเกี่ยวกับเอกสาร XML และแปลงเอกสาร XML เป็นรูปแบบอื่น ตัวอย่างเช่น ฉันมักจะใช้ความสามารถในการประมวลผล XML ของ PHP ในการจัดการบทความและหนังสือที่ฉันเขียนในรูปแบบ XML
ในบทความนี้ ผมจะพูดถึงการใช้ Expat parser ในตัวของ PHP เพื่อประมวลผลเอกสาร XML ฉันจะสาธิตวิธีการประมวลผลของชาวต่างชาติผ่านตัวอย่างต่างๆ ในเวลาเดียวกัน ตัวอย่างสามารถแสดงวิธีการ:
สร้างฟังก์ชันการประมวลผลของคุณเอง
การแปลงเอกสาร XML ให้เป็นโครงสร้างข้อมูล PHP ของคุณเอง
บทนำ
Parser ของ Expat XML หรือที่เรียกว่าโปรเซสเซอร์ XML ช่วยให้โปรแกรมสามารถเข้าถึงโครงสร้างและเนื้อหาของเอกสาร XML ได้ Expat เป็นตัวแยกวิเคราะห์ XML สำหรับภาษาสคริปต์ PHP นอกจากนี้ยังใช้ในโครงการอื่น ๆ เช่น Mozilla, Apache และ Perl
parser ตามเหตุการณ์คืออะไร?
ตัวแยกวิเคราะห์ XML มีสองประเภทพื้นฐาน:
ตัวแยกวิเคราะห์แบบต้นไม้: แปลงเอกสาร XML ให้เป็นโครงสร้างแบบต้นไม้ parser ประเภทนี้แยกวิเคราะห์บทความทั้งหมดในขณะที่จัดเตรียม API เพื่อเข้าถึงแต่ละองค์ประกอบของแผนผังผลลัพธ์ มาตรฐานทั่วไปคือ DOM (Document Object Model)
ตัวแยกวิเคราะห์ตามเหตุการณ์: ถือว่าเอกสาร XML เป็นชุดของเหตุการณ์ เมื่อมีเหตุการณ์พิเศษเกิดขึ้น parser จะเรียกใช้ฟังก์ชันที่นักพัฒนาจัดเตรียมไว้ให้เพื่อจัดการมัน
ตัวแยกวิเคราะห์ตามเหตุการณ์มีมุมมองที่เน้นข้อมูลของเอกสาร XML ซึ่งหมายความว่าจะเน้นที่ส่วนข้อมูลของเอกสาร XML แทนที่จะเป็นโครงสร้าง ตัวแยกวิเคราะห์เหล่านี้ประมวลผลเอกสารตั้งแต่ต้นจนจบและรายงานเหตุการณ์ เช่น - จุดเริ่มต้นขององค์ประกอบ จุดสิ้นสุดขององค์ประกอบ จุดเริ่มต้นของข้อมูลคุณลักษณะ ฯลฯ - ไปยังแอปพลิเคชันผ่านฟังก์ชันการโทรกลับ ต่อไปนี้เป็นตัวอย่างเอกสาร XML สำหรับ "Hello-World":
<greeting>
สวัสดีชาวโลก
</greeting>
parser ตามเหตุการณ์จะรายงานเป็นสามเหตุการณ์:
องค์ประกอบเริ่มต้น: คำทักทาย
จุดเริ่มต้นของรายการ CDATA ค่าคือ: Hello World
องค์ประกอบสิ้นสุด: คำทักทาย
ต่างจาก parser แบบต้นไม้ ตัว parser ตามเหตุการณ์ไม่ได้สร้างโครงสร้างที่อธิบายเอกสาร ในรายการ CDATA ตัวแยกวิเคราะห์ตามเหตุการณ์จะไม่อนุญาตให้คุณรับข้อมูลทักทายขององค์ประกอบหลัก
อย่างไรก็ตาม ให้การเข้าถึงระดับที่ต่ำกว่า ซึ่งช่วยให้สามารถใช้ทรัพยากรได้ดีขึ้นและเข้าถึงได้รวดเร็วยิ่งขึ้น ด้วยวิธีนี้ ไม่จำเป็นต้องใส่เอกสารทั้งหมดลงในหน่วยความจำ ที่จริงแล้ว เอกสารทั้งหมดอาจมีขนาดใหญ่กว่าค่าหน่วยความจำจริงด้วยซ้ำ
ชาวต่างชาติเป็นตัวแยกวิเคราะห์ตามเหตุการณ์ แน่นอน หากคุณใช้ Expat ก็สามารถสร้างโครงสร้างต้นไม้ดั้งเดิมใน PHP ได้หากจำเป็น
ตัวอย่าง Hello-World ด้านบนมีรูปแบบ XML ที่สมบูรณ์ แต่ไม่ถูกต้องเนื่องจากไม่มี DTD (คำจำกัดความประเภทเอกสาร) ที่เกี่ยวข้องหรือ DTD ที่ฝังอยู่
สำหรับชาวต่างชาติ สิ่งนี้ไม่ได้สร้างความแตกต่างแต่อย่างใด: Expat เป็นตัวแยกวิเคราะห์ที่ไม่ตรวจสอบความถูกต้อง และดังนั้นจึงละเว้น DTD ใด ๆ ที่เกี่ยวข้องกับเอกสาร อย่างไรก็ตาม ควรสังเกตว่าเอกสารยังคงต้องมีการจัดรูปแบบอย่างสมบูรณ์ ไม่เช่นนั้นชาวต่างชาติ (เช่น โปรแกรมแยกวิเคราะห์ที่สอดคล้องกับ XML อื่นๆ) จะหยุดแสดงข้อความแสดงข้อผิดพลาด
เนื่องจากตัวแยกวิเคราะห์ที่ไม่ตรวจสอบความถูกต้อง ความเร็วและน้ำหนักเบาของ Exapt ทำให้เหมาะสำหรับแอปพลิเคชันอินเทอร์เน็ต
Compiling Expat
Expat สามารถคอมไพล์เป็นเวอร์ชัน PHP3.0.6 (หรือสูงกว่า) เริ่มต้นจาก Apache 1.3.9 Expat ได้รวมเป็นส่วนหนึ่งของ Apache บนระบบ Unix คุณสามารถคอมไพล์มันเป็น PHP ได้โดยกำหนดค่า PHP ด้วยตัวเลือก -with-xml
หากคุณคอมไพล์ PHP เป็นโมดูล Apache Expat จะถูกรวมเป็นส่วนหนึ่งของ Apache ตามค่าเริ่มต้น ใน Windows คุณต้องโหลดไลบรารีลิงก์ไดนามิก XML
ตัวอย่าง XML: XMLstats
วิธีหนึ่งในการเรียนรู้เกี่ยวกับฟังก์ชันของชาวต่างชาติคือผ่านตัวอย่าง ตัวอย่างที่เราจะพูดถึงคือการใช้ Expat เพื่อรวบรวมสถิติเกี่ยวกับเอกสาร XML
สำหรับแต่ละองค์ประกอบในเอกสาร ข้อมูลต่อไปนี้จะถูกส่งออก:
จำนวนครั้งที่มีการใช้องค์ประกอบในเอกสาร
จำนวนข้อมูลอักขระในองค์ประกอบนี้
องค์ประกอบหลักขององค์ประกอบ
องค์ประกอบลูกขององค์ประกอบ
หมายเหตุ: เพื่อการสาธิต เราใช้ PHP เพื่อสร้างโครงสร้างเพื่อบันทึกองค์ประกอบหลักและองค์ประกอบลูก
ของ
องค์ประกอบ
อินสแตนซ์นี้จะใช้สำหรับฟังก์ชันทั้งหมดในอนาคต แนวคิดนี้คล้ายกับแท็กการเชื่อมต่อของฟังก์ชัน MySQL ใน PHP มาก ก่อนที่จะแยกวิเคราะห์เอกสาร ตัวแยกวิเคราะห์ตามเหตุการณ์มักจะต้องการให้คุณลงทะเบียนฟังก์ชันการโทรกลับ - เพื่อให้ถูกเรียกเมื่อมีเหตุการณ์เฉพาะเกิดขึ้น ชาวต่างชาติไม่มีเหตุการณ์ข้อยกเว้น มันกำหนดเหตุการณ์ที่เป็นไปได้เจ็ดเหตุการณ์ต่อไปนี้:
องค์ประกอบคำอธิบายฟังก์ชันการแยกวิเคราะห์ XML ของวัตถุ
xml_set_element_handler() ข้อมูลอักขระเริ่มต้นและสิ้นสุด
ขององค์ประกอบ xml_set_Character_data_handler() จุดเริ่มต้นของข้อมูลอักขระ เอนทิ
ตีภายนอก xml_set_external_entity_ref_handler() เอนทิตีภายนอก เอนทิ
ตีภายนอกที่แยกวิเคราะห์ xml_set_unparsed_entity_decl_handler ( ) การเกิดขึ้นของ
คำสั่งการประมวลผลเอนทิตีภายนอกที่ยังไม่ได้รับการแก้ไข xml_set_processing_instruction_handler()
การเกิดขึ้นของการประกาศสัญลักษณ์คำสั่งการประมวลผล xml_set_notation_decl_handler() การเกิดขึ้นของการประกาศสัญลักษณ์
เริ่มต้น xml_set_default_handler() เหตุการณ์อื่น ๆ ที่ไม่มีฟังก์ชันตัวจัดการที่ระบุ
ฟังก์ชันการเรียกกลับทั้งหมดต้องใช้อินสแตนซ์ของ parser เป็นพารามิเตอร์ตัวแรก (มีพารามิเตอร์อื่นเพิ่มเติม)
สำหรับสคริปต์ตัวอย่างท้ายบทความนี้ สิ่งที่คุณต้องทราบคือใช้ทั้งฟังก์ชันการประมวลผลองค์ประกอบและฟังก์ชันการประมวลผลข้อมูลอักขระ ฟังก์ชันตัวจัดการการเรียกกลับขององค์ประกอบได้รับการลงทะเบียนผ่าน xml_set_element_handler()
ฟังก์ชันนี้รับพารามิเตอร์สามตัว:
อินสแตนซ์ของ parser
ชื่อของฟังก์ชันโทรกลับที่จัดการองค์ประกอบเริ่มต้น
ชื่อของฟังก์ชันโทรกลับที่จัดการองค์ประกอบปิด
ต้องมีฟังก์ชันการโทรกลับเมื่อเริ่มต้นการแยกวิเคราะห์เอกสาร XML ต้องกำหนดให้สอดคล้องกับต้นแบบที่อธิบายไว้ในคู่มือ PHP
ตัวอย่างเช่น Expat ส่งผ่านสามอาร์กิวเมนต์ไปยังฟังก์ชันตัวจัดการสำหรับองค์ประกอบเริ่มต้น ในตัวอย่างสคริปต์ มีการกำหนดดังนี้:
function start_element($parser, $name, $attrs)
พารามิเตอร์ตัวแรกคือ parser identifier พารามิเตอร์ตัวที่สองคือชื่อขององค์ประกอบเริ่มต้น และพารามิเตอร์ตัวที่สามประกอบด้วยแอ็ตทริบิวต์และ ค่าของอาร์เรย์องค์ประกอบ
เมื่อคุณเริ่มแยกวิเคราะห์เอกสาร XML แล้ว Expat จะเรียกใช้ฟังก์ชัน start_element() และส่งพารามิเตอร์เมื่อใดก็ตามที่พบองค์ประกอบ start
ตัวเลือก Case Folding ของ XML
ใช้ฟังก์ชัน xml_parser_set_option () เพื่อปิดตัวเลือก Case Folding ตัวเลือกนี้เปิดอยู่ตามค่าเริ่มต้น ทำให้ชื่อองค์ประกอบที่ส่งไปยังฟังก์ชันตัวจัดการถูกแปลงเป็นตัวพิมพ์ใหญ่โดยอัตโนมัติ แต่ XML คำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ (ดังนั้นตัวพิมพ์จึงมีความสำคัญมากสำหรับเอกสาร XML ทางสถิติ) สำหรับตัวอย่างของเรา ต้องปิดตัวเลือกการพับเคส
การแยกวิเคราะห์เอกสาร
หลังจากเสร็จสิ้นการเตรียมการทั้งหมดแล้ว ตอนนี้สคริปต์ก็สามารถแยกวิเคราะห์เอกสาร XML ได้ในที่สุด:
Xml_parse_from_file() ซึ่งเป็นฟังก์ชันที่กำหนดเอง เปิดไฟล์ที่ระบุในพารามิเตอร์และแยกวิเคราะห์ในขนาด 4kb
xml_parse() เช่นเดียวกับ xml_parse_from_file() จะส่งคืนค่า false เมื่อเกิดข้อผิดพลาด นั่นคือเมื่อเอกสาร XML ไม่ได้รับการฟอร์แมตอย่างสมบูรณ์
คุณสามารถใช้ฟังก์ชัน xml_get_error_code() เพื่อรับรหัสตัวเลขของข้อผิดพลาดครั้งล่าสุด ส่งรหัสตัวเลขนี้ไปที่ฟังก์ชัน xml_error_string() เพื่อรับข้อมูลข้อความแสดงข้อผิดพลาด
ส่งออกหมายเลขบรรทัดปัจจุบันของ XML ทำให้การดีบักง่ายขึ้น
ในระหว่างกระบวนการแยกวิเคราะห์ ฟังก์ชันการเรียกกลับจะถูกเรียก
การอธิบายโครงสร้างเอกสาร
เมื่อแยกวิเคราะห์เอกสาร คำถามที่ต้องตอบกับ Expat คือ จะรักษาคำอธิบายพื้นฐานของโครงสร้างเอกสารได้อย่างไร
ตามที่กล่าวไว้ก่อนหน้านี้ parser ตามเหตุการณ์ไม่ได้สร้างข้อมูลเชิงโครงสร้างใดๆ
อย่างไรก็ตาม โครงสร้างแท็กเป็นคุณลักษณะที่สำคัญของ XML ตัวอย่างเช่น ลำดับองค์ประกอบ <book><title> หมายถึงสิ่งที่แตกต่างจาก <figure><title> อย่างไรก็ตาม ผู้เขียนคนใดก็ตามจะบอกคุณว่าชื่อหนังสือและชื่อรูปภาพไม่เกี่ยวข้องกัน แม้ว่าทั้งสองจะใช้คำว่า "ชื่อ" ก็ตาม ดังนั้น เพื่อประมวลผล XML อย่างมีประสิทธิภาพด้วย parser ตามเหตุการณ์ คุณต้องใช้สแต็กหรือรายการของคุณเองเพื่อรักษาข้อมูลเชิงโครงสร้างเกี่ยวกับเอกสาร
เพื่อที่จะสะท้อนโครงสร้างเอกสาร สคริปต์จำเป็นต้องรู้อย่างน้อยองค์ประกอบหลักขององค์ประกอบปัจจุบัน สิ่งนี้เป็นไปไม่ได้ด้วย API ของ Exapt โดยจะรายงานเฉพาะเหตุการณ์ขององค์ประกอบปัจจุบันโดยไม่มีข้อมูลเชิงบริบท ดังนั้นคุณต้องสร้างโครงสร้างสแต็กของคุณเอง
ตัวอย่างสคริปต์ใช้โครงสร้างสแต็กเข้าก่อนออกก่อน (FILO) สแต็กจะบันทึกองค์ประกอบเริ่มต้นทั้งหมดผ่านอาร์เรย์ สำหรับฟังก์ชันการประมวลผลองค์ประกอบเริ่มต้น องค์ประกอบปัจจุบันจะถูกผลักไปที่ด้านบนของสแต็กโดยฟังก์ชัน array_push() ในทำนองเดียวกัน ฟังก์ชั่นการประมวลผลองค์ประกอบสุดท้ายจะลบองค์ประกอบด้านบนออกผ่าน array_pop()
สำหรับลำดับ <book><title></title></book> สแต็กจะถูกเติมดังนี้:
เริ่มต้นหนังสือองค์ประกอบ: กำหนด "book" ให้กับองค์ประกอบแรกของสแต็ก ($stack[0])
ชื่อองค์ประกอบเริ่มต้น: กำหนด "ชื่อ" ที่ด้านบนของสแต็ก ($stack[1])
ชื่อองค์ประกอบสิ้นสุด: ลบองค์ประกอบด้านบนออกจากสแต็ก ($stack[1])
ชื่อองค์ประกอบสุดท้าย: ลบองค์ประกอบด้านบนออกจากสแต็ก ($stack[0])
PHP3.0 นำตัวอย่างไปใช้โดยการควบคุมการซ้อนองค์ประกอบด้วยตนเองผ่านตัวแปร $deep ทำให้สคริปต์ดูซับซ้อนมากขึ้น PHP4.0 ใช้ฟังก์ชัน array_pop() และ array_push() เพื่อทำให้สคริปต์ดูกระชับยิ่งขึ้น
การรวบรวมข้อมูล
เพื่อรวบรวมข้อมูลเกี่ยวกับแต่ละองค์ประกอบ สคริปต์จำเป็นต้องจดจำเหตุการณ์สำหรับแต่ละองค์ประกอบ บันทึกองค์ประกอบต่างๆ ทั้งหมดในเอกสารโดยใช้ตัวแปรอาร์เรย์ส่วนกลาง $elements รายการของอาร์เรย์เป็นอินสแตนซ์ของคลาสองค์ประกอบและมีคุณสมบัติ 4 รายการ (ตัวแปรของคลาส)
$count - จำนวนครั้งที่พบองค์ประกอบในเอกสาร
$chars - จำนวนไบต์ของเหตุการณ์อักขระในองค์ประกอบ
$parents - องค์ประกอบหลัก
$childs - องค์ประกอบลูก
อย่างที่คุณเห็น การบันทึกคลาสอินสแตนซ์ในอาเรย์เป็นเรื่องง่าย
หมายเหตุ: คุณสมบัติหนึ่งของ PHP คือคุณสามารถสำรวจโครงสร้างคลาสทั้งหมดผ่านลูป while(list() = Each()) ได้ เช่นเดียวกับที่คุณสำรวจอาร์เรย์ที่เกี่ยวข้องทั้งหมด ตัวแปรคลาสทั้งหมด (และชื่อเมธอดเมื่อคุณใช้ PHP3.0) จะถูกส่งออกเป็นสตริง
เมื่อพบองค์ประกอบ เราจำเป็นต้องเพิ่มตัวนับที่สอดคล้องกันเพื่อติดตามจำนวนครั้งที่ปรากฏในเอกสาร องค์ประกอบการนับในรายการ $elements ที่เกี่ยวข้องจะเพิ่มขึ้นทีละหนึ่งด้วย
นอกจากนี้เรายังต้องแจ้งให้องค์ประกอบหลักทราบว่าองค์ประกอบปัจจุบันเป็นองค์ประกอบย่อย ดังนั้นชื่อขององค์ประกอบปัจจุบันจะถูกเพิ่มไปยังรายการในอาร์เรย์ $childs ขององค์ประกอบหลัก สุดท้ายนี้ องค์ประกอบปัจจุบันควรจำไว้ว่าใครคือผู้ปกครอง ดังนั้น องค์ประกอบหลักจึงถูกเพิ่มลงในรายการในอาร์เรย์ $parents ขององค์ประกอบปัจจุบัน
การแสดงสถิติ
โค้ดที่เหลือจะวนซ้ำผ่านอาร์เรย์ $elements และอาร์เรย์ย่อยเพื่อแสดงสถิติ นี่เป็นการวนซ้ำที่ง่ายที่สุด แม้ว่าจะให้ผลลัพธ์ที่ถูกต้อง แต่โค้ดก็ไม่กระชับหรือมีทักษะพิเศษใดๆ เลย มันเป็นเพียงการวนซ้ำที่คุณสามารถใช้ทุกวันเพื่อทำงานให้เสร็จ
ตัวอย่างสคริปต์ได้รับการออกแบบให้เรียกใช้จากบรรทัดคำสั่งผ่านวิธี CGI ของ PHP ดังนั้นรูปแบบผลลัพธ์ทางสถิติจึงเป็นรูปแบบข้อความ หากคุณต้องการใช้สคริปต์บนอินเทอร์เน็ต คุณจะต้องแก้ไขฟังก์ชันเอาต์พุตเพื่อสร้างรูปแบบ HTML
สรุป
Exapt เป็นตัวแยกวิเคราะห์ XML สำหรับ PHP เนื่องจาก parser ตามเหตุการณ์ จะไม่สร้างคำอธิบายเชิงโครงสร้างของเอกสาร แต่การให้การเข้าถึงระดับต่ำทำให้สามารถใช้ทรัพยากรได้ดีขึ้นและเข้าถึงได้รวดเร็วยิ่งขึ้น
เนื่องจากตัวแยกวิเคราะห์ที่ไม่ได้ตรวจสอบความถูกต้อง Expat จะละเว้น DTD ที่แนบมากับเอกสาร XML แต่จะหยุดพร้อมข้อความแสดงข้อผิดพลาดหากเอกสารมีรูปแบบไม่ถูกต้อง
จัดเตรียมตัวจัดการเหตุการณ์เพื่อประมวลผลเอกสาร
สร้างโครงสร้างเหตุการณ์ของคุณเอง เช่น สแต็กและทรี เพื่อใช้ประโยชน์จากมาร์กอัปข้อมูลที่มีโครงสร้าง XML
โปรแกรม XML ใหม่ปรากฏขึ้นทุกวัน และการรองรับ XML ของ PHP ก็ได้รับการปรับปรุงอย่างต่อเนื่อง (เช่น เพิ่มการรองรับ LibXML ตัวแยกวิเคราะห์ XML ที่ใช้ DOM)
ด้วย PHP และ Expat คุณสามารถเตรียมพร้อมสำหรับมาตรฐานที่กำลังจะมาถึงซึ่งถูกต้อง เปิดกว้าง และไม่ขึ้นอยู่กับแพลตฟอร์ม
ตัวอย่าง
<?
/************************************************* ***** ******************************
* ชื่อ: ตัวอย่างการแยกวิเคราะห์ XML: สถิติข้อมูลเอกสาร XML
* อธิบาย
* ตัวอย่างนี้ใช้ Expat parser ของ PHP เพื่อรวบรวมและนับข้อมูลเอกสาร XML (เช่น จำนวนครั้งที่เกิดขึ้นของแต่ละองค์ประกอบ องค์ประกอบหลัก และองค์ประกอบย่อย
* ไฟล์ XML เป็นพารามิเตอร์./xmlstats_PHP4.php3 test.xml
* $Requires: ข้อกำหนดของชาวต่างชาติ: Expat PHP4.0 ได้รับการคอมไพล์เป็นโหมด CGI
************************************************** * ***************************/
// พารามิเตอร์แรกคือไฟล์ XML
$file = $argv[1];
// การกำหนดค่าเริ่มต้นของตัวแปร
$elements = $stack = array();
$total_elements = $total_chars = 0;
//คลาสพื้นฐานขององค์ประกอบ
องค์ประกอบคลาส
-
var $count = 0;
var $chars = 0;
var $parents = array();
var $childs = อาร์เรย์();
}
// ฟังก์ชั่นแยกวิเคราะห์ไฟล์ XML
ฟังก์ชั่น xml_parse_from_file($parser, $file)
-
ถ้า(!file_exists($file))
-
die("ไม่พบไฟล์ "$file"");
}
ถ้า(!($fp = @fopen($file, "r")))
-
die("ไม่สามารถเปิดไฟล์ "$file"");
}
ในขณะที่($data = fread($fp, 4096))
-
if(!xml_parse($parser, $data, feof($fp)))
-
กลับ (เท็จ);
-
}
fclose($fp);
กลับ (จริง);
}
// ฟังก์ชั่นผลลัพธ์ผลลัพธ์ (รูปแบบกล่อง)
ฟังก์ชั่น print_box($title, $value)
-
printf("n+%'-60s+n", "");
printf("|%20s", "$title:");
printf("%14s", $value);
printf("%26s|n", "");
printf("+%'-60s+n", "");
}
// ฟังก์ชันผลลัพธ์เอาต์พุต (รูปแบบเส้น)
ฟังก์ชั่น print_line($title, $value)
-
printf("%20s", "$title:");
printf("%15sn", $value);
}
// ฟังก์ชั่นการเรียงลำดับ
ฟังก์ชั่น my_sort($a, $b)
-
return(is_object($a) && is_object($b) ? $b->นับ - $a->นับ: 0);
}
ฟังก์ชัน start_element($parser, $name, $attrs)
-
global $elements, $stack;
// องค์ประกอบอยู่ในอาร์เรย์ $elements ทั่วโลกแล้วหรือยัง?
ถ้า(!isset($องค์ประกอบ[$ชื่อ]))
-
// ไม่ - เพิ่มคลาสอินสแตนซ์ขององค์ประกอบ
$องค์ประกอบ = องค์ประกอบใหม่;
$องค์ประกอบ[$ชื่อ] = $องค์ประกอบ;
}
// เพิ่มตัวนับขององค์ประกอบนี้ทีละหนึ่ง
$elements[$name]->count++;
// มีองค์ประกอบหลักหรือไม่?
ถ้า(isset($stack[นับ($stack)-1]))
-
// ใช่ - กำหนดองค์ประกอบหลักให้กับ $last_element
$last_element = $stack[count($stack)-1];
// หากอาร์เรย์องค์ประกอบหลักขององค์ประกอบปัจจุบันว่างเปล่า ให้กำหนดค่าเริ่มต้นเป็น 0
if(!isset($elements[$name]->parents[$last_element]))
-
$elements[$name]->parents[$last_element] = 0;
}
// เพิ่มตัวนับองค์ประกอบหลักขององค์ประกอบนี้ทีละหนึ่ง
$elements[$name]->parents[$last_element]++;
// หากอาร์เรย์องค์ประกอบย่อยขององค์ประกอบหลักขององค์ประกอบปัจจุบันว่างเปล่า ระบบจะกำหนดค่าเริ่มต้นเป็น 0
if(!isset($elements[$last_element]-> ลูก [$ ชื่อ]))
-
$elements[$last_element]->ลูก[$ชื่อ] = 0;
}
// เพิ่มหนึ่งรายการให้กับตัวนับองค์ประกอบย่อยขององค์ประกอบหลักขององค์ประกอบ
$elements[$last_element]->ลูก[$ชื่อ]++;
}
//เพิ่มองค์ประกอบปัจจุบันลงในสแต็ก
array_push($สแต็ค, $ชื่อ);
}
ฟังก์ชั่น stop_element($parser, $name)
-
global $stack;
// ลบองค์ประกอบด้านบนออกจากสแต็ก
array_pop($กอง);
}
ฟังก์ชัน char_data($parser, $data)
-
global $elements, $stack, $deep;
// เพิ่มจำนวนอักขระขององค์ประกอบปัจจุบัน
$elements[$stack][count($stack)-1]]->chars += strlen(trim($data));
}
// สร้างอินสแตนซ์ parser
$parser = xml_parser_create();
// ตั้งค่าฟังก์ชันการประมวลผล
xml_set_element_handler($parser, "start_element", "stop_element");
xml_set_Character_data_handler($parser, "char_data");
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
// แยกวิเคราะห์ไฟล์
$ret = xml_parse_from_file($parser, $file);
ถ้า(!$ret)
-
die(sprintf("ข้อผิดพลาด XML: %s ที่บรรทัด %d",
xml_error_string(xml_get_error_code($parser))
xml_get_current_line_number($ตัวแยกวิเคราะห์)));
}
// ปล่อยตัวแยกวิเคราะห์
xml_parser_free($parser);
// ปล่อยองค์ประกอบตัวช่วย
unset($elements["current_element"]);
unset($elements["last_element"]);
// จัดเรียงตามจำนวนองค์ประกอบ
uasort($elements, "my_sort");
// วนซ้ำ $elements เพื่อรวบรวมข้อมูลองค์ประกอบ
ในขณะที่(รายการ($ชื่อ, $องค์ประกอบ) = แต่ละ($องค์ประกอบ))
-
print_box("ชื่อองค์ประกอบ", $name);
print_line("จำนวนองค์ประกอบ", $element->count);
print_line("Character count", $element->chars);
printf("n%20sn", "* Parent element");
// วนซ้ำพาเรนต์ขององค์ประกอบและส่งออกผลลัพธ์
ในขณะที่(รายการ($key, $value) = แต่ละ($องค์ประกอบ->ผู้ปกครอง))
-
print_line($คีย์, $value);
-
ถ้า(นับ($องค์ประกอบ->ผู้ปกครอง) == 0)
-
printf("%35sn", "[องค์ประกอบรูท]");
}
// วนซ้ำลูกขององค์ประกอบนี้และส่งออกผลลัพธ์
printf("n%20sn", "* องค์ประกอบลูก");
ในขณะที่(รายการ($key, $value) = แต่ละ($element->childs))
-
print_line($คีย์, $value);
-
ถ้า(นับ($องค์ประกอบ->ลูก) == 0)
-
printf("%35sn", "[ไม่มีลูก]");
}
$total_elements += $element->นับ;
$total_chars += $element->ตัวอักษร;
}
// ผลลัพธ์สุดท้าย
print_box("องค์ประกอบทั้งหมด", $total_elements);
print_box("จำนวนตัวอักษรทั้งหมด", $total_chars);
-