Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit cb15858

Browse filesBrowse files
committed
parser: keep the current namespaces instead of stack of Set
It improves namespace resolution performance for deep element.
1 parent 2b47b16 commit cb15858
Copy full SHA for cb15858

File tree

Expand file treeCollapse file tree

1 file changed

+35
-10
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+35
-10
lines changed

‎lib/rexml/parsers/baseparser.rb

Copy file name to clipboardExpand all lines: lib/rexml/parsers/baseparser.rb
+35-10Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,8 @@ def stream=( source )
181181
@tags = []
182182
@stack = []
183183
@entities = []
184-
@nsstack = []
184+
@namespaces = {}
185+
@namespaces_restore_stack = []
185186
end
186187

187188
def position
@@ -285,7 +286,6 @@ def pull_event
285286
@source.position = start_position
286287
raise REXML::ParseException.new(message, @source)
287288
end
288-
@nsstack.unshift(Set.new)
289289
name = parse_name(base_error_message)
290290
if @source.match(/\s*\[/um, true)
291291
id = [nil, nil, nil]
@@ -379,7 +379,7 @@ def pull_event
379379
val = attdef[4] if val == "#FIXED "
380380
pairs[attdef[0]] = val
381381
if attdef[0] =~ /^xmlns:(.*)/
382-
@nsstack[0] << $1
382+
@namespaces[$1] = val
383383
end
384384
end
385385
end
@@ -432,7 +432,7 @@ def pull_event
432432
# here explicitly.
433433
@source.ensure_buffer
434434
if @source.match("/", true)
435-
@nsstack.shift
435+
@namespaces_restore_stack.pop
436436
last_tag = @tags.pop
437437
md = @source.match(Private::CLOSE_PATTERN, true)
438438
if md and !last_tag
@@ -477,18 +477,18 @@ def pull_event
477477
@document_status = :in_element
478478
@prefixes.clear
479479
@prefixes << md[2] if md[2]
480-
@nsstack.unshift(curr_ns=Set.new)
481-
attributes, closed = parse_attributes(@prefixes, curr_ns)
480+
push_namespaces_restore
481+
attributes, closed = parse_attributes(@prefixes)
482482
# Verify that all of the prefixes have been defined
483483
for prefix in @prefixes
484-
unless @nsstack.find{|k| k.member?(prefix)}
484+
unless @namespaces.key?(prefix)
485485
raise UndefinedNamespaceException.new(prefix,@source,self)
486486
end
487487
end
488488

489489
if closed
490490
@closed = tag
491-
@nsstack.shift
491+
pop_namespaces_restore
492492
else
493493
if @tags.empty? and @have_root
494494
raise ParseException.new("Malformed XML: Extra tag at the end of the document (got '<#{tag}')", @source)
@@ -599,6 +599,31 @@ def unnormalize( string, entities=nil, filter=nil )
599599
end
600600

601601
private
602+
def add_namespace(prefix, uri)
603+
@namespaces_restore_stack.last[prefix] = @namespaces[prefix]
604+
if uri.nil?
605+
@namespaces.delete(prefix)
606+
else
607+
@namespaces[prefix] = uri
608+
end
609+
end
610+
611+
def push_namespaces_restore
612+
namespaces_restore = {}
613+
@namespaces_restore_stack.push(namespaces_restore)
614+
namespaces_restore
615+
end
616+
617+
def pop_namespaces_restore
618+
namespaces_restore = @namespaces_restore_stack.pop
619+
namespaces_restore.each do |prefix, uri|
620+
if uri.nil?
621+
@namespaces.delete(prefix)
622+
else
623+
@namespaces[prefix] = uri
624+
end
625+
end
626+
end
602627

603628
def record_entity_expansion(delta=1)
604629
@entity_expansion_count += delta
@@ -727,7 +752,7 @@ def process_instruction
727752
[:processing_instruction, name, content]
728753
end
729754

730-
def parse_attributes(prefixes, curr_ns)
755+
def parse_attributes(prefixes)
731756
attributes = {}
732757
closed = false
733758
while true
@@ -770,7 +795,7 @@ def parse_attributes(prefixes, curr_ns)
770795
"(http://www.w3.org/TR/REC-xml-names/#ns-decl)"
771796
raise REXML::ParseException.new( msg, @source, self)
772797
end
773-
curr_ns << local_part
798+
add_namespace(local_part, value)
774799
elsif prefix
775800
prefixes << prefix unless prefix == "xml"
776801
end

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.