การแก้ไขปัญหารูปแบบเอกสาร ในรายการแม่ของฉันมีสูตรอาหารมากมายหรือหลายร้อยรายการ หากเกิดข้อผิดพลาดร้ายแรง การแก้ไขจุดบกพร่องจะยากมาก คุณจะต้องค้นหาเครื่องหมายที่หายไปทีละบรรทัด หากคุณใช้การซ้อนหลายระดับ การค้นหาข้อผิดพลาดจะเป็นเรื่องยาก
แต่ตัวช่วยดีๆก็มีได้ Parsers - แอปพลิเคชันที่แยกวิเคราะห์โค้ด XML และรายงานข้อผิดพลาดที่มีรูปแบบไม่ถูกต้องนั้นมีให้ใช้งานออนไลน์ได้อย่างอิสระ สิ่งที่ดีที่สุดคือ Lark ซึ่งเขียนโดย Tim Bray บรรณาธิการด้านเทคนิคและผู้สนับสนุนด้านข้อกำหนด XML ซึ่งเป็นหนึ่งในบุคคลที่ฉลาดที่สุดในโลก
ฉันใช้ Lark เพื่อวิเคราะห์โค้ดด้านล่าง โปรดทราบว่า "ช็อกโกแลตชิป" และแท็กปิดปรากฏอยู่ในตำแหน่งที่ไม่ถูกต้องภายในแท็ก </ingredients>:
<?xml version="1.0"?>
<list>
<recipe>
<author>Carol Schmidt</author>
<recipe_name >ช็อกโกแลตชิปแท่ง</recipe_name>
<meal>อาหารเย็น
<หลักสูตร>ของหวาน</course>
</meal>
<ส่วนผสม>
<item>เนย 2/3 C</item>
<item>น้ำตาลทรายแดง 2 C</ item>
<item>วานิลลา 1 ช้อนชา</item>
<item>แป้งอเนกประสงค์ 1 3/4 C ที่ไม่ได้ร่อน</item>
<item>ผงฟู 1 1/2 ช้อนชา</item>
<item>เกลือ 1/2 ช้อนชา< /item>
<item>ไข่ 3 ฟอง</item>
<item>ถั่วสับ 1/2 C</item>
<item>
</ส่วนผสม>2 ถ้วย (แพ็คละ 12 ออนซ์) ชิปช็อกโกแลตกึ่งหวาน
< /item >
<ทิศทาง>
เปิดเตา
อบที่ 350 องศา
ผสมกับน้ำตาลทรายแดงและวานิลลาในชามผสมขนาดใหญ่
พักไว้ให้เย็น ผสมแป้ง ผงฟู และเกลือ เข้าด้วยกัน
ผัด
ส่วนผสมแห้งถั่วและมันฝรั่ง
ทอดใน
กระทะ
ขนาด 13 x 9 นิ้ว อบประมาณ 25 ถึง 30 นาที
จน
เป็นสีเหลืองทอง
รายการ>
ต่อไปนี้คือผลลัพธ์ที่ส่งคืนโดยเครื่องวิเคราะห์:
รายงานข้อผิดพลาด
บรรทัดที่ 17 คอลัมน์ 22: พบ </ส่วนผสม> ที่คาดหวัง </item>
... ถือว่า </item>
บรรทัด 18 คอลัมน์ 36: พบ </item> ด้วย ไม่มีแท็กเริ่มต้น
ด้วยข้อมูลนี้ การค้นหาข้อผิดพลาดจะไม่เป็นปัญหา ความถูกต้องของไฟล์ XML หมายถึงอะไร?
การนำประสิทธิผลไปใช้ ในท้ายที่สุดเราจะเพิ่มข้อมูลลงในเอกสาร XML ที่มีการจัดระเบียบอย่างดี จริงๆ แล้ว เรามีงานต้องทำอีกมาก - ยังมีวิกฤติที่ซุ่มซ่อนอยู่ - และแม้ว่าไฟล์ XML จะได้รับการจัดระเบียบอย่างดี
แต่ข้อมูลสำคัญก็สามารถสูญหายได้เช่นกัน ดูตัวอย่างต่อไปนี้:
<recipe>
<author>แครอล ชมิดต์</author>
<recipe_name>ช็อกโกแลตแท่งแท่ง</recipe_name>
<อาหาร>อาหารเย็น <หลักสูตร>ของหวาน</หลักสูตร> </มื้อ>
<ส่วนผสม> </ส่วนผสม>
<directions>ละลายเนย รวมกับ ฯลฯ ... </directions>
</สูตร>
สูตรนี้ไม่ใส่ส่วนผสมค่ะ และเพราะจัดมาดีมาก
เครื่องวิเคราะห์ Lark ก็จะไม่พบปัญหาเช่นกัน ใครก็ตามที่จัดการแม้กระทั่งฐานข้อมูลที่อ่อนโยนที่สุดจะรู้ถึงข้อผิดพลาดที่มนุษย์ทำขึ้น เมื่อได้รับโอกาส เราจะโยนข้อมูลที่สำคัญออกไปและเพิ่มเรื่องไร้สาระที่ไร้ประโยชน์ลงไป นั่นเป็นสาเหตุที่นักประดิษฐ์ XML แนะนำ DTD -
คำจำกัดความประเภทเอกสาร DTD มีวิธีเพื่อให้แน่ใจว่า XML เป็นสิ่งที่คุณต้องการไม่มากก็น้อย
มาดู DTD ที่ใช้ในสูตรอาหารกันดีกว่า
<!รายการ DOCTYPE [
<!ELEMENT สูตรอาหาร (recipe_name, ผู้แต่ง, มื้ออาหาร, ส่วนผสม, วิธีใช้)>
<!ส่วนผสม ELEMENT (item+)>
<!ELEMENT มื้ออาหาร (#PCDATA, หลักสูตร?)>
<!รายการองค์ประกอบ (#PCDATA, sub_item*)>
<!ELEMENT สูตร_ชื่อ (#PCDATA)>
<!ผู้สร้าง ELEMENT (#PCDATA)>
<!หลักสูตร ELEMENT (#PCDATA)>
<!รายการองค์ประกอบ (#PCDATA)>
<!รายการย่อยองค์ประกอบ (#PCDATA)>
<!ทิศทางองค์ประกอบ (#PCDATA)>
-
โค้ดอาจดูไม่เป็นมิตรในตอนแรก แต่ก็สมเหตุสมผลเมื่อคุณแยกย่อย มาอธิบายโดยละเอียดกันดีกว่า:
<!DOCTYPE list [
บรรทัดนี้บอกว่าสิ่งที่อยู่ในวงเล็บเหลี่ยมคือเอกสารที่มีองค์ประกอบรูท <list>
ดีทีดี. ดังที่เราได้กล่าวไปแล้ว องค์ประกอบรูทประกอบด้วยองค์ประกอบอื่นๆ ทั้งหมด
<!ELEMENT สูตรอาหาร (recipe_name, มื้ออาหาร, ส่วนผสม, วิธีใช้)>
บรรทัดนี้กำหนดแท็ก <recipe> วงเล็บหมายความว่าแท็กสี่แท็กจะต้องปรากฏในแท็ก <recipe> ตามลำดับ
<!ELEMENT มื้ออาหาร (#PCDATA, หลักสูตร?)>
บรรทัดนี้ต้องการคำอธิบายโดยละเอียด ฉันได้กำหนดโครงสร้างดังต่อไปนี้:
<อาหาร>ในที่นี้ต้องระบุชื่ออาหาร
<หลักสูตร>อาจมีชื่อหลักสูตรหนึ่งรายการปรากฏขึ้น แต่ไม่ใช่
บังคับ</หลักสูตร>
</มื้ออาหาร>
ฉันทำเช่นนี้เพราะว่าฉันคิดอย่างไรว่าอาหารกลางวันไม่จำเป็นต้องเป็นอาหารจานใดโดยเฉพาะ แต่อาหารเย็นอาจชี้ไปที่อาหารเรียกน้ำย่อย อาหารจานหลัก และของหวาน โดยระบุ
#PCDATA - แสดงถึงข้อมูลอักขระที่แยกวิเคราะห์ (เช่น ข้อมูลที่ไม่ใช่ไบนารี) เพื่อใช้ฟังก์ชันนี้ ในที่นี้ #PCDATA คือข้อความ เช่น "dinner"
เครื่องหมายคำถามหลัง "course" ระบุว่าแท็ก <course> 0 หรือ 1 คู่จะปรากฏใน <meal>
ภายในเครื่องหมาย
ตอนนี้เรามาดูบรรทัดถัดไป:
<!ELEMENTส่วนประกอบ (item+)>
เครื่องหมายบวกที่นี่ระบุว่าควรมีแท็ก <item> อย่างน้อยหนึ่งคู่ควรปรากฏใน <ingredients>
ภายในเครื่องหมาย
บรรทัดสุดท้ายที่เราสนใจคือ:
<!ELEMENT item (#PCDATA, sub_item*)>
ฉันใส่ sub_item* เป็นมาตรการรักษาความปลอดภัย นอกจากจะขอข้อความแต่ละรายการแล้ว ผมขอนับจำนวนเนื้อหาแต่ละรายการด้วย เครื่องหมายดอกจันระบุจำนวนรายการย่อยที่สามารถรวมไว้ในแท็ก <item> ฉันไม่ต้องการรายการย่อยใดๆ สำหรับสูตรช็อกโกแลตชิปบาร์ แต่จะมีประโยชน์เมื่อส่วนผสมมีความซับซ้อน
ทีนี้ลองมารวมกันแล้วดูว่าเราได้อะไร
ตัวอย่างที่สมบูรณ์ของ DTD ด้านล่างเป็นตัวอย่างที่สมบูรณ์ ฉันเพิ่มสูตรอื่นลงในไฟล์และเพิ่ม
DTD มีคำอธิบายประกอบ จะสังเกตเห็นว่าฉันใช้รายการย่อยในสูตรที่สอง
<?xml เวอร์ชัน = "1.0"?>
<!--สิ่งนี้จะเริ่มต้น DTD โครงสร้างเอกสารที่อยู่สี่บรรทัดแรก-->
<!รายการ DOCTYPE ][
<!ELEMENT สูตรอาหาร (recipe_name, ผู้แต่ง, อาหาร, ส่วนผสม, วิธีใช้)>
<!ส่วนผสม ELEMENT (item+)>
<!ELEMENT มื้ออาหาร (#PCDATA, หลักสูตร?)>
<!รายการองค์ประกอบ (#PCDATA, sub_item*)>
<!--นี่คือองค์ประกอบที่เหลือของแท็กสูตรอาหาร -->
<!ELEMENT สูตร_ชื่อ (#PCDATA)>
<!ผู้สร้าง ELEMENT (#PCDATA)>
<!ทิศทางองค์ประกอบ (#PCDATA)>
<!--องค์ประกอบที่เหลือของแท็กมื้ออาหาร -->
<!หลักสูตร ELEMENT (#PCDATA)>
<!--องค์ประกอบที่เหลือของแท็กรายการ -->
<!ELEMENT sub_item (#PCDATA)>
-
<?xml เวอร์ชัน = "1.0"?>
<รายการ>
<สูตร>
<author>แครอล ชมิดต์</author>
<recipe_name>ช็อกโกแลตแท่งแท่ง</recipe_name>
<มื้ออาหาร>อาหารเย็น
<course>ของหวาน</course>
</มื้ออาหาร>
<ส่วนผสม>
<item>เนย 2/3 C</item>
<item>น้ำตาลทรายแดง 2 C</item>
<item>วานิลลา 1 ช้อนชา</item>
<item>1 3/4 C แป้งอเนกประสงค์ที่ไม่ได้ร่อน</item>
<item>ผงฟู 1 1/2 ช้อนชา</item>
<item>เกลือ 1/2 ช้อนชา</item>
<item>ไข่ 3 ฟอง</item>
<item>ถั่วสับ 1/2 C</item>
<item>มันฝรั่งทอดกึ่งหวาน 2 ถ้วย (12 ออนซ์)</item>
</ส่วนผสม>
<ทิศทาง>
เปิดเตาอบที่ 350 องศา
รวมกับน้ำตาลทรายแดงและวานิลลาในชามผสมขนาดใหญ่
พักไว้ให้เย็น รวมแป้ง ผงฟู และเกลือเข้าด้วยกัน
พักไว้ ใส่ไข่ลงในส่วนผสมน้ำตาลที่เย็นแล้ว ตีให้เข้ากัน
ผัดส่วนผสมแห้ง ถั่ว และมันฝรั่งทอดที่สงวนไว้
กระจายในกระทะขนาด 13 x 9 นิ้วที่ทาน้ำมันไว้
นำเข้าอบประมาณ 25 ถึง 30 นาทีจนเป็นสีเหลืองทอง
ตัดเป็นสี่เหลี่ยม
</ทิศทาง>
</สูตร>
<สูตร>
<recipe_name>พาสต้ากับซอสมะเขือเทศ</recipe_name>
<มื้ออาหาร>อาหารเย็น
<course>เข้าร่วม</course>
</มื้ออาหาร>
<ส่วนผสม>
<item>สปาเก็ตตี้ 1 ปอนด์</item>
<item>มะเขือเทศหั่นลูกเต๋าขนาด 16 ออนซ์ 1 ลูก</item>
<item>กระเทียม 4 กลีบ</item>
<item>หัวหอมหั่นเต๋า 1 หัว</item>
<item>เครื่องปรุงรสอิตาเลี่ยน
<sub_item>ออริกาโน</sub_item>
<sub_item>โหระพา</sub_item>
<sub_item>พริกแดงบด</sub_item>
</รายการ>
</ส่วนผสม>
<ทิศทาง>
ต้มพาสต้า. ผัดกระเทียมและหัวหอม.
ใส่มะเขือเทศ เสิร์ฟร้อน
</ทิศทาง>
</สูตร>
</รายการ>
ขณะนี้มี DTD แล้ว เอกสารจะถูกตรวจสอบเพื่อดูว่าเป็นไปตามข้อจำกัดที่ DTD กำหนดหรือไม่ กล่าวอีกนัยหนึ่ง เราต้องการรับรองความถูกต้องของเอกสาร
เพื่อให้บรรลุเป้าหมายนี้ เราต้องการเครื่องมืออื่น: เครื่องวิเคราะห์ความถูกต้อง MSXML ของ Microsoft ซึ่งเป็นโปรแกรมที่ใช้ Java ใช้งานง่ายและทำงานได้ดี เอกสารข้างต้นได้รับการตรวจสอบโดยโปรแกรมนี้และไม่พบข้อผิดพลาด แต่ถ้าผมตรวจสอบก
สูตรอาหารที่ไม่มีรายการในแท็กส่วนผสมจะแสดงข้อความต่อไปนี้:
องค์ประกอบที่คาดหวัง [รายการ]