โจทย์ http://www.codenone.com/node/140
ทาง python เขาใช้ SAX ไปแล้ว
ดังนั้นเราลองหันไปใช้ DOM บ้าง
require 'rexml/document' include REXML src =<<-EOF <node> <node level="0" type="c" name="toplevel"/> <node level="1" type="i" name="1. item"/> <node level="1" type="c" name="2. container"/> <node level="2" type="i" name="2.1 item"/> <node level="2" type="i" name="2.2 item"/> <node level="1" type="i" name="3. item"/> <node level="1" type="c" name="4. container"/> <node level="2" type="i" name="4.1 item"/> <node level="2" type="c" name="4.2 container"/> <node level="3" type="i" name="4.2.1 item"/> </node> EOF def solve(doc) stack = [Element.new("node")] old_level = 0 doc.root.each_element('//node/node') do |node| level = node.attributes['level'].to_i node.attributes.delete('level') (old_level-level).times {stack.pop} if level < old_level stack.last << node stack << node if node.attributes['type'] == 'c' old_level = level end stack.first end doc = Document.new(src) puts solve(doc)
ไม่รู้มี bug หรือเปล่า
กระทู้เก่าๆ จะย้ายตามไปในภายหลัง ตอนนี้ปิดการโพสต์กระทู้ไว้ เหลือไว้เฉพาะอ้างอิงเท่านั้น
(ก่อนจะทำโจทย์) ผมนึกถึง rexml เหมือนกันนะ แต่นึกถึง code แบบนี้ไม่ออก
ว่าแล้วเชียว DOM ต้องง่ายกว่า
SAX มีข้อดีตรงความเร็ว, ไม่กิน memory
DOM มีข้อดีตรงความง่ายในการใช้
ก็เลยมีคนทำ XML Pull Parser
parse แบบเดียวกับ SAX แต่แทนที่จะเป็น push (callback)
ก็เป็น pull แทน (ทำให้ดึง element ออกมาได้ง่ายกว่า)
ผมลองเขียนโดยใช้ pull parser บ้าง
โปรแกรมนี้จะ parse xml และให้ output เป็น DOM object
(่โชคร้ายที่โจทย์นี้ ไม่ส่งเสริมให้เห็นความสวยงามของ pull เลย)