Upgrade to latest REXML

Sync with REXML svn.
This commit is contained in:
Jacques Distler 2008-04-12 18:56:02 -05:00
parent 6d46e16ee1
commit 1d5faf4a84
8 changed files with 124 additions and 121 deletions

View file

@ -17,6 +17,8 @@ module REXML
attr_writer :normalized attr_writer :normalized
PATTERN = /\s*(#{NAME_STR})\s*=\s*(["'])(.*?)\2/um PATTERN = /\s*(#{NAME_STR})\s*=\s*(["'])(.*?)\2/um
NEEDS_A_SECOND_CHECK = /(<|&((#{Entity::NAME});|(#0*((?:\d+)|(?:x[a-fA-F0-9]+)));)?)/um
# Constructor. # Constructor.
# FIXME: The parser doesn't catch illegal characters in attributes # FIXME: The parser doesn't catch illegal characters in attributes
# #

View file

@ -10,64 +10,65 @@ require "rexml/output"
require "rexml/parsers/baseparser" require "rexml/parsers/baseparser"
require "rexml/parsers/streamparser" require "rexml/parsers/streamparser"
require "rexml/parsers/treeparser" require "rexml/parsers/treeparser"
require "rexml/formatters/transitive"
module REXML module REXML
# Represents a full XML document, including PIs, a doctype, etc. A # Represents a full XML document, including PIs, a doctype, etc. A
# Document has a single child that can be accessed by root(). # Document has a single child that can be accessed by root().
# Note that if you want to have an XML declaration written for a document # Note that if you want to have an XML declaration written for a document
# you create, you must add one; REXML documents do not write a default # you create, you must add one; REXML documents do not write a default
# declaration for you. See |DECLARATION| and |write|. # declaration for you. See |DECLARATION| and |write|.
class Document < Element class Document < Element
# A convenient default XML declaration. If you want an XML declaration, # A convenient default XML declaration. If you want an XML declaration,
# the easiest way to add one is mydoc << Document::DECLARATION # the easiest way to add one is mydoc << Document::DECLARATION
# +DEPRECATED+ # +DEPRECATED+
# Use: mydoc << XMLDecl.default # Use: mydoc << XMLDecl.default
DECLARATION = XMLDecl.default DECLARATION = XMLDecl.default
# Constructor # Constructor
# @param source if supplied, must be a Document, String, or IO. # @param source if supplied, must be a Document, String, or IO.
# Documents have their context and Element attributes cloned. # Documents have their context and Element attributes cloned.
# Strings are expected to be valid XML documents. IOs are expected # Strings are expected to be valid XML documents. IOs are expected
# to be sources of valid XML documents. # to be sources of valid XML documents.
# @param context if supplied, contains the context of the document; # @param context if supplied, contains the context of the document;
# this should be a Hash. # this should be a Hash.
def initialize( source = nil, context = {} ) def initialize( source = nil, context = {} )
super() super()
@context = context @context = context
return if source.nil? return if source.nil?
if source.kind_of? Document if source.kind_of? Document
@context = source.context @context = source.context
super source super source
else else
build( source ) build( source )
end end
end end
def node_type def node_type
:document :document
end end
# Should be obvious # Should be obvious
def clone def clone
Document.new self Document.new self
end end
# According to the XML spec, a root node has no expanded name # According to the XML spec, a root node has no expanded name
def expanded_name def expanded_name
'' ''
#d = doc_type #d = doc_type
#d ? d.name : "UNDEFINED" #d ? d.name : "UNDEFINED"
end end
alias :name :expanded_name alias :name :expanded_name
# We override this, because XMLDecls and DocTypes must go at the start # We override this, because XMLDecls and DocTypes must go at the start
# of the document # of the document
def add( child ) def add( child )
if child.kind_of? XMLDecl if child.kind_of? XMLDecl
@children.unshift child @children.unshift child
child.parent = self child.parent = self
elsif child.kind_of? DocType elsif child.kind_of? DocType
# Find first Element or DocType node and insert the decl right # Find first Element or DocType node and insert the decl right
# before it. If there is no such node, just insert the child at the # before it. If there is no such node, just insert the child at the
# end. If there is a child and it is an DocType, then replace it. # end. If there is a child and it is an DocType, then replace it.
@ -85,60 +86,60 @@ module REXML
else # Insert at end of list else # Insert at end of list
@children[insert_before_index] = child @children[insert_before_index] = child
end end
child.parent = self child.parent = self
else else
rv = super rv = super
raise "attempted adding second root element to document" if @elements.size > 1 raise "attempted adding second root element to document" if @elements.size > 1
rv rv
end end
end end
alias :<< :add alias :<< :add
def add_element(arg=nil, arg2=nil) def add_element(arg=nil, arg2=nil)
rv = super rv = super
raise "attempted adding second root element to document" if @elements.size > 1 raise "attempted adding second root element to document" if @elements.size > 1
rv rv
end end
# @return the root Element of the document, or nil if this document # @return the root Element of the document, or nil if this document
# has no children. # has no children.
def root def root
elements[1] elements[1]
#self #self
#@children.find { |item| item.kind_of? Element } #@children.find { |item| item.kind_of? Element }
end end
# @return the DocType child of the document, if one exists, # @return the DocType child of the document, if one exists,
# and nil otherwise. # and nil otherwise.
def doctype def doctype
@children.find { |item| item.kind_of? DocType } @children.find { |item| item.kind_of? DocType }
end end
# @return the XMLDecl of this document; if no XMLDecl has been # @return the XMLDecl of this document; if no XMLDecl has been
# set, the default declaration is returned. # set, the default declaration is returned.
def xml_decl def xml_decl
rv = @children[0] rv = @children[0]
return rv if rv.kind_of? XMLDecl return rv if rv.kind_of? XMLDecl
rv = @children.unshift(XMLDecl.default)[0] rv = @children.unshift(XMLDecl.default)[0]
end end
# @return the XMLDecl version of this document as a String. # @return the XMLDecl version of this document as a String.
# If no XMLDecl has been set, returns the default version. # If no XMLDecl has been set, returns the default version.
def version def version
xml_decl().version xml_decl().version
end end
# @return the XMLDecl encoding of this document as a String. # @return the XMLDecl encoding of this document as a String.
# If no XMLDecl has been set, returns the default encoding. # If no XMLDecl has been set, returns the default encoding.
def encoding def encoding
xml_decl().encoding xml_decl().encoding
end end
# @return the XMLDecl standalone value of this document as a String. # @return the XMLDecl standalone value of this document as a String.
# If no XMLDecl has been set, returns the default setting. # If no XMLDecl has been set, returns the default setting.
def stand_alone? def stand_alone?
xml_decl().stand_alone? xml_decl().stand_alone?
end end
# Write the XML tree out, optionally with indent. This writes out the # Write the XML tree out, optionally with indent. This writes out the
# entire XML document, including XML declarations, doctype declarations, # entire XML document, including XML declarations, doctype declarations,
@ -184,25 +185,25 @@ module REXML
output = Output.new( output, xml_decl.encoding ) output = Output.new( output, xml_decl.encoding )
end end
formatter = if indent > -1 formatter = if indent > -1
if trans if transitive
REXML::Formatters::Transitive.new( indent, ie_hack ) REXML::Formatters::Transitive.new( indent, ie_hack )
else else
REXML::Formatters::Pretty.new( indent, ie_hack ) REXML::Formatters::Pretty.new( indent, ie_hack )
end end
else else
REXML::Formatters::Default.new( ie_hack ) REXML::Formatters::Default.new( ie_hack )
end end
formatter.write( self, output ) formatter.write( self, output )
end
def Document::parse_stream( source, listener )
Parsers::StreamParser.new( source, listener ).parse
end
private
def build( source )
Parsers::TreeParser.new( source, self ).parse
end
end end
def Document::parse_stream( source, listener )
Parsers::StreamParser.new( source, listener ).parse
end
private
def build( source )
Parsers::TreeParser.new( source, self ).parse
end
end
end end

View file

@ -13,8 +13,8 @@ module REXML
rescue LoadError rescue LoadError
require 'nkf' require 'nkf'
SJISTOU8 = '-Swm0' SJISTOU8 = '-Swm0x'
U8TOSJIS = '-Wsm0' U8TOSJIS = '-Wsm0x'
def decode_sjis(str) def decode_sjis(str)
NKF.nkf(SJISTOU8, str) NKF.nkf(SJISTOU8, str)

View file

@ -12,8 +12,9 @@ module REXML
# formatted. Since this formatter does not alter whitespace nodes, the # formatted. Since this formatter does not alter whitespace nodes, the
# results of formatting already formatted XML will be odd. # results of formatting already formatted XML will be odd.
class Transitive < Default class Transitive < Default
def initialize( indentation=2 ) def initialize( indentation=2, ie_hack=false )
@indentation = indentation @indentation = indentation
@ie_hack = ie_hack
@level = 0 @level = 0
end end
@ -29,6 +30,7 @@ module REXML
output << "\n" output << "\n"
output << ' '*@level output << ' '*@level
if node.children.empty? if node.children.empty?
output << " " if @ie_hack
output << "/" output << "/"
else else
output << ">" output << ">"

View file

@ -482,7 +482,7 @@ module REXML
rv.gsub!( /\r\n?/, "\n" ) rv.gsub!( /\r\n?/, "\n" )
matches = rv.scan( REFERENCE_RE ) matches = rv.scan( REFERENCE_RE )
return rv if matches.size == 0 return rv if matches.size == 0
rv.gsub!( /&#0*((?:\d+)|(?:x[a-fA-F0-9]+));/ ) {|m| rv.gsub!( /&#0*((?:\d+)|(?:x[a-fA-F0-9]+));/ ) {
m=$1 m=$1
m = "0#{m}" if m[0] == ?x m = "0#{m}" if m[0] == ?x
[Integer(m)].pack('U*') [Integer(m)].pack('U*')

View file

@ -170,15 +170,12 @@ module REXML
rest = path[ind+1..-1] rest = path[ind+1..-1]
# have to change 'a [=<>] b [=<>] c' into 'a [=<>] b and b [=<>] c' # have to change 'a [=<>] b [=<>] c' into 'a [=<>] b and b [=<>] c'
predicate.gsub!( /([^\s(and)(or)<>=]+)\s*([<>=])\s*([^\s(and)(or)<>=]+)\s*([<>=])\s*([^\s(and)(or)<>=]+)/u ) { predicate.gsub!( /([^\s(and)(or)<>=]+)\s*([<>=])\s*([^\s(and)(or)<>=]+)\s*([<>=])\s*([^\s(and)(or)<>=]+)/u,
"#$1 #$2 #$3 and #$3 #$4 #$5" '\1 \2 \3 and \3 \4 \5' )
}
# Let's do some Ruby trickery to avoid some work: # Let's do some Ruby trickery to avoid some work:
predicate.gsub!( /&/u, "&&" ) predicate.gsub!( /&/u, "&&" )
predicate.gsub!( /=/u, "==" ) predicate.gsub!( /=/u, "==" )
predicate.gsub!( /@(\w[-\w.]*)/u ) { predicate.gsub!( /@(\w[-\w.]*)/u, 'attribute("\1")' )
"attribute(\"#$1\")"
}
predicate.gsub!( /\bmod\b/u, "%" ) predicate.gsub!( /\bmod\b/u, "%" )
predicate.gsub!( /\b(\w[-\w.]*\()/u ) { predicate.gsub!( /\b(\w[-\w.]*\()/u ) {
fname = $1 fname = $1

View file

@ -11,8 +11,8 @@
# #
# Main page:: http://www.germane-software.com/software/rexml # Main page:: http://www.germane-software.com/software/rexml
# Author:: Sean Russell <serATgermaneHYPHENsoftwareDOTcom> # Author:: Sean Russell <serATgermaneHYPHENsoftwareDOTcom>
# Version:: 3.1.7.2 # Version:: 3.1.7.4
# Date:: 2007/275 # Date:: 2008/100
# #
# This API documentation can be downloaded from the REXML home page, or can # This API documentation can be downloaded from the REXML home page, or can
# be accessed online[http://www.germane-software.com/software/rexml_doc] # be accessed online[http://www.germane-software.com/software/rexml_doc]
@ -21,10 +21,10 @@
# or can be accessed # or can be accessed
# online[http://www.germane-software.com/software/rexml/docs/tutorial.html] # online[http://www.germane-software.com/software/rexml/docs/tutorial.html]
module REXML module REXML
COPYRIGHT = "Copyright © 2001-2007 Sean Russell <ser@germane-software.com>" COPYRIGHT = "Copyright © 2001-2008 Sean Russell <ser@germane-software.com>"
DATE = "2007/275" DATE = "2008/100"
VERSION = "3.1.7.2" VERSION = "3.1.7.4"
REVISION = "$Revision: 1284 $".gsub(/\$Revision:|\$/,'').strip REVISION = "$Revision: 1312 $".gsub(/\$Revision:|\$/,'').strip
Copyright = COPYRIGHT Copyright = COPYRIGHT
Version = VERSION Version = VERSION

View file

@ -50,7 +50,7 @@ module REXML
| \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
| [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
| \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
)*$/x; )*$/nx;
end end
# Constructor # Constructor
@ -139,7 +139,7 @@ module REXML
end end
end end
else else
string.scan(/[\x00-\x7F]|[\x80-\xBF][\xC0-\xF0]*|[\xC0-\xF0]/) do |c| string.scan(/[\x00-\x7F]|[\x80-\xBF][\xC0-\xF0]*|[\xC0-\xF0]/n) do |c|
case c.unpack('U') case c.unpack('U')
when *VALID_CHAR when *VALID_CHAR
else else
@ -345,7 +345,7 @@ module REXML
copy.gsub!( SETUTITSBUS[2], SLAICEPS[2] ) copy.gsub!( SETUTITSBUS[2], SLAICEPS[2] )
copy.gsub!( SETUTITSBUS[3], SLAICEPS[3] ) copy.gsub!( SETUTITSBUS[3], SLAICEPS[3] )
copy.gsub!( SETUTITSBUS[4], SLAICEPS[4] ) copy.gsub!( SETUTITSBUS[4], SLAICEPS[4] )
copy.gsub!( /&#0*((?:\d+)|(?:x[a-f0-9]+));/ ) {|m| copy.gsub!( /&#0*((?:\d+)|(?:x[a-f0-9]+));/ ) {
m=$1 m=$1
#m='0' if m=='' #m='0' if m==''
m = "0#{m}" if m[0] == ?x m = "0#{m}" if m[0] == ?x
@ -380,7 +380,8 @@ module REXML
# Unescapes all possible entities # Unescapes all possible entities
def Text::unnormalize( string, doctype=nil, filter=nil, illegal=nil ) def Text::unnormalize( string, doctype=nil, filter=nil, illegal=nil )
string.gsub( /\r\n?/, "\n" ).gsub( REFERENCE ) { |ref| string.gsub( /\r\n?/, "\n" ).gsub( REFERENCE ) {
ref = $&
if ref[1] == ?# if ref[1] == ?#
if ref[2] == ?x if ref[2] == ?x
[ref[3...-1].to_i(16)].pack('U*') [ref[3...-1].to_i(16)].pack('U*')