rexml 3.2.5 → 3.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of rexml might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/NEWS.md +299 -2
- data/README.md +10 -1
- data/doc/rexml/tasks/rdoc/element.rdoc +2 -2
- data/doc/rexml/tutorial.rdoc +1358 -0
- data/lib/rexml/attribute.rb +14 -9
- data/lib/rexml/document.rb +1 -1
- data/lib/rexml/element.rb +5 -18
- data/lib/rexml/entity.rb +25 -15
- data/lib/rexml/formatters/pretty.rb +3 -3
- data/lib/rexml/functions.rb +1 -2
- data/lib/rexml/namespace.rb +8 -4
- data/lib/rexml/node.rb +8 -4
- data/lib/rexml/parseexception.rb +1 -0
- data/lib/rexml/parsers/baseparser.rb +307 -240
- data/lib/rexml/parsers/sax2parser.rb +2 -19
- data/lib/rexml/parsers/streamparser.rb +2 -2
- data/lib/rexml/parsers/treeparser.rb +9 -14
- data/lib/rexml/parsers/xpathparser.rb +136 -86
- data/lib/rexml/rexml.rb +3 -1
- data/lib/rexml/source.rb +121 -101
- data/lib/rexml/text.rb +40 -18
- data/lib/rexml/xpath_parser.rb +7 -3
- metadata +11 -39
| @@ -157,25 +157,8 @@ module REXML | |
| 157 157 | 
             
                          end
         | 
| 158 158 | 
             
                        end
         | 
| 159 159 | 
             
                      when :text
         | 
| 160 | 
            -
                         | 
| 161 | 
            -
                         | 
| 162 | 
            -
                        copy = event[1].clone
         | 
| 163 | 
            -
             | 
| 164 | 
            -
                        esub = proc { |match|
         | 
| 165 | 
            -
                          if @entities.has_key?($1)
         | 
| 166 | 
            -
                            @entities[$1].gsub(Text::REFERENCE, &esub)
         | 
| 167 | 
            -
                          else
         | 
| 168 | 
            -
                            match
         | 
| 169 | 
            -
                          end
         | 
| 170 | 
            -
                        }
         | 
| 171 | 
            -
             | 
| 172 | 
            -
                        copy.gsub!( Text::REFERENCE, &esub )
         | 
| 173 | 
            -
                        copy.gsub!( Text::NUMERICENTITY ) {|m|
         | 
| 174 | 
            -
                          m=$1
         | 
| 175 | 
            -
                          m = "0#{m}" if m[0] == ?x
         | 
| 176 | 
            -
                          [Integer(m)].pack('U*')
         | 
| 177 | 
            -
                        }
         | 
| 178 | 
            -
                        handle( :characters, copy )
         | 
| 160 | 
            +
                        unnormalized = @parser.unnormalize( event[1], @entities )
         | 
| 161 | 
            +
                        handle( :characters, unnormalized )
         | 
| 179 162 | 
             
                      when :entitydecl
         | 
| 180 163 | 
             
                        handle_entitydecl( event )
         | 
| 181 164 | 
             
                      when :processing_instruction, :comment, :attlistdecl,
         | 
| @@ -36,8 +36,8 @@ module REXML | |
| 36 36 | 
             
                        @listener.tag_end( event[1] )
         | 
| 37 37 | 
             
                        @tag_stack.pop
         | 
| 38 38 | 
             
                      when :text
         | 
| 39 | 
            -
                         | 
| 40 | 
            -
                        @listener.text(  | 
| 39 | 
            +
                        unnormalized = @parser.unnormalize( event[1] )
         | 
| 40 | 
            +
                        @listener.text( unnormalized )
         | 
| 41 41 | 
             
                      when :processing_instruction
         | 
| 42 42 | 
             
                        @listener.instruction( *event[1,2] )
         | 
| 43 43 | 
             
                      when :start_doctype
         | 
| @@ -16,7 +16,6 @@ module REXML | |
| 16 16 |  | 
| 17 17 | 
             
                  def parse
         | 
| 18 18 | 
             
                    tag_stack = []
         | 
| 19 | 
            -
                    in_doctype = false
         | 
| 20 19 | 
             
                    entities = nil
         | 
| 21 20 | 
             
                    begin
         | 
| 22 21 | 
             
                      while true
         | 
| @@ -39,17 +38,15 @@ module REXML | |
| 39 38 | 
             
                          tag_stack.pop
         | 
| 40 39 | 
             
                          @build_context = @build_context.parent
         | 
| 41 40 | 
             
                        when :text
         | 
| 42 | 
            -
                          if  | 
| 43 | 
            -
                             | 
| 44 | 
            -
             | 
| 45 | 
            -
                             | 
| 46 | 
            -
                              @build_context. | 
| 47 | 
            -
             | 
| 48 | 
            -
                               | 
| 49 | 
            -
             | 
| 50 | 
            -
             | 
| 51 | 
            -
                              )
         | 
| 52 | 
            -
                            end
         | 
| 41 | 
            +
                          if @build_context[-1].instance_of? Text
         | 
| 42 | 
            +
                            @build_context[-1] << event[1]
         | 
| 43 | 
            +
                          else
         | 
| 44 | 
            +
                            @build_context.add(
         | 
| 45 | 
            +
                              Text.new(event[1], @build_context.whitespace, nil, true)
         | 
| 46 | 
            +
                            ) unless (
         | 
| 47 | 
            +
                              @build_context.ignore_whitespace_nodes and
         | 
| 48 | 
            +
                              event[1].strip.size==0
         | 
| 49 | 
            +
                            )
         | 
| 53 50 | 
             
                          end
         | 
| 54 51 | 
             
                        when :comment
         | 
| 55 52 | 
             
                          c = Comment.new( event[1] )
         | 
| @@ -60,14 +57,12 @@ module REXML | |
| 60 57 | 
             
                        when :processing_instruction
         | 
| 61 58 | 
             
                          @build_context.add( Instruction.new( event[1], event[2] ) )
         | 
| 62 59 | 
             
                        when :end_doctype
         | 
| 63 | 
            -
                          in_doctype = false
         | 
| 64 60 | 
             
                          entities.each { |k,v| entities[k] = @build_context.entities[k].value }
         | 
| 65 61 | 
             
                          @build_context = @build_context.parent
         | 
| 66 62 | 
             
                        when :start_doctype
         | 
| 67 63 | 
             
                          doctype = DocType.new( event[1..-1], @build_context )
         | 
| 68 64 | 
             
                          @build_context = doctype
         | 
| 69 65 | 
             
                          entities = {}
         | 
| 70 | 
            -
                          in_doctype = true
         | 
| 71 66 | 
             
                        when :attlistdecl
         | 
| 72 67 | 
             
                          n = AttlistDecl.new( event[1..-1] )
         | 
| 73 68 | 
             
                          @build_context.add( n )
         | 
| @@ -1,4 +1,5 @@ | |
| 1 1 | 
             
            # frozen_string_literal: false
         | 
| 2 | 
            +
             | 
| 2 3 | 
             
            require_relative '../namespace'
         | 
| 3 4 | 
             
            require_relative '../xmltokens'
         | 
| 4 5 |  | 
| @@ -38,108 +39,143 @@ module REXML | |
| 38 39 | 
             
                    parsed
         | 
| 39 40 | 
             
                  end
         | 
| 40 41 |  | 
| 41 | 
            -
                  def abbreviate( | 
| 42 | 
            -
                     | 
| 43 | 
            -
             | 
| 44 | 
            -
                     | 
| 45 | 
            -
             | 
| 46 | 
            -
             | 
| 42 | 
            +
                  def abbreviate(path_or_parsed)
         | 
| 43 | 
            +
                    if path_or_parsed.kind_of?(String)
         | 
| 44 | 
            +
                      parsed = parse(path_or_parsed)
         | 
| 45 | 
            +
                    else
         | 
| 46 | 
            +
                      parsed = path_or_parsed
         | 
| 47 | 
            +
                    end
         | 
| 48 | 
            +
                    components = []
         | 
| 49 | 
            +
                    component = nil
         | 
| 50 | 
            +
                    while parsed.size > 0
         | 
| 51 | 
            +
                      op = parsed.shift
         | 
| 47 52 | 
             
                      case op
         | 
| 48 53 | 
             
                      when :node
         | 
| 54 | 
            +
                        component << "node()"
         | 
| 49 55 | 
             
                      when :attribute
         | 
| 50 | 
            -
                         | 
| 51 | 
            -
                         | 
| 56 | 
            +
                        component = "@"
         | 
| 57 | 
            +
                        components << component
         | 
| 52 58 | 
             
                      when :child
         | 
| 53 | 
            -
                         | 
| 59 | 
            +
                        component = ""
         | 
| 60 | 
            +
                        components << component
         | 
| 54 61 | 
             
                      when :descendant_or_self
         | 
| 55 | 
            -
                         | 
| 62 | 
            +
                        next_op = parsed[0]
         | 
| 63 | 
            +
                        if next_op == :node
         | 
| 64 | 
            +
                          parsed.shift
         | 
| 65 | 
            +
                          component = ""
         | 
| 66 | 
            +
                          components << component
         | 
| 67 | 
            +
                        else
         | 
| 68 | 
            +
                          component = "descendant-or-self::"
         | 
| 69 | 
            +
                          components << component
         | 
| 70 | 
            +
                        end
         | 
| 56 71 | 
             
                      when :self
         | 
| 57 | 
            -
                         | 
| 72 | 
            +
                        next_op = parsed[0]
         | 
| 73 | 
            +
                        if next_op == :node
         | 
| 74 | 
            +
                          parsed.shift
         | 
| 75 | 
            +
                          components << "."
         | 
| 76 | 
            +
                        else
         | 
| 77 | 
            +
                          component = "self::"
         | 
| 78 | 
            +
                          components << component
         | 
| 79 | 
            +
                        end
         | 
| 58 80 | 
             
                      when :parent
         | 
| 59 | 
            -
                         | 
| 81 | 
            +
                        next_op = parsed[0]
         | 
| 82 | 
            +
                        if next_op == :node
         | 
| 83 | 
            +
                          parsed.shift
         | 
| 84 | 
            +
                          components << ".."
         | 
| 85 | 
            +
                        else
         | 
| 86 | 
            +
                          component = "parent::"
         | 
| 87 | 
            +
                          components << component
         | 
| 88 | 
            +
                        end
         | 
| 60 89 | 
             
                      when :any
         | 
| 61 | 
            -
                         | 
| 90 | 
            +
                        component << "*"
         | 
| 62 91 | 
             
                      when :text
         | 
| 63 | 
            -
                         | 
| 92 | 
            +
                        component << "text()"
         | 
| 64 93 | 
             
                      when :following, :following_sibling,
         | 
| 65 94 | 
             
                            :ancestor, :ancestor_or_self, :descendant,
         | 
| 66 95 | 
             
                            :namespace, :preceding, :preceding_sibling
         | 
| 67 | 
            -
                         | 
| 68 | 
            -
                         | 
| 69 | 
            -
                        string << "::"
         | 
| 96 | 
            +
                        component = op.to_s.tr("_", "-") << "::"
         | 
| 97 | 
            +
                        components << component
         | 
| 70 98 | 
             
                      when :qname
         | 
| 71 | 
            -
                        prefix =  | 
| 72 | 
            -
                        name =  | 
| 73 | 
            -
                         | 
| 74 | 
            -
                         | 
| 99 | 
            +
                        prefix = parsed.shift
         | 
| 100 | 
            +
                        name = parsed.shift
         | 
| 101 | 
            +
                        component << prefix+":" if prefix.size > 0
         | 
| 102 | 
            +
                        component << name
         | 
| 75 103 | 
             
                      when :predicate
         | 
| 76 | 
            -
                         | 
| 77 | 
            -
                         | 
| 78 | 
            -
                         | 
| 104 | 
            +
                        component << '['
         | 
| 105 | 
            +
                        component << predicate_to_path(parsed.shift) {|x| abbreviate(x)}
         | 
| 106 | 
            +
                        component << ']'
         | 
| 79 107 | 
             
                      when :document
         | 
| 80 | 
            -
                         | 
| 108 | 
            +
                        components << ""
         | 
| 81 109 | 
             
                      when :function
         | 
| 82 | 
            -
                         | 
| 83 | 
            -
                         | 
| 84 | 
            -
                         | 
| 85 | 
            -
                         | 
| 110 | 
            +
                        component << parsed.shift
         | 
| 111 | 
            +
                        component << "( "
         | 
| 112 | 
            +
                        component << predicate_to_path(parsed.shift[0]) {|x| abbreviate(x)}
         | 
| 113 | 
            +
                        component << " )"
         | 
| 86 114 | 
             
                      when :literal
         | 
| 87 | 
            -
                         | 
| 115 | 
            +
                        component << quote_literal(parsed.shift)
         | 
| 88 116 | 
             
                      else
         | 
| 89 | 
            -
                         | 
| 90 | 
            -
                         | 
| 91 | 
            -
                         | 
| 92 | 
            -
                        string << ")"
         | 
| 117 | 
            +
                        component << "UNKNOWN("
         | 
| 118 | 
            +
                        component << op.inspect
         | 
| 119 | 
            +
                        component << ")"
         | 
| 93 120 | 
             
                      end
         | 
| 94 121 | 
             
                    end
         | 
| 95 | 
            -
                     | 
| 96 | 
            -
                     | 
| 122 | 
            +
                    case components
         | 
| 123 | 
            +
                    when [""]
         | 
| 124 | 
            +
                      "/"
         | 
| 125 | 
            +
                    when ["", ""]
         | 
| 126 | 
            +
                      "//"
         | 
| 127 | 
            +
                    else
         | 
| 128 | 
            +
                      components.join("/")
         | 
| 129 | 
            +
                    end
         | 
| 97 130 | 
             
                  end
         | 
| 98 131 |  | 
| 99 | 
            -
                  def expand( | 
| 100 | 
            -
                     | 
| 101 | 
            -
             | 
| 132 | 
            +
                  def expand(path_or_parsed)
         | 
| 133 | 
            +
                    if path_or_parsed.kind_of?(String)
         | 
| 134 | 
            +
                      parsed = parse(path_or_parsed)
         | 
| 135 | 
            +
                    else
         | 
| 136 | 
            +
                      parsed = path_or_parsed
         | 
| 137 | 
            +
                    end
         | 
| 138 | 
            +
                    path = ""
         | 
| 102 139 | 
             
                    document = false
         | 
| 103 | 
            -
                    while  | 
| 104 | 
            -
                      op =  | 
| 140 | 
            +
                    while parsed.size > 0
         | 
| 141 | 
            +
                      op = parsed.shift
         | 
| 105 142 | 
             
                      case op
         | 
| 106 143 | 
             
                      when :node
         | 
| 107 | 
            -
                         | 
| 144 | 
            +
                        path << "node()"
         | 
| 108 145 | 
             
                      when :attribute, :child, :following, :following_sibling,
         | 
| 109 146 | 
             
                            :ancestor, :ancestor_or_self, :descendant, :descendant_or_self,
         | 
| 110 147 | 
             
                            :namespace, :preceding, :preceding_sibling, :self, :parent
         | 
| 111 | 
            -
                         | 
| 112 | 
            -
                         | 
| 113 | 
            -
                         | 
| 148 | 
            +
                        path << "/" unless path.size == 0
         | 
| 149 | 
            +
                        path << op.to_s.tr("_", "-")
         | 
| 150 | 
            +
                        path << "::"
         | 
| 114 151 | 
             
                      when :any
         | 
| 115 | 
            -
                         | 
| 152 | 
            +
                        path << "*"
         | 
| 116 153 | 
             
                      when :qname
         | 
| 117 | 
            -
                        prefix =  | 
| 118 | 
            -
                        name =  | 
| 119 | 
            -
                         | 
| 120 | 
            -
                         | 
| 154 | 
            +
                        prefix = parsed.shift
         | 
| 155 | 
            +
                        name = parsed.shift
         | 
| 156 | 
            +
                        path << prefix+":" if prefix.size > 0
         | 
| 157 | 
            +
                        path << name
         | 
| 121 158 | 
             
                      when :predicate
         | 
| 122 | 
            -
                         | 
| 123 | 
            -
                         | 
| 124 | 
            -
                         | 
| 159 | 
            +
                        path << '['
         | 
| 160 | 
            +
                        path << predicate_to_path( parsed.shift ) { |x| expand(x) }
         | 
| 161 | 
            +
                        path << ']'
         | 
| 125 162 | 
             
                      when :document
         | 
| 126 163 | 
             
                        document = true
         | 
| 127 164 | 
             
                      else
         | 
| 128 | 
            -
                         | 
| 129 | 
            -
                         | 
| 130 | 
            -
                         | 
| 131 | 
            -
                        string << ")"
         | 
| 165 | 
            +
                        path << "UNKNOWN("
         | 
| 166 | 
            +
                        path << op.inspect
         | 
| 167 | 
            +
                        path << ")"
         | 
| 132 168 | 
             
                      end
         | 
| 133 169 | 
             
                    end
         | 
| 134 | 
            -
                     | 
| 135 | 
            -
                     | 
| 170 | 
            +
                    path = "/"+path if document
         | 
| 171 | 
            +
                    path
         | 
| 136 172 | 
             
                  end
         | 
| 137 173 |  | 
| 138 | 
            -
                  def  | 
| 139 | 
            -
                     | 
| 140 | 
            -
                    case  | 
| 174 | 
            +
                  def predicate_to_path(parsed, &block)
         | 
| 175 | 
            +
                    path = ""
         | 
| 176 | 
            +
                    case parsed[0]
         | 
| 141 177 | 
             
                    when :and, :or, :mult, :plus, :minus, :neq, :eq, :lt, :gt, :lteq, :gteq, :div, :mod, :union
         | 
| 142 | 
            -
                      op =  | 
| 178 | 
            +
                      op = parsed.shift
         | 
| 143 179 | 
             
                      case op
         | 
| 144 180 | 
             
                      when :eq
         | 
| 145 181 | 
             
                        op = "="
         | 
| @@ -156,36 +192,50 @@ module REXML | |
| 156 192 | 
             
                      when :union
         | 
| 157 193 | 
             
                        op = "|"
         | 
| 158 194 | 
             
                      end
         | 
| 159 | 
            -
                      left =  | 
| 160 | 
            -
                      right =  | 
| 161 | 
            -
                       | 
| 162 | 
            -
                       | 
| 163 | 
            -
                       | 
| 164 | 
            -
                       | 
| 165 | 
            -
                       | 
| 166 | 
            -
                      string << right
         | 
| 167 | 
            -
                      string << " "
         | 
| 195 | 
            +
                      left = predicate_to_path( parsed.shift, &block )
         | 
| 196 | 
            +
                      right = predicate_to_path( parsed.shift, &block )
         | 
| 197 | 
            +
                      path << left
         | 
| 198 | 
            +
                      path << " "
         | 
| 199 | 
            +
                      path << op.to_s
         | 
| 200 | 
            +
                      path << " "
         | 
| 201 | 
            +
                      path << right
         | 
| 168 202 | 
             
                    when :function
         | 
| 169 | 
            -
                       | 
| 170 | 
            -
                      name =  | 
| 171 | 
            -
                       | 
| 172 | 
            -
                       | 
| 173 | 
            -
                       | 
| 174 | 
            -
             | 
| 203 | 
            +
                      parsed.shift
         | 
| 204 | 
            +
                      name = parsed.shift
         | 
| 205 | 
            +
                      path << name
         | 
| 206 | 
            +
                      path << "("
         | 
| 207 | 
            +
                      parsed.shift.each_with_index do |argument, i|
         | 
| 208 | 
            +
                        path << ", " if i > 0
         | 
| 209 | 
            +
                        path << predicate_to_path(argument, &block)
         | 
| 210 | 
            +
                      end
         | 
| 211 | 
            +
                      path << ")"
         | 
| 175 212 | 
             
                    when :literal
         | 
| 176 | 
            -
                       | 
| 177 | 
            -
                       | 
| 178 | 
            -
                      string << path.shift.inspect
         | 
| 179 | 
            -
                      string << " "
         | 
| 213 | 
            +
                      parsed.shift
         | 
| 214 | 
            +
                      path << quote_literal(parsed.shift)
         | 
| 180 215 | 
             
                    else
         | 
| 181 | 
            -
                       | 
| 182 | 
            -
                      string << yield( path )
         | 
| 183 | 
            -
                      string << " "
         | 
| 216 | 
            +
                      path << yield( parsed )
         | 
| 184 217 | 
             
                    end
         | 
| 185 | 
            -
                    return  | 
| 218 | 
            +
                    return path.squeeze(" ")
         | 
| 186 219 | 
             
                  end
         | 
| 220 | 
            +
                  # For backward compatibility
         | 
| 221 | 
            +
                  alias_method :preciate_to_string, :predicate_to_path
         | 
| 187 222 |  | 
| 188 223 | 
             
                  private
         | 
| 224 | 
            +
                  def quote_literal( literal )
         | 
| 225 | 
            +
                    case literal
         | 
| 226 | 
            +
                    when String
         | 
| 227 | 
            +
                      # XPath 1.0 does not support escape characters.
         | 
| 228 | 
            +
                      # Assumes literal does not contain both single and double quotes.
         | 
| 229 | 
            +
                      if literal.include?("'")
         | 
| 230 | 
            +
                        "\"#{literal}\""
         | 
| 231 | 
            +
                      else
         | 
| 232 | 
            +
                        "'#{literal}'"
         | 
| 233 | 
            +
                      end
         | 
| 234 | 
            +
                    else
         | 
| 235 | 
            +
                      literal.inspect
         | 
| 236 | 
            +
                    end
         | 
| 237 | 
            +
                  end
         | 
| 238 | 
            +
             | 
| 189 239 | 
             
                  #LocationPath
         | 
| 190 240 | 
             
                  #  | RelativeLocationPath
         | 
| 191 241 | 
             
                  #  | '/' RelativeLocationPath?
         | 
    
        data/lib/rexml/rexml.rb
    CHANGED
    
    | @@ -26,10 +26,12 @@ | |
| 26 26 | 
             
            # - REXML::Document.
         | 
| 27 27 | 
             
            # - REXML::Element.
         | 
| 28 28 | 
             
            #
         | 
| 29 | 
            +
            # There's also an {REXML tutorial}[doc/rexml/tutorial_rdoc.html].
         | 
| 30 | 
            +
            #
         | 
| 29 31 | 
             
            module REXML
         | 
| 30 32 | 
             
              COPYRIGHT = "Copyright © 2001-2008 Sean Russell <ser@germane-software.com>"
         | 
| 31 33 | 
             
              DATE = "2008/019"
         | 
| 32 | 
            -
              VERSION = "3.2 | 
| 34 | 
            +
              VERSION = "3.3.2"
         | 
| 33 35 | 
             
              REVISION = ""
         | 
| 34 36 |  | 
| 35 37 | 
             
              Copyright = COPYRIGHT
         |