@@ -181,7 +181,8 @@ def stream=( source )
181
181
@tags = [ ]
182
182
@stack = [ ]
183
183
@entities = [ ]
184
- @nsstack = [ ]
184
+ @namespaces = { }
185
+ @namespaces_restore_stack = [ ]
185
186
end
186
187
187
188
def position
@@ -285,7 +286,6 @@ def pull_event
285
286
@source . position = start_position
286
287
raise REXML ::ParseException . new ( message , @source )
287
288
end
288
- @nsstack . unshift ( Set . new )
289
289
name = parse_name ( base_error_message )
290
290
if @source . match ( /\s *\[ /um , true )
291
291
id = [ nil , nil , nil ]
@@ -379,7 +379,7 @@ def pull_event
379
379
val = attdef [ 4 ] if val == "#FIXED "
380
380
pairs [ attdef [ 0 ] ] = val
381
381
if attdef [ 0 ] =~ /^xmlns:(.*)/
382
- @nsstack [ 0 ] << $1
382
+ @namespaces [ $1 ] = val
383
383
end
384
384
end
385
385
end
@@ -432,7 +432,7 @@ def pull_event
432
432
# here explicitly.
433
433
@source . ensure_buffer
434
434
if @source . match ( "/" , true )
435
- @nsstack . shift
435
+ @namespaces_restore_stack . pop
436
436
last_tag = @tags . pop
437
437
md = @source . match ( Private ::CLOSE_PATTERN , true )
438
438
if md and !last_tag
@@ -477,18 +477,18 @@ def pull_event
477
477
@document_status = :in_element
478
478
@prefixes . clear
479
479
@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 )
482
482
# Verify that all of the prefixes have been defined
483
483
for prefix in @prefixes
484
- unless @nsstack . find { | k | k . member ?( prefix ) }
484
+ unless @namespaces . key ?( prefix )
485
485
raise UndefinedNamespaceException . new ( prefix , @source , self )
486
486
end
487
487
end
488
488
489
489
if closed
490
490
@closed = tag
491
- @nsstack . shift
491
+ pop_namespaces_restore
492
492
else
493
493
if @tags . empty? and @have_root
494
494
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 )
599
599
end
600
600
601
601
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
602
627
603
628
def record_entity_expansion ( delta = 1 )
604
629
@entity_expansion_count += delta
@@ -727,7 +752,7 @@ def process_instruction
727
752
[ :processing_instruction , name , content ]
728
753
end
729
754
730
- def parse_attributes ( prefixes , curr_ns )
755
+ def parse_attributes ( prefixes )
731
756
attributes = { }
732
757
closed = false
733
758
while true
@@ -770,7 +795,7 @@ def parse_attributes(prefixes, curr_ns)
770
795
"(http://www.w3.org/TR/REC-xml-names/#ns-decl)"
771
796
raise REXML ::ParseException . new ( msg , @source , self )
772
797
end
773
- curr_ns << local_part
798
+ add_namespace ( local_part , value )
774
799
elsif prefix
775
800
prefixes << prefix unless prefix == "xml"
776
801
end
0 commit comments