#!/usr/bin/env ruby # REXMLBuilder -- REXML document builder using XMLParser # by TAKAHASHI 'Maki' Masayoshi # This source is under public domain. # 2001/12/15 v1.0 first release. require 'xmlparser' require 'rexml/document' class REXMLBuilder < XMLParser def initialize(*args) super(*args) end def startElement(name, attr) parent = @node_stack.last() element = REXML::Element.new(name, parent) attr.each{|name, value| element.add_attribute(name, value) } @node_stack.push(element) end def endElement(name) @node_stack.pop end def startCdata() @parsing_cdata = true end def endCdata() @parsing_cdata = false end def character(chars) if @parsing_cdata @node_stack.last.add(REXML::CData.new(chars, true)) else @node_stack.last.add(REXML::Text.new(chars, true)) end end def processingInstruction(target, data) @node_stack.last.add(REXML::Instruction.new(target, data)) end def comment(comment) @node_stack.last.add(REXML::Comment.new(comment)) end def startDoctypeDecl(doctypename, sysid, pubid, has_internal_subset) if pubid @node_stack.last.add(REXML::DocType.new(doctypename, "PUBLIC \"#{pubid}\" \"#{sysid}\"")) else @node_stack.last.add(REXML::DocType.new(doctypename, "SYSTEM \"#{sysid}\"")) end end def xmlDecl(version, encoding, standalone) sa_hash = {-1=>nil, 0=>"no", 1=>"yes"} @node_stack.last.add(REXML::XMLDecl.new(version, encoding, sa_hash[standalone])) end def parse(*args) @node_stack = Array.new() @doc = REXML::Document.new() @node_stack.push(@doc) super @node_stack.pop unless @node_stack.empty? raise "parse error: stack is not empty in end_document." end @doc end end if __FILE__ == $0 file = File.new(ARGV[0]) builder = REXMLBuilder.new() doc = builder.parse(file) doc.write(STDOUT, -1) end