/tools/Ruby/lib/ruby/1.8/rexml/parsers/treeparser.rb

http://github.com/agross/netopenspace · Ruby · 97 lines · 92 code · 3 blank · 2 comment · 4 complexity · e4ba711b20e726c25c10f36ee8470ff6 MD5 · raw file

  1. require 'rexml/validation/validationexception'
  2. require 'rexml/undefinednamespaceexception'
  3. module REXML
  4. module Parsers
  5. class TreeParser
  6. def initialize( source, build_context = Document.new )
  7. @build_context = build_context
  8. @parser = Parsers::BaseParser.new( source )
  9. end
  10. def add_listener( listener )
  11. @parser.add_listener( listener )
  12. end
  13. def parse
  14. tag_stack = []
  15. in_doctype = false
  16. entities = nil
  17. begin
  18. while true
  19. event = @parser.pull
  20. #STDERR.puts "TREEPARSER GOT #{event.inspect}"
  21. case event[0]
  22. when :end_document
  23. unless tag_stack.empty?
  24. #raise ParseException.new("No close tag for #{tag_stack.inspect}")
  25. raise ParseException.new("No close tag for #{@build_context.xpath}")
  26. end
  27. return
  28. when :start_element
  29. tag_stack.push(event[1])
  30. el = @build_context = @build_context.add_element( event[1], event[2] )
  31. when :end_element
  32. tag_stack.pop
  33. @build_context = @build_context.parent
  34. when :text
  35. if not in_doctype
  36. if @build_context[-1].instance_of? Text
  37. @build_context[-1] << event[1]
  38. else
  39. @build_context.add(
  40. Text.new(event[1], @build_context.whitespace, nil, true)
  41. ) unless (
  42. @build_context.ignore_whitespace_nodes and
  43. event[1].strip.size==0
  44. )
  45. end
  46. end
  47. when :comment
  48. c = Comment.new( event[1] )
  49. @build_context.add( c )
  50. when :cdata
  51. c = CData.new( event[1] )
  52. @build_context.add( c )
  53. when :processing_instruction
  54. @build_context.add( Instruction.new( event[1], event[2] ) )
  55. when :end_doctype
  56. in_doctype = false
  57. entities.each { |k,v| entities[k] = @build_context.entities[k].value }
  58. @build_context = @build_context.parent
  59. when :start_doctype
  60. doctype = DocType.new( event[1..-1], @build_context )
  61. @build_context = doctype
  62. entities = {}
  63. in_doctype = true
  64. when :attlistdecl
  65. n = AttlistDecl.new( event[1..-1] )
  66. @build_context.add( n )
  67. when :externalentity
  68. n = ExternalEntity.new( event[1] )
  69. @build_context.add( n )
  70. when :elementdecl
  71. n = ElementDecl.new( event[1] )
  72. @build_context.add(n)
  73. when :entitydecl
  74. entities[ event[1] ] = event[2] unless event[2] =~ /PUBLIC|SYSTEM/
  75. @build_context.add(Entity.new(event))
  76. when :notationdecl
  77. n = NotationDecl.new( *event[1..-1] )
  78. @build_context.add( n )
  79. when :xmldecl
  80. x = XMLDecl.new( event[1], event[2], event[3] )
  81. @build_context.add( x )
  82. end
  83. end
  84. rescue REXML::Validation::ValidationException
  85. raise
  86. rescue REXML::UndefinedNamespaceException
  87. raise
  88. rescue
  89. raise ParseException.new( $!.message, @parser.source, @parser, $! )
  90. end
  91. end
  92. end
  93. end
  94. end