mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* lib/xmlrpc, lib/rexml, test/ruby/test_array.rb,
test/ruby/test_unicode_escape.rb, test/scanf/test_scanf.rb, test/rss/rss-assertions.rb: fix indentation to remove warning. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@19657 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
952385b712
commit
46321a9a31
40 changed files with 2198 additions and 2192 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
Wed Oct 1 22:43:59 2008 Yusuke Endoh <mame@tsg.ne.jp>
|
||||||
|
|
||||||
|
* lib/xmlrpc, lib/rexml, test/ruby/test_array.rb,
|
||||||
|
test/ruby/test_unicode_escape.rb, test/scanf/test_scanf.rb,
|
||||||
|
test/rss/rss-assertions.rb: fix indentation to remove warning.
|
||||||
|
|
||||||
Wed Oct 1 21:36:35 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Wed Oct 1 21:36:35 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* gc.c (rb_gc_call_finalizer_at_exit): finalize deferred IO and Data.
|
* gc.c (rb_gc_call_finalizer_at_exit): finalize deferred IO and Data.
|
||||||
|
|
|
@ -3,60 +3,60 @@ require 'rexml/child'
|
||||||
require 'rexml/source'
|
require 'rexml/source'
|
||||||
|
|
||||||
module REXML
|
module REXML
|
||||||
# This class needs:
|
# This class needs:
|
||||||
# * Documentation
|
# * Documentation
|
||||||
# * Work! Not all types of attlists are intelligently parsed, so we just
|
# * Work! Not all types of attlists are intelligently parsed, so we just
|
||||||
# spew back out what we get in. This works, but it would be better if
|
# spew back out what we get in. This works, but it would be better if
|
||||||
# we formatted the output ourselves.
|
# we formatted the output ourselves.
|
||||||
#
|
#
|
||||||
# AttlistDecls provide *just* enough support to allow namespace
|
# AttlistDecls provide *just* enough support to allow namespace
|
||||||
# declarations. If you need some sort of generalized support, or have an
|
# declarations. If you need some sort of generalized support, or have an
|
||||||
# interesting idea about how to map the hideous, terrible design of DTD
|
# interesting idea about how to map the hideous, terrible design of DTD
|
||||||
# AttlistDecls onto an intuitive Ruby interface, let me know. I'm desperate
|
# AttlistDecls onto an intuitive Ruby interface, let me know. I'm desperate
|
||||||
# for anything to make DTDs more palateable.
|
# for anything to make DTDs more palateable.
|
||||||
class AttlistDecl < Child
|
class AttlistDecl < Child
|
||||||
include Enumerable
|
include Enumerable
|
||||||
|
|
||||||
# What is this? Got me.
|
# What is this? Got me.
|
||||||
attr_reader :element_name
|
attr_reader :element_name
|
||||||
|
|
||||||
# Create an AttlistDecl, pulling the information from a Source. Notice
|
# Create an AttlistDecl, pulling the information from a Source. Notice
|
||||||
# that this isn't very convenient; to create an AttlistDecl, you basically
|
# that this isn't very convenient; to create an AttlistDecl, you basically
|
||||||
# have to format it yourself, and then have the initializer parse it.
|
# have to format it yourself, and then have the initializer parse it.
|
||||||
# Sorry, but for the forseeable future, DTD support in REXML is pretty
|
# Sorry, but for the forseeable future, DTD support in REXML is pretty
|
||||||
# weak on convenience. Have I mentioned how much I hate DTDs?
|
# weak on convenience. Have I mentioned how much I hate DTDs?
|
||||||
def initialize(source)
|
def initialize(source)
|
||||||
super()
|
super()
|
||||||
if (source.kind_of? Array)
|
if (source.kind_of? Array)
|
||||||
@element_name, @pairs, @contents = *source
|
@element_name, @pairs, @contents = *source
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Access the attlist attribute/value pairs.
|
# Access the attlist attribute/value pairs.
|
||||||
# value = attlist_decl[ attribute_name ]
|
# value = attlist_decl[ attribute_name ]
|
||||||
def [](key)
|
def [](key)
|
||||||
@pairs[key]
|
@pairs[key]
|
||||||
end
|
end
|
||||||
|
|
||||||
# Whether an attlist declaration includes the given attribute definition
|
# Whether an attlist declaration includes the given attribute definition
|
||||||
# if attlist_decl.include? "xmlns:foobar"
|
# if attlist_decl.include? "xmlns:foobar"
|
||||||
def include?(key)
|
def include?(key)
|
||||||
@pairs.keys.include? key
|
@pairs.keys.include? key
|
||||||
end
|
end
|
||||||
|
|
||||||
# Iterate over the key/value pairs:
|
# Iterate over the key/value pairs:
|
||||||
# attlist_decl.each { |attribute_name, attribute_value| ... }
|
# attlist_decl.each { |attribute_name, attribute_value| ... }
|
||||||
def each(&block)
|
def each(&block)
|
||||||
@pairs.each(&block)
|
@pairs.each(&block)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Write out exactly what we got in.
|
# Write out exactly what we got in.
|
||||||
def write out, indent=-1
|
def write out, indent=-1
|
||||||
out << @contents
|
out << @contents
|
||||||
end
|
end
|
||||||
|
|
||||||
def node_type
|
def node_type
|
||||||
:attlistdecl
|
:attlistdecl
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,24 +2,24 @@ require "rexml/namespace"
|
||||||
require 'rexml/text'
|
require 'rexml/text'
|
||||||
|
|
||||||
module REXML
|
module REXML
|
||||||
# Defines an Element Attribute; IE, a attribute=value pair, as in:
|
# Defines an Element Attribute; IE, a attribute=value pair, as in:
|
||||||
# <element attribute="value"/>. Attributes can be in their own
|
# <element attribute="value"/>. Attributes can be in their own
|
||||||
# namespaces. General users of REXML will not interact with the
|
# namespaces. General users of REXML will not interact with the
|
||||||
# Attribute class much.
|
# Attribute class much.
|
||||||
class Attribute
|
class Attribute
|
||||||
include Node
|
include Node
|
||||||
include Namespace
|
include Namespace
|
||||||
|
|
||||||
# The element to which this attribute belongs
|
# The element to which this attribute belongs
|
||||||
attr_reader :element
|
attr_reader :element
|
||||||
# The normalized value of this attribute. That is, the attribute with
|
# The normalized value of this attribute. That is, the attribute with
|
||||||
# entities intact.
|
# entities intact.
|
||||||
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
|
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
|
||||||
#
|
#
|
||||||
# first::
|
# first::
|
||||||
|
@ -36,137 +36,137 @@ module REXML
|
||||||
# Ignored unless +first+ is a String; otherwise, may be the Element
|
# Ignored unless +first+ is a String; otherwise, may be the Element
|
||||||
# parent of this attribute, or nil.
|
# parent of this attribute, or nil.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Attribute.new( attribute_to_clone )
|
# Attribute.new( attribute_to_clone )
|
||||||
# Attribute.new( attribute_to_clone, parent_element )
|
# Attribute.new( attribute_to_clone, parent_element )
|
||||||
# Attribute.new( "attr", "attr_value" )
|
# Attribute.new( "attr", "attr_value" )
|
||||||
# Attribute.new( "attr", "attr_value", parent_element )
|
# Attribute.new( "attr", "attr_value", parent_element )
|
||||||
def initialize( first, second=nil, parent=nil )
|
def initialize( first, second=nil, parent=nil )
|
||||||
@normalized = @unnormalized = @element = nil
|
@normalized = @unnormalized = @element = nil
|
||||||
if first.kind_of? Attribute
|
if first.kind_of? Attribute
|
||||||
self.name = first.expanded_name
|
self.name = first.expanded_name
|
||||||
@unnormalized = first.value
|
@unnormalized = first.value
|
||||||
if second.kind_of? Element
|
if second.kind_of? Element
|
||||||
@element = second
|
@element = second
|
||||||
else
|
else
|
||||||
@element = first.element
|
@element = first.element
|
||||||
end
|
end
|
||||||
elsif first.kind_of? String
|
elsif first.kind_of? String
|
||||||
@element = parent
|
@element = parent
|
||||||
self.name = first
|
self.name = first
|
||||||
@normalized = second.to_s
|
@normalized = second.to_s
|
||||||
else
|
else
|
||||||
raise "illegal argument #{first.class.name} to Attribute constructor"
|
raise "illegal argument #{first.class.name} to Attribute constructor"
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
# Returns the namespace of the attribute.
|
|
||||||
#
|
|
||||||
# e = Element.new( "elns:myelement" )
|
|
||||||
# e.add_attribute( "nsa:a", "aval" )
|
|
||||||
# e.add_attribute( "b", "bval" )
|
|
||||||
# e.attributes.get_attribute( "a" ).prefix # -> "nsa"
|
|
||||||
# e.attributes.get_attribute( "b" ).prefix # -> "elns"
|
|
||||||
# a = Attribute.new( "x", "y" )
|
|
||||||
# a.prefix # -> ""
|
|
||||||
def prefix
|
|
||||||
pf = super
|
|
||||||
if pf == ""
|
|
||||||
pf = @element.prefix if @element
|
|
||||||
end
|
|
||||||
pf
|
|
||||||
end
|
|
||||||
|
|
||||||
# Returns the namespace URL, if defined, or nil otherwise
|
|
||||||
#
|
|
||||||
# e = Element.new("el")
|
|
||||||
# e.add_attributes({"xmlns:ns", "http://url"})
|
|
||||||
# e.namespace( "ns" ) # -> "http://url"
|
|
||||||
def namespace arg=nil
|
|
||||||
arg = prefix if arg.nil?
|
|
||||||
@element.namespace arg
|
|
||||||
end
|
|
||||||
|
|
||||||
# Returns true if other is an Attribute and has the same name and value,
|
|
||||||
# false otherwise.
|
|
||||||
def ==( other )
|
|
||||||
other.kind_of?(Attribute) and other.name==name and other.value==value
|
|
||||||
end
|
|
||||||
|
|
||||||
# Creates (and returns) a hash from both the name and value
|
|
||||||
def hash
|
|
||||||
name.hash + value.hash
|
|
||||||
end
|
|
||||||
|
|
||||||
# Returns this attribute out as XML source, expanding the name
|
|
||||||
#
|
|
||||||
# a = Attribute.new( "x", "y" )
|
|
||||||
# a.to_string # -> "x='y'"
|
|
||||||
# b = Attribute.new( "ns:x", "y" )
|
|
||||||
# b.to_string # -> "ns:x='y'"
|
|
||||||
def to_string
|
|
||||||
if @element and @element.context and @element.context[:attribute_quote] == :quote
|
|
||||||
%Q^#@expanded_name="#{to_s().gsub(/"/, '"e;')}"^
|
|
||||||
else
|
|
||||||
"#@expanded_name='#{to_s().gsub(/'/, ''')}'"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def doctype
|
|
||||||
if @element
|
|
||||||
doc = @element.document
|
|
||||||
doctype = doc.doctype if doc
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the attribute value, with entities replaced
|
# Returns the namespace of the attribute.
|
||||||
def to_s
|
#
|
||||||
return @normalized if @normalized
|
# e = Element.new( "elns:myelement" )
|
||||||
|
# e.add_attribute( "nsa:a", "aval" )
|
||||||
|
# e.add_attribute( "b", "bval" )
|
||||||
|
# e.attributes.get_attribute( "a" ).prefix # -> "nsa"
|
||||||
|
# e.attributes.get_attribute( "b" ).prefix # -> "elns"
|
||||||
|
# a = Attribute.new( "x", "y" )
|
||||||
|
# a.prefix # -> ""
|
||||||
|
def prefix
|
||||||
|
pf = super
|
||||||
|
if pf == ""
|
||||||
|
pf = @element.prefix if @element
|
||||||
|
end
|
||||||
|
pf
|
||||||
|
end
|
||||||
|
|
||||||
@normalized = Text::normalize( @unnormalized, doctype )
|
# Returns the namespace URL, if defined, or nil otherwise
|
||||||
@unnormalized = nil
|
#
|
||||||
|
# e = Element.new("el")
|
||||||
|
# e.add_attributes({"xmlns:ns", "http://url"})
|
||||||
|
# e.namespace( "ns" ) # -> "http://url"
|
||||||
|
def namespace arg=nil
|
||||||
|
arg = prefix if arg.nil?
|
||||||
|
@element.namespace arg
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns true if other is an Attribute and has the same name and value,
|
||||||
|
# false otherwise.
|
||||||
|
def ==( other )
|
||||||
|
other.kind_of?(Attribute) and other.name==name and other.value==value
|
||||||
|
end
|
||||||
|
|
||||||
|
# Creates (and returns) a hash from both the name and value
|
||||||
|
def hash
|
||||||
|
name.hash + value.hash
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns this attribute out as XML source, expanding the name
|
||||||
|
#
|
||||||
|
# a = Attribute.new( "x", "y" )
|
||||||
|
# a.to_string # -> "x='y'"
|
||||||
|
# b = Attribute.new( "ns:x", "y" )
|
||||||
|
# b.to_string # -> "ns:x='y'"
|
||||||
|
def to_string
|
||||||
|
if @element and @element.context and @element.context[:attribute_quote] == :quote
|
||||||
|
%Q^#@expanded_name="#{to_s().gsub(/"/, '"e;')}"^
|
||||||
|
else
|
||||||
|
"#@expanded_name='#{to_s().gsub(/'/, ''')}'"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def doctype
|
||||||
|
if @element
|
||||||
|
doc = @element.document
|
||||||
|
doctype = doc.doctype if doc
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns the attribute value, with entities replaced
|
||||||
|
def to_s
|
||||||
|
return @normalized if @normalized
|
||||||
|
|
||||||
|
@normalized = Text::normalize( @unnormalized, doctype )
|
||||||
|
@unnormalized = nil
|
||||||
@normalized
|
@normalized
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the UNNORMALIZED value of this attribute. That is, entities
|
# Returns the UNNORMALIZED value of this attribute. That is, entities
|
||||||
# have been expanded to their values
|
# have been expanded to their values
|
||||||
def value
|
def value
|
||||||
return @unnormalized if @unnormalized
|
return @unnormalized if @unnormalized
|
||||||
@unnormalized = Text::unnormalize( @normalized, doctype )
|
@unnormalized = Text::unnormalize( @normalized, doctype )
|
||||||
@normalized = nil
|
@normalized = nil
|
||||||
@unnormalized
|
@unnormalized
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns a copy of this attribute
|
# Returns a copy of this attribute
|
||||||
def clone
|
def clone
|
||||||
Attribute.new self
|
Attribute.new self
|
||||||
end
|
end
|
||||||
|
|
||||||
# Sets the element of which this object is an attribute. Normally, this
|
# Sets the element of which this object is an attribute. Normally, this
|
||||||
# is not directly called.
|
# is not directly called.
|
||||||
#
|
#
|
||||||
# Returns this attribute
|
# Returns this attribute
|
||||||
def element=( element )
|
def element=( element )
|
||||||
@element = element
|
@element = element
|
||||||
|
|
||||||
if @normalized
|
if @normalized
|
||||||
Text.check( @normalized, NEEDS_A_SECOND_CHECK, doctype )
|
Text.check( @normalized, NEEDS_A_SECOND_CHECK, doctype )
|
||||||
end
|
end
|
||||||
|
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
# Removes this Attribute from the tree, and returns true if successfull
|
# Removes this Attribute from the tree, and returns true if successfull
|
||||||
#
|
#
|
||||||
# This method is usually not called directly.
|
# This method is usually not called directly.
|
||||||
def remove
|
def remove
|
||||||
@element.attributes.delete self.name unless @element.nil?
|
@element.attributes.delete self.name unless @element.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
# Writes this attribute (EG, puts 'key="value"' to the output)
|
# Writes this attribute (EG, puts 'key="value"' to the output)
|
||||||
def write( output, indent=-1 )
|
def write( output, indent=-1 )
|
||||||
output << to_string
|
output << to_string
|
||||||
end
|
end
|
||||||
|
|
||||||
def node_type
|
def node_type
|
||||||
:attribute
|
:attribute
|
||||||
|
@ -183,6 +183,6 @@ module REXML
|
||||||
path += "/@#{self.expanded_name}"
|
path += "/@#{self.expanded_name}"
|
||||||
return path
|
return path
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
#vim:ts=2 sw=2 noexpandtab:
|
#vim:ts=2 sw=2 noexpandtab:
|
||||||
|
|
|
@ -1,39 +1,39 @@
|
||||||
require "rexml/text"
|
require "rexml/text"
|
||||||
|
|
||||||
module REXML
|
module REXML
|
||||||
class CData < Text
|
class CData < Text
|
||||||
START = '<![CDATA['
|
START = '<![CDATA['
|
||||||
STOP = ']]>'
|
STOP = ']]>'
|
||||||
ILLEGAL = /(\]\]>)/
|
ILLEGAL = /(\]\]>)/
|
||||||
|
|
||||||
# Constructor. CData is data between <![CDATA[ ... ]]>
|
# Constructor. CData is data between <![CDATA[ ... ]]>
|
||||||
#
|
#
|
||||||
# _Examples_
|
# _Examples_
|
||||||
# CData.new( source )
|
# CData.new( source )
|
||||||
# CData.new( "Here is some CDATA" )
|
# CData.new( "Here is some CDATA" )
|
||||||
# CData.new( "Some unprocessed data", respect_whitespace_TF, parent_element )
|
# CData.new( "Some unprocessed data", respect_whitespace_TF, parent_element )
|
||||||
def initialize( first, whitespace=true, parent=nil )
|
def initialize( first, whitespace=true, parent=nil )
|
||||||
super( first, whitespace, parent, false, true, ILLEGAL )
|
super( first, whitespace, parent, false, true, ILLEGAL )
|
||||||
end
|
end
|
||||||
|
|
||||||
# Make a copy of this object
|
# Make a copy of this object
|
||||||
#
|
#
|
||||||
# _Examples_
|
# _Examples_
|
||||||
# c = CData.new( "Some text" )
|
# c = CData.new( "Some text" )
|
||||||
# d = c.clone
|
# d = c.clone
|
||||||
# d.to_s # -> "Some text"
|
# d.to_s # -> "Some text"
|
||||||
def clone
|
def clone
|
||||||
CData.new self
|
CData.new self
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the content of this CData object
|
# Returns the content of this CData object
|
||||||
#
|
#
|
||||||
# _Examples_
|
# _Examples_
|
||||||
# c = CData.new( "Some text" )
|
# c = CData.new( "Some text" )
|
||||||
# c.to_s # -> "Some text"
|
# c.to_s # -> "Some text"
|
||||||
def to_s
|
def to_s
|
||||||
@string
|
@string
|
||||||
end
|
end
|
||||||
|
|
||||||
def value
|
def value
|
||||||
@string
|
@string
|
||||||
|
@ -42,26 +42,26 @@ module REXML
|
||||||
# == DEPRECATED
|
# == DEPRECATED
|
||||||
# See the rexml/formatters package
|
# See the rexml/formatters package
|
||||||
#
|
#
|
||||||
# Generates XML output of this object
|
# Generates XML output of this object
|
||||||
#
|
#
|
||||||
# output::
|
# output::
|
||||||
# Where to write the string. Defaults to $stdout
|
# Where to write the string. Defaults to $stdout
|
||||||
# indent::
|
# indent::
|
||||||
# The amount to indent this node by
|
# The amount to indent this node by
|
||||||
# transitive::
|
# transitive::
|
||||||
# Ignored
|
# Ignored
|
||||||
# ie_hack::
|
# ie_hack::
|
||||||
# Ignored
|
# Ignored
|
||||||
#
|
#
|
||||||
# _Examples_
|
# _Examples_
|
||||||
# c = CData.new( " Some text " )
|
# c = CData.new( " Some text " )
|
||||||
# c.write( $stdout ) #-> <![CDATA[ Some text ]]>
|
# c.write( $stdout ) #-> <![CDATA[ Some text ]]>
|
||||||
def write( output=$stdout, indent=-1, transitive=false, ie_hack=false )
|
def write( output=$stdout, indent=-1, transitive=false, ie_hack=false )
|
||||||
Kernel.warn( "#{self.class.name}.write is deprecated" )
|
Kernel.warn( "#{self.class.name}.write is deprecated" )
|
||||||
indent( output, indent )
|
indent( output, indent )
|
||||||
output << START
|
output << START
|
||||||
output << @string
|
output << @string
|
||||||
output << STOP
|
output << STOP
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,96 +1,96 @@
|
||||||
require "rexml/node"
|
require "rexml/node"
|
||||||
|
|
||||||
module REXML
|
module REXML
|
||||||
##
|
##
|
||||||
# A Child object is something contained by a parent, and this class
|
# A Child object is something contained by a parent, and this class
|
||||||
# contains methods to support that. Most user code will not use this
|
# contains methods to support that. Most user code will not use this
|
||||||
# class directly.
|
# class directly.
|
||||||
class Child
|
class Child
|
||||||
include Node
|
include Node
|
||||||
attr_reader :parent # The Parent of this object
|
attr_reader :parent # The Parent of this object
|
||||||
|
|
||||||
# Constructor. Any inheritors of this class should call super to make
|
# Constructor. Any inheritors of this class should call super to make
|
||||||
# sure this method is called.
|
# sure this method is called.
|
||||||
# parent::
|
# parent::
|
||||||
# if supplied, the parent of this child will be set to the
|
# if supplied, the parent of this child will be set to the
|
||||||
# supplied value, and self will be added to the parent
|
# supplied value, and self will be added to the parent
|
||||||
def initialize( parent = nil )
|
def initialize( parent = nil )
|
||||||
@parent = nil
|
@parent = nil
|
||||||
# Declare @parent, but don't define it. The next line sets the
|
# Declare @parent, but don't define it. The next line sets the
|
||||||
# parent.
|
# parent.
|
||||||
parent.add( self ) if parent
|
parent.add( self ) if parent
|
||||||
end
|
end
|
||||||
|
|
||||||
# Replaces this object with another object. Basically, calls
|
# Replaces this object with another object. Basically, calls
|
||||||
# Parent.replace_child
|
# Parent.replace_child
|
||||||
#
|
#
|
||||||
# Returns:: self
|
# Returns:: self
|
||||||
def replace_with( child )
|
def replace_with( child )
|
||||||
@parent.replace_child( self, child )
|
@parent.replace_child( self, child )
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
# Removes this child from the parent.
|
# Removes this child from the parent.
|
||||||
#
|
#
|
||||||
# Returns:: self
|
# Returns:: self
|
||||||
def remove
|
def remove
|
||||||
unless @parent.nil?
|
unless @parent.nil?
|
||||||
@parent.delete self
|
@parent.delete self
|
||||||
end
|
end
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
# Sets the parent of this child to the supplied argument.
|
# Sets the parent of this child to the supplied argument.
|
||||||
#
|
#
|
||||||
# other::
|
# other::
|
||||||
# Must be a Parent object. If this object is the same object as the
|
# Must be a Parent object. If this object is the same object as the
|
||||||
# existing parent of this child, no action is taken. Otherwise, this
|
# existing parent of this child, no action is taken. Otherwise, this
|
||||||
# child is removed from the current parent (if one exists), and is added
|
# child is removed from the current parent (if one exists), and is added
|
||||||
# to the new parent.
|
# to the new parent.
|
||||||
# Returns:: The parent added
|
# Returns:: The parent added
|
||||||
def parent=( other )
|
def parent=( other )
|
||||||
return @parent if @parent == other
|
return @parent if @parent == other
|
||||||
@parent.delete self if defined? @parent and @parent
|
@parent.delete self if defined? @parent and @parent
|
||||||
@parent = other
|
@parent = other
|
||||||
end
|
end
|
||||||
|
|
||||||
alias :next_sibling :next_sibling_node
|
alias :next_sibling :next_sibling_node
|
||||||
alias :previous_sibling :previous_sibling_node
|
alias :previous_sibling :previous_sibling_node
|
||||||
|
|
||||||
# Sets the next sibling of this child. This can be used to insert a child
|
# Sets the next sibling of this child. This can be used to insert a child
|
||||||
# after some other child.
|
# after some other child.
|
||||||
# a = Element.new("a")
|
# a = Element.new("a")
|
||||||
# b = a.add_element("b")
|
# b = a.add_element("b")
|
||||||
# c = Element.new("c")
|
# c = Element.new("c")
|
||||||
# b.next_sibling = c
|
# b.next_sibling = c
|
||||||
# # => <a><b/><c/></a>
|
# # => <a><b/><c/></a>
|
||||||
def next_sibling=( other )
|
def next_sibling=( other )
|
||||||
parent.insert_after self, other
|
parent.insert_after self, other
|
||||||
end
|
end
|
||||||
|
|
||||||
# Sets the previous sibling of this child. This can be used to insert a
|
# Sets the previous sibling of this child. This can be used to insert a
|
||||||
# child before some other child.
|
# child before some other child.
|
||||||
# a = Element.new("a")
|
# a = Element.new("a")
|
||||||
# b = a.add_element("b")
|
# b = a.add_element("b")
|
||||||
# c = Element.new("c")
|
# c = Element.new("c")
|
||||||
# b.previous_sibling = c
|
# b.previous_sibling = c
|
||||||
# # => <a><b/><c/></a>
|
# # => <a><b/><c/></a>
|
||||||
def previous_sibling=(other)
|
def previous_sibling=(other)
|
||||||
parent.insert_before self, other
|
parent.insert_before self, other
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns:: the document this child belongs to, or nil if this child
|
# Returns:: the document this child belongs to, or nil if this child
|
||||||
# belongs to no document
|
# belongs to no document
|
||||||
def document
|
def document
|
||||||
return parent.document unless parent.nil?
|
return parent.document unless parent.nil?
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
# This doesn't yet handle encodings
|
# This doesn't yet handle encodings
|
||||||
def bytes
|
def bytes
|
||||||
encoding = document.encoding
|
encoding = document.encoding
|
||||||
|
|
||||||
to_s
|
to_s
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,80 +1,80 @@
|
||||||
require "rexml/child"
|
require "rexml/child"
|
||||||
|
|
||||||
module REXML
|
module REXML
|
||||||
##
|
##
|
||||||
# Represents an XML comment; that is, text between \<!-- ... -->
|
# Represents an XML comment; that is, text between \<!-- ... -->
|
||||||
class Comment < Child
|
class Comment < Child
|
||||||
include Comparable
|
include Comparable
|
||||||
START = "<!--"
|
START = "<!--"
|
||||||
STOP = "-->"
|
STOP = "-->"
|
||||||
|
|
||||||
# The content text
|
# The content text
|
||||||
|
|
||||||
attr_accessor :string
|
attr_accessor :string
|
||||||
|
|
||||||
##
|
##
|
||||||
# Constructor. The first argument can be one of three types:
|
# Constructor. The first argument can be one of three types:
|
||||||
# @param first If String, the contents of this comment are set to the
|
# @param first If String, the contents of this comment are set to the
|
||||||
# argument. If Comment, the argument is duplicated. If
|
# argument. If Comment, the argument is duplicated. If
|
||||||
# Source, the argument is scanned for a comment.
|
# Source, the argument is scanned for a comment.
|
||||||
# @param second If the first argument is a Source, this argument
|
# @param second If the first argument is a Source, this argument
|
||||||
# should be nil, not supplied, or a Parent to be set as the parent
|
# should be nil, not supplied, or a Parent to be set as the parent
|
||||||
# of this object
|
# of this object
|
||||||
def initialize( first, second = nil )
|
def initialize( first, second = nil )
|
||||||
#puts "IN COMMENT CONSTRUCTOR; SECOND IS #{second.type}"
|
#puts "IN COMMENT CONSTRUCTOR; SECOND IS #{second.type}"
|
||||||
super(second)
|
super(second)
|
||||||
if first.kind_of? String
|
if first.kind_of? String
|
||||||
@string = first
|
@string = first
|
||||||
elsif first.kind_of? Comment
|
elsif first.kind_of? Comment
|
||||||
@string = first.string
|
@string = first.string
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def clone
|
def clone
|
||||||
Comment.new self
|
Comment.new self
|
||||||
end
|
end
|
||||||
|
|
||||||
# == DEPRECATED
|
# == DEPRECATED
|
||||||
# See REXML::Formatters
|
# See REXML::Formatters
|
||||||
#
|
#
|
||||||
# output::
|
# output::
|
||||||
# Where to write the string
|
# Where to write the string
|
||||||
# indent::
|
# indent::
|
||||||
# An integer. If -1, no indenting will be used; otherwise, the
|
# An integer. If -1, no indenting will be used; otherwise, the
|
||||||
# indentation will be this number of spaces, and children will be
|
# indentation will be this number of spaces, and children will be
|
||||||
# indented an additional amount.
|
# indented an additional amount.
|
||||||
# transitive::
|
# transitive::
|
||||||
# Ignored by this class. The contents of comments are never modified.
|
# Ignored by this class. The contents of comments are never modified.
|
||||||
# ie_hack::
|
# ie_hack::
|
||||||
# Needed for conformity to the child API, but not used by this class.
|
# Needed for conformity to the child API, but not used by this class.
|
||||||
def write( output, indent=-1, transitive=false, ie_hack=false )
|
def write( output, indent=-1, transitive=false, ie_hack=false )
|
||||||
Kernel.warn("Comment.write is deprecated. See REXML::Formatters")
|
Kernel.warn("Comment.write is deprecated. See REXML::Formatters")
|
||||||
indent( output, indent )
|
indent( output, indent )
|
||||||
output << START
|
output << START
|
||||||
output << @string
|
output << @string
|
||||||
output << STOP
|
output << STOP
|
||||||
end
|
end
|
||||||
|
|
||||||
alias :to_s :string
|
alias :to_s :string
|
||||||
|
|
||||||
##
|
##
|
||||||
# Compares this Comment to another; the contents of the comment are used
|
# Compares this Comment to another; the contents of the comment are used
|
||||||
# in the comparison.
|
# in the comparison.
|
||||||
def <=>(other)
|
def <=>(other)
|
||||||
other.to_s <=> @string
|
other.to_s <=> @string
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Compares this Comment to another; the contents of the comment are used
|
# Compares this Comment to another; the contents of the comment are used
|
||||||
# in the comparison.
|
# in the comparison.
|
||||||
def ==( other )
|
def ==( other )
|
||||||
other.kind_of? Comment and
|
other.kind_of? Comment and
|
||||||
(other <=> self) == 0
|
(other <=> self) == 0
|
||||||
end
|
end
|
||||||
|
|
||||||
def node_type
|
def node_type
|
||||||
:comment
|
:comment
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
#vim:ts=2 sw=2 noexpandtab:
|
#vim:ts=2 sw=2 noexpandtab:
|
||||||
|
|
|
@ -16,59 +16,59 @@ module REXML
|
||||||
# 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 = {} )
|
||||||
@entity_expansion_count = 0
|
@entity_expansion_count = 0
|
||||||
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.
|
||||||
|
@ -86,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,
|
||||||
|
@ -194,12 +194,12 @@ module REXML
|
||||||
REXML::Formatters::Default.new( ie_hack )
|
REXML::Formatters::Default.new( ie_hack )
|
||||||
end
|
end
|
||||||
formatter.write( self, output )
|
formatter.write( self, output )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def Document::parse_stream( source, listener )
|
def Document::parse_stream( source, listener )
|
||||||
Parsers::StreamParser.new( source, listener ).parse
|
Parsers::StreamParser.new( source, listener ).parse
|
||||||
end
|
end
|
||||||
|
|
||||||
@@entity_expansion_limit = 10_000
|
@@entity_expansion_limit = 10_000
|
||||||
|
|
||||||
|
@ -222,9 +222,9 @@ module REXML
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def build( source )
|
def build( source )
|
||||||
Parsers::TreeParser.new( source, self ).parse
|
Parsers::TreeParser.new( source, self ).parse
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
require "rexml/child"
|
require "rexml/child"
|
||||||
module REXML
|
module REXML
|
||||||
module DTD
|
module DTD
|
||||||
class AttlistDecl < Child
|
class AttlistDecl < Child
|
||||||
START = "<!ATTLIST"
|
START = "<!ATTLIST"
|
||||||
START_RE = /^\s*#{START}/um
|
START_RE = /^\s*#{START}/um
|
||||||
PATTERN_RE = /\s*(#{START}.*?>)/um
|
PATTERN_RE = /\s*(#{START}.*?>)/um
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,46 +6,46 @@ require "rexml/dtd/attlistdecl"
|
||||||
require "rexml/parent"
|
require "rexml/parent"
|
||||||
|
|
||||||
module REXML
|
module REXML
|
||||||
module DTD
|
module DTD
|
||||||
class Parser
|
class Parser
|
||||||
def Parser.parse( input )
|
def Parser.parse( input )
|
||||||
case input
|
case input
|
||||||
when String
|
when String
|
||||||
parse_helper input
|
parse_helper input
|
||||||
when File
|
when File
|
||||||
parse_helper input.read
|
parse_helper input.read
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Takes a String and parses it out
|
# Takes a String and parses it out
|
||||||
def Parser.parse_helper( input )
|
def Parser.parse_helper( input )
|
||||||
contents = Parent.new
|
contents = Parent.new
|
||||||
while input.size > 0
|
while input.size > 0
|
||||||
case input
|
case input
|
||||||
when ElementDecl.PATTERN_RE
|
when ElementDecl.PATTERN_RE
|
||||||
match = $&
|
match = $&
|
||||||
source = $'
|
source = $'
|
||||||
contents << ElementDecl.new( match )
|
contents << ElementDecl.new( match )
|
||||||
when AttlistDecl.PATTERN_RE
|
when AttlistDecl.PATTERN_RE
|
||||||
matchdata = $~
|
matchdata = $~
|
||||||
source = $'
|
source = $'
|
||||||
contents << AttlistDecl.new( matchdata )
|
contents << AttlistDecl.new( matchdata )
|
||||||
when EntityDecl.PATTERN_RE
|
when EntityDecl.PATTERN_RE
|
||||||
matchdata = $~
|
matchdata = $~
|
||||||
source = $'
|
source = $'
|
||||||
contents << EntityDecl.new( matchdata )
|
contents << EntityDecl.new( matchdata )
|
||||||
when Comment.PATTERN_RE
|
when Comment.PATTERN_RE
|
||||||
matchdata = $~
|
matchdata = $~
|
||||||
source = $'
|
source = $'
|
||||||
contents << Comment.new( matchdata )
|
contents << Comment.new( matchdata )
|
||||||
when NotationDecl.PATTERN_RE
|
when NotationDecl.PATTERN_RE
|
||||||
matchdata = $~
|
matchdata = $~
|
||||||
source = $'
|
source = $'
|
||||||
contents << NotationDecl.new( matchdata )
|
contents << NotationDecl.new( matchdata )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
contents
|
contents
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
require "rexml/child"
|
require "rexml/child"
|
||||||
module REXML
|
module REXML
|
||||||
module DTD
|
module DTD
|
||||||
class ElementDecl < Child
|
class ElementDecl < Child
|
||||||
START = "<!ELEMENT"
|
START = "<!ELEMENT"
|
||||||
START_RE = /^\s*#{START}/um
|
START_RE = /^\s*#{START}/um
|
||||||
PATTERN_RE = /^\s*(#{START}.*?)>/um
|
PATTERN_RE = /^\s*(#{START}.*?)>/um
|
||||||
PATTERN_RE = /^\s*#{START}\s+((?:[:\w_][-\.\w_]*:)?[-!\*\.\w_]*)(.*?)>/
|
PATTERN_RE = /^\s*#{START}\s+((?:[:\w_][-\.\w_]*:)?[-!\*\.\w_]*)(.*?)>/
|
||||||
#\s*((((["']).*?\5)|[^\/'">]*)*?)(\/)?>/um, true)
|
#\s*((((["']).*?\5)|[^\/'">]*)*?)(\/)?>/um, true)
|
||||||
|
|
||||||
def initialize match
|
def initialize match
|
||||||
@name = match[1]
|
@name = match[1]
|
||||||
@rest = match[2]
|
@rest = match[2]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,56 +1,56 @@
|
||||||
require "rexml/child"
|
require "rexml/child"
|
||||||
module REXML
|
module REXML
|
||||||
module DTD
|
module DTD
|
||||||
class EntityDecl < Child
|
class EntityDecl < Child
|
||||||
START = "<!ENTITY"
|
START = "<!ENTITY"
|
||||||
START_RE = /^\s*#{START}/um
|
START_RE = /^\s*#{START}/um
|
||||||
PUBLIC = /^\s*#{START}\s+(?:%\s+)?(\w+)\s+PUBLIC\s+((["']).*?\3)\s+((["']).*?\5)\s*>/um
|
PUBLIC = /^\s*#{START}\s+(?:%\s+)?(\w+)\s+PUBLIC\s+((["']).*?\3)\s+((["']).*?\5)\s*>/um
|
||||||
SYSTEM = /^\s*#{START}\s+(?:%\s+)?(\w+)\s+SYSTEM\s+((["']).*?\3)(?:\s+NDATA\s+\w+)?\s*>/um
|
SYSTEM = /^\s*#{START}\s+(?:%\s+)?(\w+)\s+SYSTEM\s+((["']).*?\3)(?:\s+NDATA\s+\w+)?\s*>/um
|
||||||
PLAIN = /^\s*#{START}\s+(\w+)\s+((["']).*?\3)\s*>/um
|
PLAIN = /^\s*#{START}\s+(\w+)\s+((["']).*?\3)\s*>/um
|
||||||
PERCENT = /^\s*#{START}\s+%\s+(\w+)\s+((["']).*?\3)\s*>/um
|
PERCENT = /^\s*#{START}\s+%\s+(\w+)\s+((["']).*?\3)\s*>/um
|
||||||
# <!ENTITY name SYSTEM "...">
|
# <!ENTITY name SYSTEM "...">
|
||||||
# <!ENTITY name "...">
|
# <!ENTITY name "...">
|
||||||
def initialize src
|
def initialize src
|
||||||
super()
|
super()
|
||||||
md = nil
|
md = nil
|
||||||
if src.match( PUBLIC )
|
if src.match( PUBLIC )
|
||||||
md = src.match( PUBLIC, true )
|
md = src.match( PUBLIC, true )
|
||||||
@middle = "PUBLIC"
|
@middle = "PUBLIC"
|
||||||
@content = "#{md[2]} #{md[4]}"
|
@content = "#{md[2]} #{md[4]}"
|
||||||
elsif src.match( SYSTEM )
|
elsif src.match( SYSTEM )
|
||||||
md = src.match( SYSTEM, true )
|
md = src.match( SYSTEM, true )
|
||||||
@middle = "SYSTEM"
|
@middle = "SYSTEM"
|
||||||
@content = md[2]
|
@content = md[2]
|
||||||
elsif src.match( PLAIN )
|
elsif src.match( PLAIN )
|
||||||
md = src.match( PLAIN, true )
|
md = src.match( PLAIN, true )
|
||||||
@middle = ""
|
@middle = ""
|
||||||
@content = md[2]
|
@content = md[2]
|
||||||
elsif src.match( PERCENT )
|
elsif src.match( PERCENT )
|
||||||
md = src.match( PERCENT, true )
|
md = src.match( PERCENT, true )
|
||||||
@middle = ""
|
@middle = ""
|
||||||
@content = md[2]
|
@content = md[2]
|
||||||
end
|
end
|
||||||
raise ParseException.new("failed Entity match", src) if md.nil?
|
raise ParseException.new("failed Entity match", src) if md.nil?
|
||||||
@name = md[1]
|
@name = md[1]
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
rv = "<!ENTITY #@name "
|
rv = "<!ENTITY #@name "
|
||||||
rv << "#@middle " if @middle.size > 0
|
rv << "#@middle " if @middle.size > 0
|
||||||
rv << @content
|
rv << @content
|
||||||
rv
|
rv
|
||||||
end
|
end
|
||||||
|
|
||||||
def write( output, indent )
|
def write( output, indent )
|
||||||
indent( output, indent )
|
indent( output, indent )
|
||||||
output << to_s
|
output << to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
def EntityDecl.parse_source source, listener
|
def EntityDecl.parse_source source, listener
|
||||||
md = source.match( PATTERN_RE, true )
|
md = source.match( PATTERN_RE, true )
|
||||||
thing = md[0].squeeze(" \t\n\r")
|
thing = md[0].squeeze(" \t\n\r")
|
||||||
listener.send inspect.downcase, thing
|
listener.send inspect.downcase, thing
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,39 +1,39 @@
|
||||||
require "rexml/child"
|
require "rexml/child"
|
||||||
module REXML
|
module REXML
|
||||||
module DTD
|
module DTD
|
||||||
class NotationDecl < Child
|
class NotationDecl < Child
|
||||||
START = "<!NOTATION"
|
START = "<!NOTATION"
|
||||||
START_RE = /^\s*#{START}/um
|
START_RE = /^\s*#{START}/um
|
||||||
PUBLIC = /^\s*#{START}\s+(\w[\w-]*)\s+(PUBLIC)\s+((["']).*?\4)\s*>/um
|
PUBLIC = /^\s*#{START}\s+(\w[\w-]*)\s+(PUBLIC)\s+((["']).*?\4)\s*>/um
|
||||||
SYSTEM = /^\s*#{START}\s+(\w[\w-]*)\s+(SYSTEM)\s+((["']).*?\4)\s*>/um
|
SYSTEM = /^\s*#{START}\s+(\w[\w-]*)\s+(SYSTEM)\s+((["']).*?\4)\s*>/um
|
||||||
def initialize src
|
def initialize src
|
||||||
super()
|
super()
|
||||||
if src.match( PUBLIC )
|
if src.match( PUBLIC )
|
||||||
md = src.match( PUBLIC, true )
|
md = src.match( PUBLIC, true )
|
||||||
elsif src.match( SYSTEM )
|
elsif src.match( SYSTEM )
|
||||||
md = src.match( SYSTEM, true )
|
md = src.match( SYSTEM, true )
|
||||||
else
|
else
|
||||||
raise ParseException.new( "error parsing notation: no matching pattern", src )
|
raise ParseException.new( "error parsing notation: no matching pattern", src )
|
||||||
end
|
end
|
||||||
@name = md[1]
|
@name = md[1]
|
||||||
@middle = md[2]
|
@middle = md[2]
|
||||||
@rest = md[3]
|
@rest = md[3]
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
"<!NOTATION #@name #@middle #@rest>"
|
"<!NOTATION #@name #@middle #@rest>"
|
||||||
end
|
end
|
||||||
|
|
||||||
def write( output, indent )
|
def write( output, indent )
|
||||||
indent( output, indent )
|
indent( output, indent )
|
||||||
output << to_s
|
output << to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
def NotationDecl.parse_source source, listener
|
def NotationDecl.parse_source source, listener
|
||||||
md = source.match( PATTERN_RE, true )
|
md = source.match( PATTERN_RE, true )
|
||||||
thing = md[0].squeeze(" \t\n\r")
|
thing = md[0].squeeze(" \t\n\r")
|
||||||
listener.send inspect.downcase, thing
|
listener.send inspect.downcase, thing
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,12 +3,12 @@
|
||||||
#
|
#
|
||||||
module REXML
|
module REXML
|
||||||
module Encoding
|
module Encoding
|
||||||
register( "CP-1252" ) do |o|
|
register( "CP-1252" ) do |o|
|
||||||
class << o
|
class << o
|
||||||
alias encode encode_cp1252
|
alias encode encode_cp1252
|
||||||
alias decode decode_cp1252
|
alias decode decode_cp1252
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Convert from UTF-8
|
# Convert from UTF-8
|
||||||
def encode_cp1252(content)
|
def encode_cp1252(content)
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
#
|
#
|
||||||
module REXML
|
module REXML
|
||||||
module Encoding
|
module Encoding
|
||||||
register("ISO-8859-15") do |o|
|
register("ISO-8859-15") do |o|
|
||||||
alias encode to_iso_8859_15
|
alias encode to_iso_8859_15
|
||||||
alias decode from_iso_8859_15
|
alias decode from_iso_8859_15
|
||||||
end
|
end
|
||||||
|
|
||||||
# Convert from UTF-8
|
# Convert from UTF-8
|
||||||
def to_iso_8859_15(content)
|
def to_iso_8859_15(content)
|
||||||
|
|
|
@ -3,164 +3,164 @@ require 'rexml/source'
|
||||||
require 'rexml/xmltokens'
|
require 'rexml/xmltokens'
|
||||||
|
|
||||||
module REXML
|
module REXML
|
||||||
# God, I hate DTDs. I really do. Why this idiot standard still
|
# God, I hate DTDs. I really do. Why this idiot standard still
|
||||||
# plagues us is beyond me.
|
# plagues us is beyond me.
|
||||||
class Entity < Child
|
class Entity < Child
|
||||||
include XMLTokens
|
include XMLTokens
|
||||||
PUBIDCHAR = "\x20\x0D\x0Aa-zA-Z0-9\\-()+,./:=?;!*@$_%#"
|
PUBIDCHAR = "\x20\x0D\x0Aa-zA-Z0-9\\-()+,./:=?;!*@$_%#"
|
||||||
SYSTEMLITERAL = %Q{((?:"[^"]*")|(?:'[^']*'))}
|
SYSTEMLITERAL = %Q{((?:"[^"]*")|(?:'[^']*'))}
|
||||||
PUBIDLITERAL = %Q{("[#{PUBIDCHAR}']*"|'[#{PUBIDCHAR}]*')}
|
PUBIDLITERAL = %Q{("[#{PUBIDCHAR}']*"|'[#{PUBIDCHAR}]*')}
|
||||||
EXTERNALID = "(?:(?:(SYSTEM)\\s+#{SYSTEMLITERAL})|(?:(PUBLIC)\\s+#{PUBIDLITERAL}\\s+#{SYSTEMLITERAL}))"
|
EXTERNALID = "(?:(?:(SYSTEM)\\s+#{SYSTEMLITERAL})|(?:(PUBLIC)\\s+#{PUBIDLITERAL}\\s+#{SYSTEMLITERAL}))"
|
||||||
NDATADECL = "\\s+NDATA\\s+#{NAME}"
|
NDATADECL = "\\s+NDATA\\s+#{NAME}"
|
||||||
PEREFERENCE = "%#{NAME};"
|
PEREFERENCE = "%#{NAME};"
|
||||||
ENTITYVALUE = %Q{((?:"(?:[^%&"]|#{PEREFERENCE}|#{REFERENCE})*")|(?:'([^%&']|#{PEREFERENCE}|#{REFERENCE})*'))}
|
ENTITYVALUE = %Q{((?:"(?:[^%&"]|#{PEREFERENCE}|#{REFERENCE})*")|(?:'([^%&']|#{PEREFERENCE}|#{REFERENCE})*'))}
|
||||||
PEDEF = "(?:#{ENTITYVALUE}|#{EXTERNALID})"
|
PEDEF = "(?:#{ENTITYVALUE}|#{EXTERNALID})"
|
||||||
ENTITYDEF = "(?:#{ENTITYVALUE}|(?:#{EXTERNALID}(#{NDATADECL})?))"
|
ENTITYDEF = "(?:#{ENTITYVALUE}|(?:#{EXTERNALID}(#{NDATADECL})?))"
|
||||||
PEDECL = "<!ENTITY\\s+(%)\\s+#{NAME}\\s+#{PEDEF}\\s*>"
|
PEDECL = "<!ENTITY\\s+(%)\\s+#{NAME}\\s+#{PEDEF}\\s*>"
|
||||||
GEDECL = "<!ENTITY\\s+#{NAME}\\s+#{ENTITYDEF}\\s*>"
|
GEDECL = "<!ENTITY\\s+#{NAME}\\s+#{ENTITYDEF}\\s*>"
|
||||||
ENTITYDECL = /\s*(?:#{GEDECL})|(?:#{PEDECL})/um
|
ENTITYDECL = /\s*(?:#{GEDECL})|(?:#{PEDECL})/um
|
||||||
|
|
||||||
attr_reader :name, :external, :ref, :ndata, :pubid
|
attr_reader :name, :external, :ref, :ndata, :pubid
|
||||||
|
|
||||||
# Create a new entity. Simple entities can be constructed by passing a
|
# Create a new entity. Simple entities can be constructed by passing a
|
||||||
# name, value to the constructor; this creates a generic, plain entity
|
# name, value to the constructor; this creates a generic, plain entity
|
||||||
# reference. For anything more complicated, you have to pass a Source to
|
# reference. For anything more complicated, you have to pass a Source to
|
||||||
# the constructor with the entity definiton, or use the accessor methods.
|
# the constructor with the entity definiton, or use the accessor methods.
|
||||||
# +WARNING+: There is no validation of entity state except when the entity
|
# +WARNING+: There is no validation of entity state except when the entity
|
||||||
# is read from a stream. If you start poking around with the accessors,
|
# is read from a stream. If you start poking around with the accessors,
|
||||||
# you can easily create a non-conformant Entity. The best thing to do is
|
# you can easily create a non-conformant Entity. The best thing to do is
|
||||||
# dump the stupid DTDs and use XMLSchema instead.
|
# dump the stupid DTDs and use XMLSchema instead.
|
||||||
#
|
#
|
||||||
# e = Entity.new( 'amp', '&' )
|
# e = Entity.new( 'amp', '&' )
|
||||||
def initialize stream, value=nil, parent=nil, reference=false
|
def initialize stream, value=nil, parent=nil, reference=false
|
||||||
super(parent)
|
super(parent)
|
||||||
@ndata = @pubid = @value = @external = nil
|
@ndata = @pubid = @value = @external = nil
|
||||||
if stream.kind_of? Array
|
if stream.kind_of? Array
|
||||||
@name = stream[1]
|
@name = stream[1]
|
||||||
if stream[-1] == '%'
|
if stream[-1] == '%'
|
||||||
@reference = true
|
@reference = true
|
||||||
stream.pop
|
stream.pop
|
||||||
else
|
else
|
||||||
@reference = false
|
@reference = false
|
||||||
end
|
end
|
||||||
if stream[2] =~ /SYSTEM|PUBLIC/
|
if stream[2] =~ /SYSTEM|PUBLIC/
|
||||||
@external = stream[2]
|
@external = stream[2]
|
||||||
if @external == 'SYSTEM'
|
if @external == 'SYSTEM'
|
||||||
@ref = stream[3]
|
@ref = stream[3]
|
||||||
@ndata = stream[4] if stream.size == 5
|
@ndata = stream[4] if stream.size == 5
|
||||||
else
|
else
|
||||||
@pubid = stream[3]
|
@pubid = stream[3]
|
||||||
@ref = stream[4]
|
@ref = stream[4]
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@value = stream[2]
|
@value = stream[2]
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@reference = reference
|
@reference = reference
|
||||||
@external = nil
|
@external = nil
|
||||||
@name = stream
|
@name = stream
|
||||||
@value = value
|
@value = value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Evaluates whether the given string matchs an entity definition,
|
# Evaluates whether the given string matchs an entity definition,
|
||||||
# returning true if so, and false otherwise.
|
# returning true if so, and false otherwise.
|
||||||
def Entity::matches? string
|
def Entity::matches? string
|
||||||
(ENTITYDECL =~ string) == 0
|
(ENTITYDECL =~ string) == 0
|
||||||
end
|
end
|
||||||
|
|
||||||
# Evaluates to the unnormalized value of this entity; that is, replacing
|
# Evaluates to the unnormalized value of this entity; that is, replacing
|
||||||
# all entities -- both %ent; and &ent; entities. This differs from
|
# all entities -- both %ent; and &ent; entities. This differs from
|
||||||
# +value()+ in that +value+ only replaces %ent; entities.
|
# +value()+ in that +value+ only replaces %ent; entities.
|
||||||
def unnormalized
|
def unnormalized
|
||||||
document.record_entity_expansion
|
document.record_entity_expansion
|
||||||
v = value()
|
v = value()
|
||||||
return nil if v.nil?
|
return nil if v.nil?
|
||||||
@unnormalized = Text::unnormalize(v, parent)
|
@unnormalized = Text::unnormalize(v, parent)
|
||||||
@unnormalized
|
@unnormalized
|
||||||
end
|
end
|
||||||
|
|
||||||
#once :unnormalized
|
#once :unnormalized
|
||||||
|
|
||||||
# Returns the value of this entity unprocessed -- raw. This is the
|
# Returns the value of this entity unprocessed -- raw. This is the
|
||||||
# normalized value; that is, with all %ent; and &ent; entities intact
|
# normalized value; that is, with all %ent; and &ent; entities intact
|
||||||
def normalized
|
def normalized
|
||||||
@value
|
@value
|
||||||
end
|
end
|
||||||
|
|
||||||
# Write out a fully formed, correct entity definition (assuming the Entity
|
# Write out a fully formed, correct entity definition (assuming the Entity
|
||||||
# object itself is valid.)
|
# object itself is valid.)
|
||||||
#
|
#
|
||||||
# out::
|
# out::
|
||||||
# An object implementing <TT><<<TT> to which the entity will be
|
# An object implementing <TT><<<TT> to which the entity will be
|
||||||
# output
|
# output
|
||||||
# indent::
|
# indent::
|
||||||
# *DEPRECATED* and ignored
|
# *DEPRECATED* and ignored
|
||||||
def write out, indent=-1
|
def write out, indent=-1
|
||||||
out << '<!ENTITY '
|
out << '<!ENTITY '
|
||||||
out << '% ' if @reference
|
out << '% ' if @reference
|
||||||
out << @name
|
out << @name
|
||||||
out << ' '
|
out << ' '
|
||||||
if @external
|
if @external
|
||||||
out << @external << ' '
|
out << @external << ' '
|
||||||
if @pubid
|
if @pubid
|
||||||
q = @pubid.include?('"')?"'":'"'
|
q = @pubid.include?('"')?"'":'"'
|
||||||
out << q << @pubid << q << ' '
|
out << q << @pubid << q << ' '
|
||||||
end
|
end
|
||||||
q = @ref.include?('"')?"'":'"'
|
q = @ref.include?('"')?"'":'"'
|
||||||
out << q << @ref << q
|
out << q << @ref << q
|
||||||
out << ' NDATA ' << @ndata if @ndata
|
out << ' NDATA ' << @ndata if @ndata
|
||||||
else
|
else
|
||||||
q = @value.include?('"')?"'":'"'
|
q = @value.include?('"')?"'":'"'
|
||||||
out << q << @value << q
|
out << q << @value << q
|
||||||
end
|
end
|
||||||
out << '>'
|
out << '>'
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns this entity as a string. See write().
|
# Returns this entity as a string. See write().
|
||||||
def to_s
|
def to_s
|
||||||
rv = ''
|
rv = ''
|
||||||
write rv
|
write rv
|
||||||
rv
|
rv
|
||||||
end
|
end
|
||||||
|
|
||||||
PEREFERENCE_RE = /#{PEREFERENCE}/um
|
PEREFERENCE_RE = /#{PEREFERENCE}/um
|
||||||
# Returns the value of this entity. At the moment, only internal entities
|
# Returns the value of this entity. At the moment, only internal entities
|
||||||
# are processed. If the value contains internal references (IE,
|
# are processed. If the value contains internal references (IE,
|
||||||
# %blah;), those are replaced with their values. IE, if the doctype
|
# %blah;), those are replaced with their values. IE, if the doctype
|
||||||
# contains:
|
# contains:
|
||||||
# <!ENTITY % foo "bar">
|
# <!ENTITY % foo "bar">
|
||||||
# <!ENTITY yada "nanoo %foo; nanoo>
|
# <!ENTITY yada "nanoo %foo; nanoo>
|
||||||
# then:
|
# then:
|
||||||
# doctype.entity('yada').value #-> "nanoo bar nanoo"
|
# doctype.entity('yada').value #-> "nanoo bar nanoo"
|
||||||
def value
|
def value
|
||||||
if @value
|
if @value
|
||||||
matches = @value.scan(PEREFERENCE_RE)
|
matches = @value.scan(PEREFERENCE_RE)
|
||||||
rv = @value.clone
|
rv = @value.clone
|
||||||
if @parent
|
if @parent
|
||||||
matches.each do |entity_reference|
|
matches.each do |entity_reference|
|
||||||
entity_value = @parent.entity( entity_reference[0] )
|
entity_value = @parent.entity( entity_reference[0] )
|
||||||
rv.gsub!( /%#{entity_reference.join};/um, entity_value )
|
rv.gsub!( /%#{entity_reference.join};/um, entity_value )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return rv
|
return rv
|
||||||
end
|
end
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# This is a set of entity constants -- the ones defined in the XML
|
# This is a set of entity constants -- the ones defined in the XML
|
||||||
# specification. These are +gt+, +lt+, +amp+, +quot+ and +apos+.
|
# specification. These are +gt+, +lt+, +amp+, +quot+ and +apos+.
|
||||||
module EntityConst
|
module EntityConst
|
||||||
# +>+
|
# +>+
|
||||||
GT = Entity.new( 'gt', '>' )
|
GT = Entity.new( 'gt', '>' )
|
||||||
# +<+
|
# +<+
|
||||||
LT = Entity.new( 'lt', '<' )
|
LT = Entity.new( 'lt', '<' )
|
||||||
# +&+
|
# +&+
|
||||||
AMP = Entity.new( 'amp', '&' )
|
AMP = Entity.new( 'amp', '&' )
|
||||||
# +"+
|
# +"+
|
||||||
QUOT = Entity.new( 'quot', '"' )
|
QUOT = Entity.new( 'quot', '"' )
|
||||||
# +'+
|
# +'+
|
||||||
APOS = Entity.new( 'apos', "'" )
|
APOS = Entity.new( 'apos', "'" )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,62 +2,62 @@ require "rexml/child"
|
||||||
require "rexml/source"
|
require "rexml/source"
|
||||||
|
|
||||||
module REXML
|
module REXML
|
||||||
# Represents an XML Instruction; IE, <? ... ?>
|
# Represents an XML Instruction; IE, <? ... ?>
|
||||||
# TODO: Add parent arg (3rd arg) to constructor
|
# TODO: Add parent arg (3rd arg) to constructor
|
||||||
class Instruction < Child
|
class Instruction < Child
|
||||||
START = '<\?'
|
START = '<\?'
|
||||||
STOP = '\?>'
|
STOP = '\?>'
|
||||||
|
|
||||||
# target is the "name" of the Instruction; IE, the "tag" in <?tag ...?>
|
# target is the "name" of the Instruction; IE, the "tag" in <?tag ...?>
|
||||||
# content is everything else.
|
# content is everything else.
|
||||||
attr_accessor :target, :content
|
attr_accessor :target, :content
|
||||||
|
|
||||||
# Constructs a new Instruction
|
# Constructs a new Instruction
|
||||||
# @param target can be one of a number of things. If String, then
|
# @param target can be one of a number of things. If String, then
|
||||||
# the target of this instruction is set to this. If an Instruction,
|
# the target of this instruction is set to this. If an Instruction,
|
||||||
# then the Instruction is shallowly cloned (target and content are
|
# then the Instruction is shallowly cloned (target and content are
|
||||||
# copied). If a Source, then the source is scanned and parsed for
|
# copied). If a Source, then the source is scanned and parsed for
|
||||||
# an Instruction declaration.
|
# an Instruction declaration.
|
||||||
# @param content Must be either a String, or a Parent. Can only
|
# @param content Must be either a String, or a Parent. Can only
|
||||||
# be a Parent if the target argument is a Source. Otherwise, this
|
# be a Parent if the target argument is a Source. Otherwise, this
|
||||||
# String is set as the content of this instruction.
|
# String is set as the content of this instruction.
|
||||||
def initialize(target, content=nil)
|
def initialize(target, content=nil)
|
||||||
if target.kind_of? String
|
if target.kind_of? String
|
||||||
super()
|
super()
|
||||||
@target = target
|
@target = target
|
||||||
@content = content
|
@content = content
|
||||||
elsif target.kind_of? Instruction
|
elsif target.kind_of? Instruction
|
||||||
super(content)
|
super(content)
|
||||||
@target = target.target
|
@target = target.target
|
||||||
@content = target.content
|
@content = target.content
|
||||||
end
|
end
|
||||||
@content.strip! if @content
|
@content.strip! if @content
|
||||||
end
|
end
|
||||||
|
|
||||||
def clone
|
def clone
|
||||||
Instruction.new self
|
Instruction.new self
|
||||||
end
|
end
|
||||||
|
|
||||||
# == DEPRECATED
|
# == DEPRECATED
|
||||||
# See the rexml/formatters package
|
# See the rexml/formatters package
|
||||||
#
|
#
|
||||||
def write writer, indent=-1, transitive=false, ie_hack=false
|
def write writer, indent=-1, transitive=false, ie_hack=false
|
||||||
Kernel.warn( "#{self.class.name}.write is deprecated" )
|
Kernel.warn( "#{self.class.name}.write is deprecated" )
|
||||||
indent(writer, indent)
|
indent(writer, indent)
|
||||||
writer << START.sub(/\\/u, '')
|
writer << START.sub(/\\/u, '')
|
||||||
writer << @target
|
writer << @target
|
||||||
writer << ' '
|
writer << ' '
|
||||||
writer << @content
|
writer << @content
|
||||||
writer << STOP.sub(/\\/u, '')
|
writer << STOP.sub(/\\/u, '')
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return true if other is an Instruction, and the content and target
|
# @return true if other is an Instruction, and the content and target
|
||||||
# of the other matches the target and content of this object.
|
# of the other matches the target and content of this object.
|
||||||
def ==( other )
|
def ==( other )
|
||||||
other.kind_of? Instruction and
|
other.kind_of? Instruction and
|
||||||
other.target == @target and
|
other.target == @target and
|
||||||
other.content == @content
|
other.content == @content
|
||||||
end
|
end
|
||||||
|
|
||||||
def node_type
|
def node_type
|
||||||
:processing_instruction
|
:processing_instruction
|
||||||
|
@ -66,5 +66,5 @@ module REXML
|
||||||
def inspect
|
def inspect
|
||||||
"<?p-i #{target} ...?>"
|
"<?p-i #{target} ...?>"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,195 +2,195 @@ require 'rexml/xmltokens'
|
||||||
require 'rexml/light/node'
|
require 'rexml/light/node'
|
||||||
|
|
||||||
# [ :element, parent, name, attributes, children* ]
|
# [ :element, parent, name, attributes, children* ]
|
||||||
# a = Node.new
|
# a = Node.new
|
||||||
# a << "B" # => <a>B</a>
|
# a << "B" # => <a>B</a>
|
||||||
# a.b # => <a>B<b/></a>
|
# a.b # => <a>B<b/></a>
|
||||||
# a.b[1] # => <a>B<b/><b/><a>
|
# a.b[1] # => <a>B<b/><b/><a>
|
||||||
# a.b[1]["x"] = "y" # => <a>B<b/><b x="y"/></a>
|
# a.b[1]["x"] = "y" # => <a>B<b/><b x="y"/></a>
|
||||||
# a.b[0].c # => <a>B<b><c/></b><b x="y"/></a>
|
# a.b[0].c # => <a>B<b><c/></b><b x="y"/></a>
|
||||||
# a.b.c << "D" # => <a>B<b><c>D</c></b><b x="y"/></a>
|
# a.b.c << "D" # => <a>B<b><c>D</c></b><b x="y"/></a>
|
||||||
module REXML
|
module REXML
|
||||||
module Light
|
module Light
|
||||||
# Represents a tagged XML element. Elements are characterized by
|
# Represents a tagged XML element. Elements are characterized by
|
||||||
# having children, attributes, and names, and can themselves be
|
# having children, attributes, and names, and can themselves be
|
||||||
# children.
|
# children.
|
||||||
class Node
|
class Node
|
||||||
NAMESPLIT = /^(?:(#{XMLTokens::NCNAME_STR}):)?(#{XMLTokens::NCNAME_STR})/u
|
NAMESPLIT = /^(?:(#{XMLTokens::NCNAME_STR}):)?(#{XMLTokens::NCNAME_STR})/u
|
||||||
PARENTS = [ :element, :document, :doctype ]
|
PARENTS = [ :element, :document, :doctype ]
|
||||||
# Create a new element.
|
# Create a new element.
|
||||||
def initialize node=nil
|
def initialize node=nil
|
||||||
@node = node
|
@node = node
|
||||||
if node.kind_of? String
|
if node.kind_of? String
|
||||||
node = [ :text, node ]
|
node = [ :text, node ]
|
||||||
elsif node.nil?
|
elsif node.nil?
|
||||||
node = [ :document, nil, nil ]
|
node = [ :document, nil, nil ]
|
||||||
elsif node[0] == :start_element
|
elsif node[0] == :start_element
|
||||||
node[0] = :element
|
node[0] = :element
|
||||||
elsif node[0] == :start_doctype
|
elsif node[0] == :start_doctype
|
||||||
node[0] = :doctype
|
node[0] = :doctype
|
||||||
elsif node[0] == :start_document
|
elsif node[0] == :start_document
|
||||||
node[0] = :document
|
node[0] = :document
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def size
|
def size
|
||||||
if PARENTS.include? @node[0]
|
if PARENTS.include? @node[0]
|
||||||
@node[-1].size
|
@node[-1].size
|
||||||
else
|
else
|
||||||
0
|
0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def each( &block )
|
def each( &block )
|
||||||
size.times { |x| yield( at(x+4) ) }
|
size.times { |x| yield( at(x+4) ) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def name
|
def name
|
||||||
at(2)
|
at(2)
|
||||||
end
|
end
|
||||||
|
|
||||||
def name=( name_str, ns=nil )
|
def name=( name_str, ns=nil )
|
||||||
pfx = ''
|
pfx = ''
|
||||||
pfx = "#{prefix(ns)}:" if ns
|
pfx = "#{prefix(ns)}:" if ns
|
||||||
_old_put(2, "#{pfx}#{name_str}")
|
_old_put(2, "#{pfx}#{name_str}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def parent=( node )
|
def parent=( node )
|
||||||
_old_put(1,node)
|
_old_put(1,node)
|
||||||
end
|
end
|
||||||
|
|
||||||
def local_name
|
def local_name
|
||||||
namesplit
|
namesplit
|
||||||
@name
|
@name
|
||||||
end
|
end
|
||||||
|
|
||||||
def local_name=( name_str )
|
def local_name=( name_str )
|
||||||
_old_put( 1, "#@prefix:#{name_str}" )
|
_old_put( 1, "#@prefix:#{name_str}" )
|
||||||
end
|
end
|
||||||
|
|
||||||
def prefix( namespace=nil )
|
def prefix( namespace=nil )
|
||||||
prefix_of( self, namespace )
|
prefix_of( self, namespace )
|
||||||
end
|
end
|
||||||
|
|
||||||
def namespace( prefix=prefix() )
|
def namespace( prefix=prefix() )
|
||||||
namespace_of( self, prefix )
|
namespace_of( self, prefix )
|
||||||
end
|
end
|
||||||
|
|
||||||
def namespace=( namespace )
|
def namespace=( namespace )
|
||||||
@prefix = prefix( namespace )
|
@prefix = prefix( namespace )
|
||||||
pfx = ''
|
pfx = ''
|
||||||
pfx = "#@prefix:" if @prefix.size > 0
|
pfx = "#@prefix:" if @prefix.size > 0
|
||||||
_old_put(1, "#{pfx}#@name")
|
_old_put(1, "#{pfx}#@name")
|
||||||
end
|
end
|
||||||
|
|
||||||
def []( reference, ns=nil )
|
def []( reference, ns=nil )
|
||||||
if reference.kind_of? String
|
if reference.kind_of? String
|
||||||
pfx = ''
|
pfx = ''
|
||||||
pfx = "#{prefix(ns)}:" if ns
|
pfx = "#{prefix(ns)}:" if ns
|
||||||
at(3)["#{pfx}#{reference}"]
|
at(3)["#{pfx}#{reference}"]
|
||||||
elsif reference.kind_of? Range
|
elsif reference.kind_of? Range
|
||||||
_old_get( Range.new(4+reference.begin, reference.end, reference.exclude_end?) )
|
_old_get( Range.new(4+reference.begin, reference.end, reference.exclude_end?) )
|
||||||
else
|
else
|
||||||
_old_get( 4+reference )
|
_old_get( 4+reference )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def =~( path )
|
def =~( path )
|
||||||
XPath.match( self, path )
|
XPath.match( self, path )
|
||||||
end
|
end
|
||||||
|
|
||||||
# Doesn't handle namespaces yet
|
# Doesn't handle namespaces yet
|
||||||
def []=( reference, ns, value=nil )
|
def []=( reference, ns, value=nil )
|
||||||
if reference.kind_of? String
|
if reference.kind_of? String
|
||||||
value = ns unless value
|
value = ns unless value
|
||||||
at( 3 )[reference] = value
|
at( 3 )[reference] = value
|
||||||
elsif reference.kind_of? Range
|
elsif reference.kind_of? Range
|
||||||
_old_put( Range.new(3+reference.begin, reference.end, reference.exclude_end?), ns )
|
_old_put( Range.new(3+reference.begin, reference.end, reference.exclude_end?), ns )
|
||||||
else
|
else
|
||||||
if value
|
if value
|
||||||
_old_put( 4+reference, ns, value )
|
_old_put( 4+reference, ns, value )
|
||||||
else
|
else
|
||||||
_old_put( 4+reference, ns )
|
_old_put( 4+reference, ns )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Append a child to this element, optionally under a provided namespace.
|
# Append a child to this element, optionally under a provided namespace.
|
||||||
# The namespace argument is ignored if the element argument is an Element
|
# The namespace argument is ignored if the element argument is an Element
|
||||||
# object. Otherwise, the element argument is a string, the namespace (if
|
# object. Otherwise, the element argument is a string, the namespace (if
|
||||||
# provided) is the namespace the element is created in.
|
# provided) is the namespace the element is created in.
|
||||||
def << element
|
def << element
|
||||||
if node_type() == :text
|
if node_type() == :text
|
||||||
at(-1) << element
|
at(-1) << element
|
||||||
else
|
else
|
||||||
newnode = Node.new( element )
|
newnode = Node.new( element )
|
||||||
newnode.parent = self
|
newnode.parent = self
|
||||||
self.push( newnode )
|
self.push( newnode )
|
||||||
end
|
end
|
||||||
at(-1)
|
at(-1)
|
||||||
end
|
end
|
||||||
|
|
||||||
def node_type
|
def node_type
|
||||||
_old_get(0)
|
_old_get(0)
|
||||||
end
|
end
|
||||||
|
|
||||||
def text=( foo )
|
def text=( foo )
|
||||||
replace = at(4).kind_of?(String)? 1 : 0
|
replace = at(4).kind_of?(String)? 1 : 0
|
||||||
self._old_put(4,replace, normalizefoo)
|
self._old_put(4,replace, normalizefoo)
|
||||||
end
|
end
|
||||||
|
|
||||||
def root
|
def root
|
||||||
context = self
|
context = self
|
||||||
context = context.at(1) while context.at(1)
|
context = context.at(1) while context.at(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_name?( name, namespace = '' )
|
def has_name?( name, namespace = '' )
|
||||||
at(3) == name and namespace() == namespace
|
at(3) == name and namespace() == namespace
|
||||||
end
|
end
|
||||||
|
|
||||||
def children
|
def children
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
def parent
|
def parent
|
||||||
at(1)
|
at(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def namesplit
|
def namesplit
|
||||||
return if @name.defined?
|
return if @name.defined?
|
||||||
at(2) =~ NAMESPLIT
|
at(2) =~ NAMESPLIT
|
||||||
@prefix = '' || $1
|
@prefix = '' || $1
|
||||||
@name = $2
|
@name = $2
|
||||||
end
|
end
|
||||||
|
|
||||||
def namespace_of( node, prefix=nil )
|
def namespace_of( node, prefix=nil )
|
||||||
if not prefix
|
if not prefix
|
||||||
name = at(2)
|
name = at(2)
|
||||||
name =~ NAMESPLIT
|
name =~ NAMESPLIT
|
||||||
prefix = $1
|
prefix = $1
|
||||||
end
|
end
|
||||||
to_find = 'xmlns'
|
to_find = 'xmlns'
|
||||||
to_find = "xmlns:#{prefix}" if not prefix.nil?
|
to_find = "xmlns:#{prefix}" if not prefix.nil?
|
||||||
ns = at(3)[ to_find ]
|
ns = at(3)[ to_find ]
|
||||||
ns ? ns : namespace_of( @node[0], prefix )
|
ns ? ns : namespace_of( @node[0], prefix )
|
||||||
end
|
end
|
||||||
|
|
||||||
def prefix_of( node, namespace=nil )
|
def prefix_of( node, namespace=nil )
|
||||||
if not namespace
|
if not namespace
|
||||||
name = node.name
|
name = node.name
|
||||||
name =~ NAMESPLIT
|
name =~ NAMESPLIT
|
||||||
$1
|
$1
|
||||||
else
|
else
|
||||||
ns = at(3).find { |k,v| v == namespace }
|
ns = at(3).find { |k,v| v == namespace }
|
||||||
ns ? ns : prefix_of( node.parent, namespace )
|
ns ? ns : prefix_of( node.parent, namespace )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,47 +1,47 @@
|
||||||
require 'rexml/xmltokens'
|
require 'rexml/xmltokens'
|
||||||
|
|
||||||
module REXML
|
module REXML
|
||||||
# Adds named attributes to an object.
|
# Adds named attributes to an object.
|
||||||
module Namespace
|
module Namespace
|
||||||
# The name of the object, valid if set
|
# The name of the object, valid if set
|
||||||
attr_reader :name, :expanded_name
|
attr_reader :name, :expanded_name
|
||||||
# The expanded name of the object, valid if name is set
|
# The expanded name of the object, valid if name is set
|
||||||
attr_accessor :prefix
|
attr_accessor :prefix
|
||||||
include XMLTokens
|
include XMLTokens
|
||||||
NAMESPLIT = /^(?:(#{NCNAME_STR}):)?(#{NCNAME_STR})/u
|
NAMESPLIT = /^(?:(#{NCNAME_STR}):)?(#{NCNAME_STR})/u
|
||||||
|
|
||||||
# Sets the name and the expanded name
|
# Sets the name and the expanded name
|
||||||
def name=( name )
|
def name=( name )
|
||||||
@expanded_name = name
|
@expanded_name = name
|
||||||
name =~ NAMESPLIT
|
name =~ NAMESPLIT
|
||||||
if $1
|
if $1
|
||||||
@prefix = $1
|
@prefix = $1
|
||||||
else
|
else
|
||||||
@prefix = ""
|
@prefix = ""
|
||||||
@namespace = ""
|
@namespace = ""
|
||||||
end
|
end
|
||||||
@name = $2
|
@name = $2
|
||||||
end
|
end
|
||||||
|
|
||||||
# Compares names optionally WITH namespaces
|
# Compares names optionally WITH namespaces
|
||||||
def has_name?( other, ns=nil )
|
def has_name?( other, ns=nil )
|
||||||
if ns
|
if ns
|
||||||
return (namespace() == ns and name() == other)
|
return (namespace() == ns and name() == other)
|
||||||
elsif other.include? ":"
|
elsif other.include? ":"
|
||||||
return fully_expanded_name == other
|
return fully_expanded_name == other
|
||||||
else
|
else
|
||||||
return name == other
|
return name == other
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
alias :local_name :name
|
alias :local_name :name
|
||||||
|
|
||||||
# Fully expand the name, even if the prefix wasn't specified in the
|
# Fully expand the name, even if the prefix wasn't specified in the
|
||||||
# source file.
|
# source file.
|
||||||
def fully_expanded_name
|
def fully_expanded_name
|
||||||
ns = prefix
|
ns = prefix
|
||||||
return "#{ns}:#@name" if ns.size > 0
|
return "#{ns}:#@name" if ns.size > 0
|
||||||
return @name
|
return @name
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,27 +3,27 @@ require "rexml/formatters/pretty"
|
||||||
require "rexml/formatters/default"
|
require "rexml/formatters/default"
|
||||||
|
|
||||||
module REXML
|
module REXML
|
||||||
# Represents a node in the tree. Nodes are never encountered except as
|
# Represents a node in the tree. Nodes are never encountered except as
|
||||||
# superclasses of other objects. Nodes have siblings.
|
# superclasses of other objects. Nodes have siblings.
|
||||||
module Node
|
module Node
|
||||||
# @return the next sibling (nil if unset)
|
# @return the next sibling (nil if unset)
|
||||||
def next_sibling_node
|
def next_sibling_node
|
||||||
return nil if @parent.nil?
|
return nil if @parent.nil?
|
||||||
@parent[ @parent.index(self) + 1 ]
|
@parent[ @parent.index(self) + 1 ]
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return the previous sibling (nil if unset)
|
# @return the previous sibling (nil if unset)
|
||||||
def previous_sibling_node
|
def previous_sibling_node
|
||||||
return nil if @parent.nil?
|
return nil if @parent.nil?
|
||||||
ind = @parent.index(self)
|
ind = @parent.index(self)
|
||||||
return nil if ind == 0
|
return nil if ind == 0
|
||||||
@parent[ ind - 1 ]
|
@parent[ ind - 1 ]
|
||||||
end
|
end
|
||||||
|
|
||||||
# indent::
|
# indent::
|
||||||
# *DEPRECATED* This parameter is now ignored. See the formatters in the
|
# *DEPRECATED* This parameter is now ignored. See the formatters in the
|
||||||
# REXML::Formatters package for changing the output style.
|
# REXML::Formatters package for changing the output style.
|
||||||
def to_s indent=nil
|
def to_s indent=nil
|
||||||
unless indent.nil?
|
unless indent.nil?
|
||||||
Kernel.warn( "#{self.class.name}.to_s(indent) parameter is deprecated" )
|
Kernel.warn( "#{self.class.name}.to_s(indent) parameter is deprecated" )
|
||||||
f = REXML::Formatters::Pretty.new( indent )
|
f = REXML::Formatters::Pretty.new( indent )
|
||||||
|
@ -33,33 +33,33 @@ module REXML
|
||||||
f.write( self, rv = "" )
|
f.write( self, rv = "" )
|
||||||
end
|
end
|
||||||
return rv
|
return rv
|
||||||
end
|
end
|
||||||
|
|
||||||
def indent to, ind
|
def indent to, ind
|
||||||
if @parent and @parent.context and not @parent.context[:indentstyle].nil? then
|
if @parent and @parent.context and not @parent.context[:indentstyle].nil? then
|
||||||
indentstyle = @parent.context[:indentstyle]
|
indentstyle = @parent.context[:indentstyle]
|
||||||
else
|
else
|
||||||
indentstyle = ' '
|
indentstyle = ' '
|
||||||
end
|
end
|
||||||
to << indentstyle*ind unless ind<1
|
to << indentstyle*ind unless ind<1
|
||||||
end
|
end
|
||||||
|
|
||||||
def parent?
|
def parent?
|
||||||
false;
|
false;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# Visit all subnodes of +self+ recursively
|
# Visit all subnodes of +self+ recursively
|
||||||
def each_recursive(&block) # :yields: node
|
def each_recursive(&block) # :yields: node
|
||||||
self.elements.each {|node|
|
self.elements.each {|node|
|
||||||
block.call(node)
|
block.call(node)
|
||||||
node.each_recursive(&block)
|
node.each_recursive(&block)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
# Find (and return) first subnode (recursively) for which the block
|
# Find (and return) first subnode (recursively) for which the block
|
||||||
# evaluates to true. Returns +nil+ if none was found.
|
# evaluates to true. Returns +nil+ if none was found.
|
||||||
def find_first_recursive(&block) # :yields: node
|
def find_first_recursive(&block) # :yields: node
|
||||||
each_recursive {|node|
|
each_recursive {|node|
|
||||||
return node if block.call(node)
|
return node if block.call(node)
|
||||||
}
|
}
|
||||||
|
@ -71,5 +71,5 @@ module REXML
|
||||||
def index_in_parent
|
def index_in_parent
|
||||||
parent.index(self)+1
|
parent.index(self)+1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
require 'rexml/encoding'
|
require 'rexml/encoding'
|
||||||
|
|
||||||
module REXML
|
module REXML
|
||||||
class Output
|
class Output
|
||||||
include Encoding
|
include Encoding
|
||||||
|
|
||||||
attr_reader :encoding
|
attr_reader :encoding
|
||||||
|
|
||||||
def initialize real_IO, encd="iso-8859-1"
|
def initialize real_IO, encd="iso-8859-1"
|
||||||
@output = real_IO
|
@output = real_IO
|
||||||
self.encoding = encd
|
self.encoding = encd
|
||||||
|
|
||||||
@to_utf = encd == UTF_8 ? false : true
|
@to_utf = encd == UTF_8 ? false : true
|
||||||
end
|
end
|
||||||
|
|
||||||
def <<( content )
|
def <<( content )
|
||||||
@output << (@to_utf ? self.encode(content) : content)
|
@output << (@to_utf ? self.encode(content) : content)
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
"Output[#{encoding}]"
|
"Output[#{encoding}]"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,12 +3,12 @@ require 'rexml/parsers/baseparser'
|
||||||
require 'rexml/light/node'
|
require 'rexml/light/node'
|
||||||
|
|
||||||
module REXML
|
module REXML
|
||||||
module Parsers
|
module Parsers
|
||||||
class LightParser
|
class LightParser
|
||||||
def initialize stream
|
def initialize stream
|
||||||
@stream = stream
|
@stream = stream
|
||||||
@parser = REXML::Parsers::BaseParser.new( stream )
|
@parser = REXML::Parsers::BaseParser.new( stream )
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_listener( listener )
|
def add_listener( listener )
|
||||||
@parser.add_listener( listener )
|
@parser.add_listener( listener )
|
||||||
|
@ -19,42 +19,42 @@ module REXML
|
||||||
@parser.stream = @stream
|
@parser.stream = @stream
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse
|
def parse
|
||||||
root = context = [ :document ]
|
root = context = [ :document ]
|
||||||
while true
|
while true
|
||||||
event = @parser.pull
|
event = @parser.pull
|
||||||
case event[0]
|
case event[0]
|
||||||
when :end_document
|
when :end_document
|
||||||
break
|
break
|
||||||
when :end_doctype
|
when :end_doctype
|
||||||
context = context[1]
|
context = context[1]
|
||||||
when :start_element, :start_doctype
|
when :start_element, :start_doctype
|
||||||
new_node = event
|
new_node = event
|
||||||
context << new_node
|
context << new_node
|
||||||
new_node[1,0] = [context]
|
new_node[1,0] = [context]
|
||||||
context = new_node
|
context = new_node
|
||||||
when :end_element, :end_doctype
|
when :end_element, :end_doctype
|
||||||
context = context[1]
|
context = context[1]
|
||||||
else
|
else
|
||||||
new_node = event
|
new_node = event
|
||||||
context << new_node
|
context << new_node
|
||||||
new_node[1,0] = [context]
|
new_node[1,0] = [context]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
root
|
root
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# An element is an array. The array contains:
|
# An element is an array. The array contains:
|
||||||
# 0 The parent element
|
# 0 The parent element
|
||||||
# 1 The tag name
|
# 1 The tag name
|
||||||
# 2 A hash of attributes
|
# 2 A hash of attributes
|
||||||
# 3..-1 The child elements
|
# 3..-1 The child elements
|
||||||
# An element is an array of size > 3
|
# An element is an array of size > 3
|
||||||
# Text is a String
|
# Text is a String
|
||||||
# PIs are [ :processing_instruction, target, data ]
|
# PIs are [ :processing_instruction, target, data ]
|
||||||
# Comments are [ :comment, data ]
|
# Comments are [ :comment, data ]
|
||||||
# DocTypes are DocType structs
|
# DocTypes are DocType structs
|
||||||
# The root is an array with XMLDecls, Text, DocType, Array, Text
|
# The root is an array with XMLDecls, Text, DocType, Array, Text
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,158 +4,158 @@ require 'rexml/namespace'
|
||||||
require 'rexml/text'
|
require 'rexml/text'
|
||||||
|
|
||||||
module REXML
|
module REXML
|
||||||
module Parsers
|
module Parsers
|
||||||
# SAX2Parser
|
# SAX2Parser
|
||||||
class SAX2Parser
|
class SAX2Parser
|
||||||
def initialize source
|
def initialize source
|
||||||
@parser = BaseParser.new(source)
|
@parser = BaseParser.new(source)
|
||||||
@listeners = []
|
@listeners = []
|
||||||
@procs = []
|
@procs = []
|
||||||
@namespace_stack = []
|
@namespace_stack = []
|
||||||
@has_listeners = false
|
@has_listeners = false
|
||||||
@tag_stack = []
|
@tag_stack = []
|
||||||
@entities = {}
|
@entities = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
def source
|
def source
|
||||||
@parser.source
|
@parser.source
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_listener( listener )
|
def add_listener( listener )
|
||||||
@parser.add_listener( listener )
|
@parser.add_listener( listener )
|
||||||
end
|
end
|
||||||
|
|
||||||
# Listen arguments:
|
# Listen arguments:
|
||||||
#
|
#
|
||||||
# Symbol, Array, Block
|
# Symbol, Array, Block
|
||||||
# Listen to Symbol events on Array elements
|
# Listen to Symbol events on Array elements
|
||||||
# Symbol, Block
|
# Symbol, Block
|
||||||
# Listen to Symbol events
|
# Listen to Symbol events
|
||||||
# Array, Listener
|
# Array, Listener
|
||||||
# Listen to all events on Array elements
|
# Listen to all events on Array elements
|
||||||
# Array, Block
|
# Array, Block
|
||||||
# Listen to :start_element events on Array elements
|
# Listen to :start_element events on Array elements
|
||||||
# Listener
|
# Listener
|
||||||
# Listen to All events
|
# Listen to All events
|
||||||
#
|
#
|
||||||
# Symbol can be one of: :start_element, :end_element,
|
# Symbol can be one of: :start_element, :end_element,
|
||||||
# :start_prefix_mapping, :end_prefix_mapping, :characters,
|
# :start_prefix_mapping, :end_prefix_mapping, :characters,
|
||||||
# :processing_instruction, :doctype, :attlistdecl, :elementdecl,
|
# :processing_instruction, :doctype, :attlistdecl, :elementdecl,
|
||||||
# :entitydecl, :notationdecl, :cdata, :xmldecl, :comment
|
# :entitydecl, :notationdecl, :cdata, :xmldecl, :comment
|
||||||
#
|
#
|
||||||
# There is an additional symbol that can be listened for: :progress.
|
# There is an additional symbol that can be listened for: :progress.
|
||||||
# This will be called for every event generated, passing in the current
|
# This will be called for every event generated, passing in the current
|
||||||
# stream position.
|
# stream position.
|
||||||
#
|
#
|
||||||
# Array contains regular expressions or strings which will be matched
|
# Array contains regular expressions or strings which will be matched
|
||||||
# against fully qualified element names.
|
# against fully qualified element names.
|
||||||
#
|
#
|
||||||
# Listener must implement the methods in SAX2Listener
|
# Listener must implement the methods in SAX2Listener
|
||||||
#
|
#
|
||||||
# Block will be passed the same arguments as a SAX2Listener method would
|
# Block will be passed the same arguments as a SAX2Listener method would
|
||||||
# be, where the method name is the same as the matched Symbol.
|
# be, where the method name is the same as the matched Symbol.
|
||||||
# See the SAX2Listener for more information.
|
# See the SAX2Listener for more information.
|
||||||
def listen( *args, &blok )
|
def listen( *args, &blok )
|
||||||
if args[0].kind_of? Symbol
|
if args[0].kind_of? Symbol
|
||||||
if args.size == 2
|
if args.size == 2
|
||||||
args[1].each { |match| @procs << [args[0], match, blok] }
|
args[1].each { |match| @procs << [args[0], match, blok] }
|
||||||
else
|
else
|
||||||
add( [args[0], nil, blok] )
|
add( [args[0], nil, blok] )
|
||||||
end
|
end
|
||||||
elsif args[0].kind_of? Array
|
elsif args[0].kind_of? Array
|
||||||
if args.size == 2
|
if args.size == 2
|
||||||
args[0].each { |match| add( [nil, match, args[1]] ) }
|
args[0].each { |match| add( [nil, match, args[1]] ) }
|
||||||
else
|
else
|
||||||
args[0].each { |match| add( [ :start_element, match, blok ] ) }
|
args[0].each { |match| add( [ :start_element, match, blok ] ) }
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
add([nil, nil, args[0]])
|
add([nil, nil, args[0]])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def deafen( listener=nil, &blok )
|
def deafen( listener=nil, &blok )
|
||||||
if listener
|
if listener
|
||||||
@listeners.delete_if {|item| item[-1] == listener }
|
@listeners.delete_if {|item| item[-1] == listener }
|
||||||
@has_listeners = false if @listeners.size == 0
|
@has_listeners = false if @listeners.size == 0
|
||||||
else
|
else
|
||||||
@procs.delete_if {|item| item[-1] == blok }
|
@procs.delete_if {|item| item[-1] == blok }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse
|
def parse
|
||||||
@procs.each { |sym,match,block| block.call if sym == :start_document }
|
@procs.each { |sym,match,block| block.call if sym == :start_document }
|
||||||
@listeners.each { |sym,match,block|
|
@listeners.each { |sym,match,block|
|
||||||
block.start_document if sym == :start_document or sym.nil?
|
block.start_document if sym == :start_document or sym.nil?
|
||||||
}
|
}
|
||||||
root = context = []
|
root = context = []
|
||||||
while true
|
while true
|
||||||
event = @parser.pull
|
event = @parser.pull
|
||||||
case event[0]
|
case event[0]
|
||||||
when :end_document
|
when :end_document
|
||||||
handle( :end_document )
|
handle( :end_document )
|
||||||
break
|
break
|
||||||
when :start_doctype
|
when :start_doctype
|
||||||
handle( :doctype, *event[1..-1])
|
handle( :doctype, *event[1..-1])
|
||||||
when :end_doctype
|
when :end_doctype
|
||||||
context = context[1]
|
context = context[1]
|
||||||
when :start_element
|
when :start_element
|
||||||
@tag_stack.push(event[1])
|
@tag_stack.push(event[1])
|
||||||
# find the observers for namespaces
|
# find the observers for namespaces
|
||||||
procs = get_procs( :start_prefix_mapping, event[1] )
|
procs = get_procs( :start_prefix_mapping, event[1] )
|
||||||
listeners = get_listeners( :start_prefix_mapping, event[1] )
|
listeners = get_listeners( :start_prefix_mapping, event[1] )
|
||||||
if procs or listeners
|
if procs or listeners
|
||||||
# break out the namespace declarations
|
# break out the namespace declarations
|
||||||
# The attributes live in event[2]
|
# The attributes live in event[2]
|
||||||
event[2].each {|n, v| event[2][n] = @parser.normalize(v)}
|
event[2].each {|n, v| event[2][n] = @parser.normalize(v)}
|
||||||
nsdecl = event[2].find_all { |n, value| n =~ /^xmlns(:|$)/ }
|
nsdecl = event[2].find_all { |n, value| n =~ /^xmlns(:|$)/ }
|
||||||
nsdecl.collect! { |n, value| [ n[6..-1], value ] }
|
nsdecl.collect! { |n, value| [ n[6..-1], value ] }
|
||||||
@namespace_stack.push({})
|
@namespace_stack.push({})
|
||||||
nsdecl.each do |n,v|
|
nsdecl.each do |n,v|
|
||||||
@namespace_stack[-1][n] = v
|
@namespace_stack[-1][n] = v
|
||||||
# notify observers of namespaces
|
# notify observers of namespaces
|
||||||
procs.each { |ob| ob.call( n, v ) } if procs
|
procs.each { |ob| ob.call( n, v ) } if procs
|
||||||
listeners.each { |ob| ob.start_prefix_mapping(n, v) } if listeners
|
listeners.each { |ob| ob.start_prefix_mapping(n, v) } if listeners
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
event[1] =~ Namespace::NAMESPLIT
|
event[1] =~ Namespace::NAMESPLIT
|
||||||
prefix = $1
|
prefix = $1
|
||||||
local = $2
|
local = $2
|
||||||
uri = get_namespace(prefix)
|
uri = get_namespace(prefix)
|
||||||
# find the observers for start_element
|
# find the observers for start_element
|
||||||
procs = get_procs( :start_element, event[1] )
|
procs = get_procs( :start_element, event[1] )
|
||||||
listeners = get_listeners( :start_element, event[1] )
|
listeners = get_listeners( :start_element, event[1] )
|
||||||
# notify observers
|
# notify observers
|
||||||
procs.each { |ob| ob.call( uri, local, event[1], event[2] ) } if procs
|
procs.each { |ob| ob.call( uri, local, event[1], event[2] ) } if procs
|
||||||
listeners.each { |ob|
|
listeners.each { |ob|
|
||||||
ob.start_element( uri, local, event[1], event[2] )
|
ob.start_element( uri, local, event[1], event[2] )
|
||||||
} if listeners
|
} if listeners
|
||||||
when :end_element
|
when :end_element
|
||||||
@tag_stack.pop
|
@tag_stack.pop
|
||||||
event[1] =~ Namespace::NAMESPLIT
|
event[1] =~ Namespace::NAMESPLIT
|
||||||
prefix = $1
|
prefix = $1
|
||||||
local = $2
|
local = $2
|
||||||
uri = get_namespace(prefix)
|
uri = get_namespace(prefix)
|
||||||
# find the observers for start_element
|
# find the observers for start_element
|
||||||
procs = get_procs( :end_element, event[1] )
|
procs = get_procs( :end_element, event[1] )
|
||||||
listeners = get_listeners( :end_element, event[1] )
|
listeners = get_listeners( :end_element, event[1] )
|
||||||
# notify observers
|
# notify observers
|
||||||
procs.each { |ob| ob.call( uri, local, event[1] ) } if procs
|
procs.each { |ob| ob.call( uri, local, event[1] ) } if procs
|
||||||
listeners.each { |ob|
|
listeners.each { |ob|
|
||||||
ob.end_element( uri, local, event[1] )
|
ob.end_element( uri, local, event[1] )
|
||||||
} if listeners
|
} if listeners
|
||||||
|
|
||||||
namespace_mapping = @namespace_stack.pop
|
namespace_mapping = @namespace_stack.pop
|
||||||
# find the observers for namespaces
|
# find the observers for namespaces
|
||||||
procs = get_procs( :end_prefix_mapping, event[1] )
|
procs = get_procs( :end_prefix_mapping, event[1] )
|
||||||
listeners = get_listeners( :end_prefix_mapping, event[1] )
|
listeners = get_listeners( :end_prefix_mapping, event[1] )
|
||||||
if procs or listeners
|
if procs or listeners
|
||||||
namespace_mapping.each do |ns_prefix, ns_uri|
|
namespace_mapping.each do |ns_prefix, ns_uri|
|
||||||
# notify observers of namespaces
|
# notify observers of namespaces
|
||||||
procs.each { |ob| ob.call( ns_prefix ) } if procs
|
procs.each { |ob| ob.call( ns_prefix ) } if procs
|
||||||
listeners.each { |ob| ob.end_prefix_mapping(ns_prefix) } if listeners
|
listeners.each { |ob| ob.end_prefix_mapping(ns_prefix) } if listeners
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
when :text
|
when :text
|
||||||
#normalized = @parser.normalize( event[1] )
|
#normalized = @parser.normalize( event[1] )
|
||||||
#handle( :characters, normalized )
|
#handle( :characters, normalized )
|
||||||
copy = event[1].clone
|
copy = event[1].clone
|
||||||
|
@ -177,71 +177,71 @@ module REXML
|
||||||
handle( :characters, copy )
|
handle( :characters, copy )
|
||||||
when :entitydecl
|
when :entitydecl
|
||||||
@entities[ event[1] ] = event[2] if event.size == 3
|
@entities[ event[1] ] = event[2] if event.size == 3
|
||||||
handle( *event )
|
handle( *event )
|
||||||
when :processing_instruction, :comment, :attlistdecl,
|
when :processing_instruction, :comment, :attlistdecl,
|
||||||
:elementdecl, :cdata, :notationdecl, :xmldecl
|
:elementdecl, :cdata, :notationdecl, :xmldecl
|
||||||
handle( *event )
|
handle( *event )
|
||||||
end
|
end
|
||||||
handle( :progress, @parser.position )
|
handle( :progress, @parser.position )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def handle( symbol, *arguments )
|
def handle( symbol, *arguments )
|
||||||
tag = @tag_stack[-1]
|
tag = @tag_stack[-1]
|
||||||
procs = get_procs( symbol, tag )
|
procs = get_procs( symbol, tag )
|
||||||
listeners = get_listeners( symbol, tag )
|
listeners = get_listeners( symbol, tag )
|
||||||
# notify observers
|
# notify observers
|
||||||
procs.each { |ob| ob.call( *arguments ) } if procs
|
procs.each { |ob| ob.call( *arguments ) } if procs
|
||||||
listeners.each { |l|
|
listeners.each { |l|
|
||||||
l.send( symbol.to_s, *arguments )
|
l.send( symbol.to_s, *arguments )
|
||||||
} if listeners
|
} if listeners
|
||||||
end
|
end
|
||||||
|
|
||||||
# The following methods are duplicates, but it is faster than using
|
# The following methods are duplicates, but it is faster than using
|
||||||
# a helper
|
# a helper
|
||||||
def get_procs( symbol, name )
|
def get_procs( symbol, name )
|
||||||
return nil if @procs.size == 0
|
return nil if @procs.size == 0
|
||||||
@procs.find_all do |sym, match, block|
|
@procs.find_all do |sym, match, block|
|
||||||
#puts sym.inspect+"=="+symbol.inspect+ "\t"+match.inspect+"=="+name.inspect+ "\t"+( (sym.nil? or symbol == sym) and ((name.nil? and match.nil?) or match.nil? or ( (name == match) or (match.kind_of? Regexp and name =~ match)))).to_s
|
#puts sym.inspect+"=="+symbol.inspect+ "\t"+match.inspect+"=="+name.inspect+ "\t"+( (sym.nil? or symbol == sym) and ((name.nil? and match.nil?) or match.nil? or ( (name == match) or (match.kind_of? Regexp and name =~ match)))).to_s
|
||||||
(
|
(
|
||||||
(sym.nil? or symbol == sym) and
|
(sym.nil? or symbol == sym) and
|
||||||
((name.nil? and match.nil?) or match.nil? or (
|
((name.nil? and match.nil?) or match.nil? or (
|
||||||
(name == match) or
|
(name == match) or
|
||||||
(match.kind_of? Regexp and name =~ match)
|
(match.kind_of? Regexp and name =~ match)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
end.collect{|x| x[-1]}
|
end.collect{|x| x[-1]}
|
||||||
end
|
end
|
||||||
def get_listeners( symbol, name )
|
def get_listeners( symbol, name )
|
||||||
return nil if @listeners.size == 0
|
return nil if @listeners.size == 0
|
||||||
@listeners.find_all do |sym, match, block|
|
@listeners.find_all do |sym, match, block|
|
||||||
(
|
(
|
||||||
(sym.nil? or symbol == sym) and
|
(sym.nil? or symbol == sym) and
|
||||||
((name.nil? and match.nil?) or match.nil? or (
|
((name.nil? and match.nil?) or match.nil? or (
|
||||||
(name == match) or
|
(name == match) or
|
||||||
(match.kind_of? Regexp and name =~ match)
|
(match.kind_of? Regexp and name =~ match)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
end.collect{|x| x[-1]}
|
end.collect{|x| x[-1]}
|
||||||
end
|
end
|
||||||
|
|
||||||
def add( pair )
|
def add( pair )
|
||||||
if pair[-1].respond_to? :call
|
if pair[-1].respond_to? :call
|
||||||
@procs << pair unless @procs.include? pair
|
@procs << pair unless @procs.include? pair
|
||||||
else
|
else
|
||||||
@listeners << pair unless @listeners.include? pair
|
@listeners << pair unless @listeners.include? pair
|
||||||
@has_listeners = true
|
@has_listeners = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_namespace( prefix )
|
def get_namespace( prefix )
|
||||||
uris = (@namespace_stack.find_all { |ns| not ns[prefix].nil? }) ||
|
uris = (@namespace_stack.find_all { |ns| not ns[prefix].nil? }) ||
|
||||||
(@namespace_stack.find { |ns| not ns[nil].nil? })
|
(@namespace_stack.find { |ns| not ns[nil].nil? })
|
||||||
uris[-1][prefix] unless uris.nil? or 0 == uris.size
|
uris[-1][prefix] unless uris.nil? or 0 == uris.size
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,12 +2,12 @@ require 'rexml/parsers/streamparser'
|
||||||
require 'rexml/parsers/baseparser'
|
require 'rexml/parsers/baseparser'
|
||||||
|
|
||||||
module REXML
|
module REXML
|
||||||
module Parsers
|
module Parsers
|
||||||
class UltraLightParser
|
class UltraLightParser
|
||||||
def initialize stream
|
def initialize stream
|
||||||
@stream = stream
|
@stream = stream
|
||||||
@parser = REXML::Parsers::BaseParser.new( stream )
|
@parser = REXML::Parsers::BaseParser.new( stream )
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_listener( listener )
|
def add_listener( listener )
|
||||||
@parser.add_listener( listener )
|
@parser.add_listener( listener )
|
||||||
|
@ -18,39 +18,39 @@ module REXML
|
||||||
@parser.stream = @stream
|
@parser.stream = @stream
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse
|
def parse
|
||||||
root = context = []
|
root = context = []
|
||||||
while true
|
while true
|
||||||
event = @parser.pull
|
event = @parser.pull
|
||||||
case event[0]
|
case event[0]
|
||||||
when :end_document
|
when :end_document
|
||||||
break
|
break
|
||||||
when :end_doctype
|
when :end_doctype
|
||||||
context = context[1]
|
context = context[1]
|
||||||
when :start_element, :doctype
|
when :start_element, :doctype
|
||||||
context << event
|
context << event
|
||||||
event[1,0] = [context]
|
event[1,0] = [context]
|
||||||
context = event
|
context = event
|
||||||
when :end_element
|
when :end_element
|
||||||
context = context[1]
|
context = context[1]
|
||||||
else
|
else
|
||||||
context << event
|
context << event
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
root
|
root
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# An element is an array. The array contains:
|
# An element is an array. The array contains:
|
||||||
# 0 The parent element
|
# 0 The parent element
|
||||||
# 1 The tag name
|
# 1 The tag name
|
||||||
# 2 A hash of attributes
|
# 2 A hash of attributes
|
||||||
# 3..-1 The child elements
|
# 3..-1 The child elements
|
||||||
# An element is an array of size > 3
|
# An element is an array of size > 3
|
||||||
# Text is a String
|
# Text is a String
|
||||||
# PIs are [ :processing_instruction, target, data ]
|
# PIs are [ :processing_instruction, target, data ]
|
||||||
# Comments are [ :comment, data ]
|
# Comments are [ :comment, data ]
|
||||||
# DocTypes are DocType structs
|
# DocTypes are DocType structs
|
||||||
# The root is an array with XMLDecls, Text, DocType, Array, Text
|
# The root is an array with XMLDecls, Text, DocType, Array, Text
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -39,10 +39,10 @@ module REXML
|
||||||
case op
|
case op
|
||||||
when :node
|
when :node
|
||||||
when :attribute
|
when :attribute
|
||||||
string << "/" if string.size > 0
|
string << "/" if string.size > 0
|
||||||
string << "@"
|
string << "@"
|
||||||
when :child
|
when :child
|
||||||
string << "/" if string.size > 0
|
string << "/" if string.size > 0
|
||||||
when :descendant_or_self
|
when :descendant_or_self
|
||||||
string << "/"
|
string << "/"
|
||||||
when :self
|
when :self
|
||||||
|
@ -51,8 +51,8 @@ module REXML
|
||||||
string << ".."
|
string << ".."
|
||||||
when :any
|
when :any
|
||||||
string << "*"
|
string << "*"
|
||||||
when :text
|
when :text
|
||||||
string << "text()"
|
string << "text()"
|
||||||
when :following, :following_sibling,
|
when :following, :following_sibling,
|
||||||
:ancestor, :ancestor_or_self, :descendant,
|
:ancestor, :ancestor_or_self, :descendant,
|
||||||
:namespace, :preceding, :preceding_sibling
|
:namespace, :preceding, :preceding_sibling
|
||||||
|
@ -70,13 +70,13 @@ module REXML
|
||||||
string << ']'
|
string << ']'
|
||||||
when :document
|
when :document
|
||||||
document = true
|
document = true
|
||||||
when :function
|
when :function
|
||||||
string << path.shift
|
string << path.shift
|
||||||
string << "( "
|
string << "( "
|
||||||
string << predicate_to_string( path.shift[0] ) {|x| abbreviate( x )}
|
string << predicate_to_string( path.shift[0] ) {|x| abbreviate( x )}
|
||||||
string << " )"
|
string << " )"
|
||||||
when :literal
|
when :literal
|
||||||
string << %Q{ "#{path.shift}" }
|
string << %Q{ "#{path.shift}" }
|
||||||
else
|
else
|
||||||
string << "/" unless string.size == 0
|
string << "/" unless string.size == 0
|
||||||
string << "UNKNOWN("
|
string << "UNKNOWN("
|
||||||
|
@ -84,7 +84,7 @@ module REXML
|
||||||
string << ")"
|
string << ")"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
string = "/"+string if document
|
string = "/"+string if document
|
||||||
return string
|
return string
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -653,39 +653,39 @@ module REXML
|
||||||
def parse_args( string )
|
def parse_args( string )
|
||||||
arguments = []
|
arguments = []
|
||||||
ind = 0
|
ind = 0
|
||||||
inquot = false
|
inquot = false
|
||||||
inapos = false
|
inapos = false
|
||||||
depth = 1
|
depth = 1
|
||||||
begin
|
begin
|
||||||
case string[ind]
|
case string[ind]
|
||||||
when ?"
|
when ?"
|
||||||
inquot = !inquot unless inapos
|
inquot = !inquot unless inapos
|
||||||
when ?'
|
when ?'
|
||||||
inapos = !inapos unless inquot
|
inapos = !inapos unless inquot
|
||||||
else
|
else
|
||||||
unless inquot or inapos
|
unless inquot or inapos
|
||||||
case string[ind]
|
case string[ind]
|
||||||
when ?(
|
when ?(
|
||||||
depth += 1
|
depth += 1
|
||||||
if depth == 1
|
if depth == 1
|
||||||
string = string[1..-1]
|
string = string[1..-1]
|
||||||
ind -= 1
|
ind -= 1
|
||||||
end
|
end
|
||||||
when ?)
|
when ?)
|
||||||
depth -= 1
|
depth -= 1
|
||||||
if depth == 0
|
if depth == 0
|
||||||
s = string[0,ind].strip
|
s = string[0,ind].strip
|
||||||
arguments << s unless s == ""
|
arguments << s unless s == ""
|
||||||
string = string[ind+1..-1]
|
string = string[ind+1..-1]
|
||||||
end
|
end
|
||||||
when ?,
|
when ?,
|
||||||
if depth == 1
|
if depth == 1
|
||||||
s = string[0,ind].strip
|
s = string[0,ind].strip
|
||||||
arguments << s unless s == ""
|
arguments << s unless s == ""
|
||||||
string = string[ind+1..-1]
|
string = string[ind+1..-1]
|
||||||
ind = -1
|
ind = -1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
ind += 1
|
ind += 1
|
||||||
|
|
|
@ -2,262 +2,262 @@ require 'rexml/functions'
|
||||||
require 'rexml/xmltokens'
|
require 'rexml/xmltokens'
|
||||||
|
|
||||||
module REXML
|
module REXML
|
||||||
class QuickPath
|
class QuickPath
|
||||||
include Functions
|
include Functions
|
||||||
include XMLTokens
|
include XMLTokens
|
||||||
|
|
||||||
EMPTY_HASH = {}
|
EMPTY_HASH = {}
|
||||||
|
|
||||||
def QuickPath::first element, path, namespaces=EMPTY_HASH
|
def QuickPath::first element, path, namespaces=EMPTY_HASH
|
||||||
match(element, path, namespaces)[0]
|
match(element, path, namespaces)[0]
|
||||||
end
|
end
|
||||||
|
|
||||||
def QuickPath::each element, path, namespaces=EMPTY_HASH, &block
|
def QuickPath::each element, path, namespaces=EMPTY_HASH, &block
|
||||||
path = "*" unless path
|
path = "*" unless path
|
||||||
match(element, path, namespaces).each( &block )
|
match(element, path, namespaces).each( &block )
|
||||||
end
|
end
|
||||||
|
|
||||||
def QuickPath::match element, path, namespaces=EMPTY_HASH
|
def QuickPath::match element, path, namespaces=EMPTY_HASH
|
||||||
raise "nil is not a valid xpath" unless path
|
raise "nil is not a valid xpath" unless path
|
||||||
results = nil
|
results = nil
|
||||||
Functions::namespace_context = namespaces
|
Functions::namespace_context = namespaces
|
||||||
case path
|
case path
|
||||||
when /^\/([^\/]|$)/u
|
when /^\/([^\/]|$)/u
|
||||||
# match on root
|
# match on root
|
||||||
path = path[1..-1]
|
path = path[1..-1]
|
||||||
return [element.root.parent] if path == ''
|
return [element.root.parent] if path == ''
|
||||||
results = filter([element.root], path)
|
results = filter([element.root], path)
|
||||||
when /^[-\w]*::/u
|
when /^[-\w]*::/u
|
||||||
results = filter([element], path)
|
results = filter([element], path)
|
||||||
when /^\*/u
|
when /^\*/u
|
||||||
results = filter(element.to_a, path)
|
results = filter(element.to_a, path)
|
||||||
when /^[\[!\w:]/u
|
when /^[\[!\w:]/u
|
||||||
# match on child
|
# match on child
|
||||||
matches = []
|
matches = []
|
||||||
children = element.to_a
|
children = element.to_a
|
||||||
results = filter(children, path)
|
results = filter(children, path)
|
||||||
else
|
else
|
||||||
results = filter([element], path)
|
results = filter([element], path)
|
||||||
end
|
end
|
||||||
return results
|
return results
|
||||||
end
|
end
|
||||||
|
|
||||||
# Given an array of nodes it filters the array based on the path. The
|
# Given an array of nodes it filters the array based on the path. The
|
||||||
# result is that when this method returns, the array will contain elements
|
# result is that when this method returns, the array will contain elements
|
||||||
# which match the path
|
# which match the path
|
||||||
def QuickPath::filter elements, path
|
def QuickPath::filter elements, path
|
||||||
return elements if path.nil? or path == '' or elements.size == 0
|
return elements if path.nil? or path == '' or elements.size == 0
|
||||||
case path
|
case path
|
||||||
when /^\/\//u # Descendant
|
when /^\/\//u # Descendant
|
||||||
return axe( elements, "descendant-or-self", $' )
|
return axe( elements, "descendant-or-self", $' )
|
||||||
when /^\/?\b(\w[-\w]*)\b::/u # Axe
|
when /^\/?\b(\w[-\w]*)\b::/u # Axe
|
||||||
axe_name = $1
|
axe_name = $1
|
||||||
rest = $'
|
rest = $'
|
||||||
return axe( elements, $1, $' )
|
return axe( elements, $1, $' )
|
||||||
when /^\/(?=\b([:!\w][-\.\w]*:)?[-!\*\.\w]*\b([^:(]|$)|\*)/u # Child
|
when /^\/(?=\b([:!\w][-\.\w]*:)?[-!\*\.\w]*\b([^:(]|$)|\*)/u # Child
|
||||||
rest = $'
|
rest = $'
|
||||||
results = []
|
results = []
|
||||||
elements.each do |element|
|
elements.each do |element|
|
||||||
results |= filter( element.to_a, rest )
|
results |= filter( element.to_a, rest )
|
||||||
end
|
end
|
||||||
return results
|
return results
|
||||||
when /^\/?(\w[-\w]*)\(/u # / Function
|
when /^\/?(\w[-\w]*)\(/u # / Function
|
||||||
return function( elements, $1, $' )
|
return function( elements, $1, $' )
|
||||||
when Namespace::NAMESPLIT # Element name
|
when Namespace::NAMESPLIT # Element name
|
||||||
name = $2
|
name = $2
|
||||||
ns = $1
|
ns = $1
|
||||||
rest = $'
|
rest = $'
|
||||||
elements.delete_if do |element|
|
elements.delete_if do |element|
|
||||||
!(element.kind_of? Element and
|
!(element.kind_of? Element and
|
||||||
(element.expanded_name == name or
|
(element.expanded_name == name or
|
||||||
(element.name == name and
|
(element.name == name and
|
||||||
element.namespace == Functions.namespace_context[ns])))
|
element.namespace == Functions.namespace_context[ns])))
|
||||||
end
|
end
|
||||||
return filter( elements, rest )
|
return filter( elements, rest )
|
||||||
when /^\/\[/u
|
when /^\/\[/u
|
||||||
matches = []
|
matches = []
|
||||||
elements.each do |element|
|
elements.each do |element|
|
||||||
matches |= predicate( element.to_a, path[1..-1] ) if element.kind_of? Element
|
matches |= predicate( element.to_a, path[1..-1] ) if element.kind_of? Element
|
||||||
end
|
end
|
||||||
return matches
|
return matches
|
||||||
when /^\[/u # Predicate
|
when /^\[/u # Predicate
|
||||||
return predicate( elements, path )
|
return predicate( elements, path )
|
||||||
when /^\/?\.\.\./u # Ancestor
|
when /^\/?\.\.\./u # Ancestor
|
||||||
return axe( elements, "ancestor", $' )
|
return axe( elements, "ancestor", $' )
|
||||||
when /^\/?\.\./u # Parent
|
when /^\/?\.\./u # Parent
|
||||||
return filter( elements.collect{|e|e.parent}, $' )
|
return filter( elements.collect{|e|e.parent}, $' )
|
||||||
when /^\/?\./u # Self
|
when /^\/?\./u # Self
|
||||||
return filter( elements, $' )
|
return filter( elements, $' )
|
||||||
when /^\*/u # Any
|
when /^\*/u # Any
|
||||||
results = []
|
results = []
|
||||||
elements.each do |element|
|
elements.each do |element|
|
||||||
results |= filter( [element], $' ) if element.kind_of? Element
|
results |= filter( [element], $' ) if element.kind_of? Element
|
||||||
#if element.kind_of? Element
|
#if element.kind_of? Element
|
||||||
# children = element.to_a
|
# children = element.to_a
|
||||||
# children.delete_if { |child| !child.kind_of?(Element) }
|
# children.delete_if { |child| !child.kind_of?(Element) }
|
||||||
# results |= filter( children, $' )
|
# results |= filter( children, $' )
|
||||||
#end
|
#end
|
||||||
end
|
end
|
||||||
return results
|
return results
|
||||||
end
|
end
|
||||||
return []
|
return []
|
||||||
end
|
end
|
||||||
|
|
||||||
def QuickPath::axe( elements, axe_name, rest )
|
def QuickPath::axe( elements, axe_name, rest )
|
||||||
matches = []
|
matches = []
|
||||||
matches = filter( elements.dup, rest ) if axe_name =~ /-or-self$/u
|
matches = filter( elements.dup, rest ) if axe_name =~ /-or-self$/u
|
||||||
case axe_name
|
case axe_name
|
||||||
when /^descendant/u
|
when /^descendant/u
|
||||||
elements.each do |element|
|
elements.each do |element|
|
||||||
matches |= filter( element.to_a, "descendant-or-self::#{rest}" ) if element.kind_of? Element
|
matches |= filter( element.to_a, "descendant-or-self::#{rest}" ) if element.kind_of? Element
|
||||||
end
|
end
|
||||||
when /^ancestor/u
|
when /^ancestor/u
|
||||||
elements.each do |element|
|
elements.each do |element|
|
||||||
while element.parent
|
while element.parent
|
||||||
matches << element.parent
|
matches << element.parent
|
||||||
element = element.parent
|
element = element.parent
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
matches = filter( matches, rest )
|
matches = filter( matches, rest )
|
||||||
when "self"
|
when "self"
|
||||||
matches = filter( elements, rest )
|
matches = filter( elements, rest )
|
||||||
when "child"
|
when "child"
|
||||||
elements.each do |element|
|
elements.each do |element|
|
||||||
matches |= filter( element.to_a, rest ) if element.kind_of? Element
|
matches |= filter( element.to_a, rest ) if element.kind_of? Element
|
||||||
end
|
end
|
||||||
when "attribute"
|
when "attribute"
|
||||||
elements.each do |element|
|
elements.each do |element|
|
||||||
matches << element.attributes[ rest ] if element.kind_of? Element
|
matches << element.attributes[ rest ] if element.kind_of? Element
|
||||||
end
|
end
|
||||||
when "parent"
|
when "parent"
|
||||||
matches = filter(elements.collect{|element| element.parent}.uniq, rest)
|
matches = filter(elements.collect{|element| element.parent}.uniq, rest)
|
||||||
when "following-sibling"
|
when "following-sibling"
|
||||||
matches = filter(elements.collect{|element| element.next_sibling}.uniq,
|
matches = filter(elements.collect{|element| element.next_sibling}.uniq,
|
||||||
rest)
|
rest)
|
||||||
when "previous-sibling"
|
when "previous-sibling"
|
||||||
matches = filter(elements.collect{|element|
|
matches = filter(elements.collect{|element|
|
||||||
element.previous_sibling}.uniq, rest )
|
element.previous_sibling}.uniq, rest )
|
||||||
end
|
end
|
||||||
return matches.uniq
|
return matches.uniq
|
||||||
end
|
end
|
||||||
|
|
||||||
# A predicate filters a node-set with respect to an axis to produce a
|
# A predicate filters a node-set with respect to an axis to produce a
|
||||||
# new node-set. For each node in the node-set to be filtered, the
|
# new node-set. For each node in the node-set to be filtered, the
|
||||||
# PredicateExpr is evaluated with that node as the context node, with
|
# PredicateExpr is evaluated with that node as the context node, with
|
||||||
# the number of nodes in the node-set as the context size, and with the
|
# the number of nodes in the node-set as the context size, and with the
|
||||||
# proximity position of the node in the node-set with respect to the
|
# proximity position of the node in the node-set with respect to the
|
||||||
# axis as the context position; if PredicateExpr evaluates to true for
|
# axis as the context position; if PredicateExpr evaluates to true for
|
||||||
# that node, the node is included in the new node-set; otherwise, it is
|
# that node, the node is included in the new node-set; otherwise, it is
|
||||||
# not included.
|
# not included.
|
||||||
#
|
#
|
||||||
# A PredicateExpr is evaluated by evaluating the Expr and converting
|
# A PredicateExpr is evaluated by evaluating the Expr and converting
|
||||||
# the result to a boolean. If the result is a number, the result will
|
# the result to a boolean. If the result is a number, the result will
|
||||||
# be converted to true if the number is equal to the context position
|
# be converted to true if the number is equal to the context position
|
||||||
# and will be converted to false otherwise; if the result is not a
|
# and will be converted to false otherwise; if the result is not a
|
||||||
# number, then the result will be converted as if by a call to the
|
# number, then the result will be converted as if by a call to the
|
||||||
# boolean function. Thus a location path para[3] is equivalent to
|
# boolean function. Thus a location path para[3] is equivalent to
|
||||||
# para[position()=3].
|
# para[position()=3].
|
||||||
def QuickPath::predicate( elements, path )
|
def QuickPath::predicate( elements, path )
|
||||||
ind = 1
|
ind = 1
|
||||||
bcount = 1
|
bcount = 1
|
||||||
while bcount > 0
|
while bcount > 0
|
||||||
bcount += 1 if path[ind] == ?[
|
bcount += 1 if path[ind] == ?[
|
||||||
bcount -= 1 if path[ind] == ?]
|
bcount -= 1 if path[ind] == ?]
|
||||||
ind += 1
|
ind += 1
|
||||||
end
|
end
|
||||||
ind -= 1
|
ind -= 1
|
||||||
predicate = path[1..ind-1]
|
predicate = path[1..ind-1]
|
||||||
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, 'attribute("\1")' )
|
predicate.gsub!( /@(\w[-\w.]*)/u, '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
|
||||||
fname.gsub( /-/u, "_" )
|
fname.gsub( /-/u, "_" )
|
||||||
}
|
}
|
||||||
|
|
||||||
Functions.pair = [ 0, elements.size ]
|
Functions.pair = [ 0, elements.size ]
|
||||||
results = []
|
results = []
|
||||||
elements.each do |element|
|
elements.each do |element|
|
||||||
Functions.pair[0] += 1
|
Functions.pair[0] += 1
|
||||||
Functions.node = element
|
Functions.node = element
|
||||||
res = eval( predicate )
|
res = eval( predicate )
|
||||||
case res
|
case res
|
||||||
when true
|
when true
|
||||||
results << element
|
results << element
|
||||||
when Fixnum
|
when Fixnum
|
||||||
results << element if Functions.pair[0] == res
|
results << element if Functions.pair[0] == res
|
||||||
when String
|
when String
|
||||||
results << element
|
results << element
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return filter( results, rest )
|
return filter( results, rest )
|
||||||
end
|
end
|
||||||
|
|
||||||
def QuickPath::attribute( name )
|
def QuickPath::attribute( name )
|
||||||
return Functions.node.attributes[name] if Functions.node.kind_of? Element
|
return Functions.node.attributes[name] if Functions.node.kind_of? Element
|
||||||
end
|
end
|
||||||
|
|
||||||
def QuickPath::name()
|
def QuickPath::name()
|
||||||
return Functions.node.name if Functions.node.kind_of? Element
|
return Functions.node.name if Functions.node.kind_of? Element
|
||||||
end
|
end
|
||||||
|
|
||||||
def QuickPath::method_missing( id, *args )
|
def QuickPath::method_missing( id, *args )
|
||||||
begin
|
begin
|
||||||
Functions.send( id.id2name, *args )
|
Functions.send( id.id2name, *args )
|
||||||
rescue Exception
|
rescue Exception
|
||||||
raise "METHOD: #{id.id2name}(#{args.join ', '})\n#{$!.message}"
|
raise "METHOD: #{id.id2name}(#{args.join ', '})\n#{$!.message}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def QuickPath::function( elements, fname, rest )
|
def QuickPath::function( elements, fname, rest )
|
||||||
args = parse_args( elements, rest )
|
args = parse_args( elements, rest )
|
||||||
Functions.pair = [0, elements.size]
|
Functions.pair = [0, elements.size]
|
||||||
results = []
|
results = []
|
||||||
elements.each do |element|
|
elements.each do |element|
|
||||||
Functions.pair[0] += 1
|
Functions.pair[0] += 1
|
||||||
Functions.node = element
|
Functions.node = element
|
||||||
res = Functions.send( fname, *args )
|
res = Functions.send( fname, *args )
|
||||||
case res
|
case res
|
||||||
when true
|
when true
|
||||||
results << element
|
results << element
|
||||||
when Fixnum
|
when Fixnum
|
||||||
results << element if Functions.pair[0] == res
|
results << element if Functions.pair[0] == res
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return results
|
return results
|
||||||
end
|
end
|
||||||
|
|
||||||
def QuickPath::parse_args( element, string )
|
def QuickPath::parse_args( element, string )
|
||||||
# /.*?(?:\)|,)/
|
# /.*?(?:\)|,)/
|
||||||
arguments = []
|
arguments = []
|
||||||
buffer = ""
|
buffer = ""
|
||||||
while string and string != ""
|
while string and string != ""
|
||||||
c = string[0]
|
c = string[0]
|
||||||
string.sub!(/^./u, "")
|
string.sub!(/^./u, "")
|
||||||
case c
|
case c
|
||||||
when ?,
|
when ?,
|
||||||
# if depth = 1, then we start a new argument
|
# if depth = 1, then we start a new argument
|
||||||
arguments << evaluate( buffer )
|
arguments << evaluate( buffer )
|
||||||
#arguments << evaluate( string[0..count] )
|
#arguments << evaluate( string[0..count] )
|
||||||
when ?(
|
when ?(
|
||||||
# start a new method call
|
# start a new method call
|
||||||
function( element, buffer, string )
|
function( element, buffer, string )
|
||||||
buffer = ""
|
buffer = ""
|
||||||
when ?)
|
when ?)
|
||||||
# close the method call and return arguments
|
# close the method call and return arguments
|
||||||
return arguments
|
return arguments
|
||||||
else
|
else
|
||||||
buffer << c
|
buffer << c
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
""
|
""
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,97 +1,97 @@
|
||||||
module REXML
|
module REXML
|
||||||
# A template for stream parser listeners.
|
# A template for stream parser listeners.
|
||||||
# Note that the declarations (attlistdecl, elementdecl, etc) are trivially
|
# Note that the declarations (attlistdecl, elementdecl, etc) are trivially
|
||||||
# processed; REXML doesn't yet handle doctype entity declarations, so you
|
# processed; REXML doesn't yet handle doctype entity declarations, so you
|
||||||
# have to parse them out yourself.
|
# have to parse them out yourself.
|
||||||
# === Missing methods from SAX2
|
# === Missing methods from SAX2
|
||||||
# ignorable_whitespace
|
# ignorable_whitespace
|
||||||
# === Methods extending SAX2
|
# === Methods extending SAX2
|
||||||
# +WARNING+
|
# +WARNING+
|
||||||
# These methods are certainly going to change, until DTDs are fully
|
# These methods are certainly going to change, until DTDs are fully
|
||||||
# supported. Be aware of this.
|
# supported. Be aware of this.
|
||||||
# start_document
|
# start_document
|
||||||
# end_document
|
# end_document
|
||||||
# doctype
|
# doctype
|
||||||
# elementdecl
|
# elementdecl
|
||||||
# attlistdecl
|
# attlistdecl
|
||||||
# entitydecl
|
# entitydecl
|
||||||
# notationdecl
|
# notationdecl
|
||||||
# cdata
|
# cdata
|
||||||
# xmldecl
|
# xmldecl
|
||||||
# comment
|
# comment
|
||||||
module SAX2Listener
|
module SAX2Listener
|
||||||
def start_document
|
def start_document
|
||||||
end
|
end
|
||||||
def end_document
|
def end_document
|
||||||
end
|
end
|
||||||
def start_prefix_mapping prefix, uri
|
def start_prefix_mapping prefix, uri
|
||||||
end
|
end
|
||||||
def end_prefix_mapping prefix
|
def end_prefix_mapping prefix
|
||||||
end
|
end
|
||||||
def start_element uri, localname, qname, attributes
|
def start_element uri, localname, qname, attributes
|
||||||
end
|
end
|
||||||
def end_element uri, localname, qname
|
def end_element uri, localname, qname
|
||||||
end
|
end
|
||||||
def characters text
|
def characters text
|
||||||
end
|
end
|
||||||
def processing_instruction target, data
|
def processing_instruction target, data
|
||||||
end
|
end
|
||||||
# Handles a doctype declaration. Any attributes of the doctype which are
|
# Handles a doctype declaration. Any attributes of the doctype which are
|
||||||
# not supplied will be nil. # EG, <!DOCTYPE me PUBLIC "foo" "bar">
|
# not supplied will be nil. # EG, <!DOCTYPE me PUBLIC "foo" "bar">
|
||||||
# @p name the name of the doctype; EG, "me"
|
# @p name the name of the doctype; EG, "me"
|
||||||
# @p pub_sys "PUBLIC", "SYSTEM", or nil. EG, "PUBLIC"
|
# @p pub_sys "PUBLIC", "SYSTEM", or nil. EG, "PUBLIC"
|
||||||
# @p long_name the supplied long name, or nil. EG, "foo"
|
# @p long_name the supplied long name, or nil. EG, "foo"
|
||||||
# @p uri the uri of the doctype, or nil. EG, "bar"
|
# @p uri the uri of the doctype, or nil. EG, "bar"
|
||||||
def doctype name, pub_sys, long_name, uri
|
def doctype name, pub_sys, long_name, uri
|
||||||
end
|
end
|
||||||
# If a doctype includes an ATTLIST declaration, it will cause this
|
# If a doctype includes an ATTLIST declaration, it will cause this
|
||||||
# method to be called. The content is the declaration itself, unparsed.
|
# method to be called. The content is the declaration itself, unparsed.
|
||||||
# EG, <!ATTLIST el attr CDATA #REQUIRED> will come to this method as "el
|
# EG, <!ATTLIST el attr CDATA #REQUIRED> will come to this method as "el
|
||||||
# attr CDATA #REQUIRED". This is the same for all of the .*decl
|
# attr CDATA #REQUIRED". This is the same for all of the .*decl
|
||||||
# methods.
|
# methods.
|
||||||
def attlistdecl(element, pairs, contents)
|
def attlistdecl(element, pairs, contents)
|
||||||
end
|
end
|
||||||
# <!ELEMENT ...>
|
# <!ELEMENT ...>
|
||||||
def elementdecl content
|
def elementdecl content
|
||||||
end
|
end
|
||||||
# <!ENTITY ...>
|
# <!ENTITY ...>
|
||||||
# The argument passed to this method is an array of the entity
|
# The argument passed to this method is an array of the entity
|
||||||
# declaration. It can be in a number of formats, but in general it
|
# declaration. It can be in a number of formats, but in general it
|
||||||
# returns (example, result):
|
# returns (example, result):
|
||||||
# <!ENTITY % YN '"Yes"'>
|
# <!ENTITY % YN '"Yes"'>
|
||||||
# ["%", "YN", "'\"Yes\"'", "\""]
|
# ["%", "YN", "'\"Yes\"'", "\""]
|
||||||
# <!ENTITY % YN 'Yes'>
|
# <!ENTITY % YN 'Yes'>
|
||||||
# ["%", "YN", "'Yes'", "s"]
|
# ["%", "YN", "'Yes'", "s"]
|
||||||
# <!ENTITY WhatHeSaid "He said %YN;">
|
# <!ENTITY WhatHeSaid "He said %YN;">
|
||||||
# ["WhatHeSaid", "\"He said %YN;\"", "YN"]
|
# ["WhatHeSaid", "\"He said %YN;\"", "YN"]
|
||||||
# <!ENTITY open-hatch SYSTEM "http://www.textuality.com/boilerplate/OpenHatch.xml">
|
# <!ENTITY open-hatch SYSTEM "http://www.textuality.com/boilerplate/OpenHatch.xml">
|
||||||
# ["open-hatch", "SYSTEM", "\"http://www.textuality.com/boilerplate/OpenHatch.xml\""]
|
# ["open-hatch", "SYSTEM", "\"http://www.textuality.com/boilerplate/OpenHatch.xml\""]
|
||||||
# <!ENTITY open-hatch PUBLIC "-//Textuality//TEXT Standard open-hatch boilerplate//EN" "http://www.textuality.com/boilerplate/OpenHatch.xml">
|
# <!ENTITY open-hatch PUBLIC "-//Textuality//TEXT Standard open-hatch boilerplate//EN" "http://www.textuality.com/boilerplate/OpenHatch.xml">
|
||||||
# ["open-hatch", "PUBLIC", "\"-//Textuality//TEXT Standard open-hatch boilerplate//EN\"", "\"http://www.textuality.com/boilerplate/OpenHatch.xml\""]
|
# ["open-hatch", "PUBLIC", "\"-//Textuality//TEXT Standard open-hatch boilerplate//EN\"", "\"http://www.textuality.com/boilerplate/OpenHatch.xml\""]
|
||||||
# <!ENTITY hatch-pic SYSTEM "../grafix/OpenHatch.gif" NDATA gif>
|
# <!ENTITY hatch-pic SYSTEM "../grafix/OpenHatch.gif" NDATA gif>
|
||||||
# ["hatch-pic", "SYSTEM", "\"../grafix/OpenHatch.gif\"", "\n\t\t\t\t\t\t\tNDATA gif", "gif"]
|
# ["hatch-pic", "SYSTEM", "\"../grafix/OpenHatch.gif\"", "\n\t\t\t\t\t\t\tNDATA gif", "gif"]
|
||||||
def entitydecl name, decl
|
def entitydecl name, decl
|
||||||
end
|
end
|
||||||
# <!NOTATION ...>
|
# <!NOTATION ...>
|
||||||
def notationdecl content
|
def notationdecl content
|
||||||
end
|
end
|
||||||
# Called when <![CDATA[ ... ]]> is encountered in a document.
|
# Called when <![CDATA[ ... ]]> is encountered in a document.
|
||||||
# @p content "..."
|
# @p content "..."
|
||||||
def cdata content
|
def cdata content
|
||||||
end
|
end
|
||||||
# Called when an XML PI is encountered in the document.
|
# Called when an XML PI is encountered in the document.
|
||||||
# EG: <?xml version="1.0" encoding="utf"?>
|
# EG: <?xml version="1.0" encoding="utf"?>
|
||||||
# @p version the version attribute value. EG, "1.0"
|
# @p version the version attribute value. EG, "1.0"
|
||||||
# @p encoding the encoding attribute value, or nil. EG, "utf"
|
# @p encoding the encoding attribute value, or nil. EG, "utf"
|
||||||
# @p standalone the standalone attribute value, or nil. EG, nil
|
# @p standalone the standalone attribute value, or nil. EG, nil
|
||||||
# @p spaced the declaration is followed by a line break
|
# @p spaced the declaration is followed by a line break
|
||||||
def xmldecl version, encoding, standalone
|
def xmldecl version, encoding, standalone
|
||||||
end
|
end
|
||||||
# Called when a comment is encountered.
|
# Called when a comment is encountered.
|
||||||
# @p comment The content of the comment
|
# @p comment The content of the comment
|
||||||
def comment comment
|
def comment comment
|
||||||
end
|
end
|
||||||
def progress position
|
def progress position
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,92 +1,92 @@
|
||||||
module REXML
|
module REXML
|
||||||
# A template for stream parser listeners.
|
# A template for stream parser listeners.
|
||||||
# Note that the declarations (attlistdecl, elementdecl, etc) are trivially
|
# Note that the declarations (attlistdecl, elementdecl, etc) are trivially
|
||||||
# processed; REXML doesn't yet handle doctype entity declarations, so you
|
# processed; REXML doesn't yet handle doctype entity declarations, so you
|
||||||
# have to parse them out yourself.
|
# have to parse them out yourself.
|
||||||
module StreamListener
|
module StreamListener
|
||||||
# Called when a tag is encountered.
|
# Called when a tag is encountered.
|
||||||
# @p name the tag name
|
# @p name the tag name
|
||||||
# @p attrs an array of arrays of attribute/value pairs, suitable for
|
# @p attrs an array of arrays of attribute/value pairs, suitable for
|
||||||
# use with assoc or rassoc. IE, <tag attr1="value1" attr2="value2">
|
# use with assoc or rassoc. IE, <tag attr1="value1" attr2="value2">
|
||||||
# will result in
|
# will result in
|
||||||
# tag_start( "tag", # [["attr1","value1"],["attr2","value2"]])
|
# tag_start( "tag", # [["attr1","value1"],["attr2","value2"]])
|
||||||
def tag_start name, attrs
|
def tag_start name, attrs
|
||||||
end
|
end
|
||||||
# Called when the end tag is reached. In the case of <tag/>, tag_end
|
# Called when the end tag is reached. In the case of <tag/>, tag_end
|
||||||
# will be called immidiately after tag_start
|
# will be called immidiately after tag_start
|
||||||
# @p the name of the tag
|
# @p the name of the tag
|
||||||
def tag_end name
|
def tag_end name
|
||||||
end
|
end
|
||||||
# Called when text is encountered in the document
|
# Called when text is encountered in the document
|
||||||
# @p text the text content.
|
# @p text the text content.
|
||||||
def text text
|
def text text
|
||||||
end
|
end
|
||||||
# Called when an instruction is encountered. EG: <?xsl sheet='foo'?>
|
# Called when an instruction is encountered. EG: <?xsl sheet='foo'?>
|
||||||
# @p name the instruction name; in the example, "xsl"
|
# @p name the instruction name; in the example, "xsl"
|
||||||
# @p instruction the rest of the instruction. In the example,
|
# @p instruction the rest of the instruction. In the example,
|
||||||
# "sheet='foo'"
|
# "sheet='foo'"
|
||||||
def instruction name, instruction
|
def instruction name, instruction
|
||||||
end
|
end
|
||||||
# Called when a comment is encountered.
|
# Called when a comment is encountered.
|
||||||
# @p comment The content of the comment
|
# @p comment The content of the comment
|
||||||
def comment comment
|
def comment comment
|
||||||
end
|
end
|
||||||
# Handles a doctype declaration. Any attributes of the doctype which are
|
# Handles a doctype declaration. Any attributes of the doctype which are
|
||||||
# not supplied will be nil. # EG, <!DOCTYPE me PUBLIC "foo" "bar">
|
# not supplied will be nil. # EG, <!DOCTYPE me PUBLIC "foo" "bar">
|
||||||
# @p name the name of the doctype; EG, "me"
|
# @p name the name of the doctype; EG, "me"
|
||||||
# @p pub_sys "PUBLIC", "SYSTEM", or nil. EG, "PUBLIC"
|
# @p pub_sys "PUBLIC", "SYSTEM", or nil. EG, "PUBLIC"
|
||||||
# @p long_name the supplied long name, or nil. EG, "foo"
|
# @p long_name the supplied long name, or nil. EG, "foo"
|
||||||
# @p uri the uri of the doctype, or nil. EG, "bar"
|
# @p uri the uri of the doctype, or nil. EG, "bar"
|
||||||
def doctype name, pub_sys, long_name, uri
|
def doctype name, pub_sys, long_name, uri
|
||||||
end
|
end
|
||||||
# Called when the doctype is done
|
# Called when the doctype is done
|
||||||
def doctype_end
|
def doctype_end
|
||||||
end
|
end
|
||||||
# If a doctype includes an ATTLIST declaration, it will cause this
|
# If a doctype includes an ATTLIST declaration, it will cause this
|
||||||
# method to be called. The content is the declaration itself, unparsed.
|
# method to be called. The content is the declaration itself, unparsed.
|
||||||
# EG, <!ATTLIST el attr CDATA #REQUIRED> will come to this method as "el
|
# EG, <!ATTLIST el attr CDATA #REQUIRED> will come to this method as "el
|
||||||
# attr CDATA #REQUIRED". This is the same for all of the .*decl
|
# attr CDATA #REQUIRED". This is the same for all of the .*decl
|
||||||
# methods.
|
# methods.
|
||||||
def attlistdecl element_name, attributes, raw_content
|
def attlistdecl element_name, attributes, raw_content
|
||||||
end
|
end
|
||||||
# <!ELEMENT ...>
|
# <!ELEMENT ...>
|
||||||
def elementdecl content
|
def elementdecl content
|
||||||
end
|
end
|
||||||
# <!ENTITY ...>
|
# <!ENTITY ...>
|
||||||
# The argument passed to this method is an array of the entity
|
# The argument passed to this method is an array of the entity
|
||||||
# declaration. It can be in a number of formats, but in general it
|
# declaration. It can be in a number of formats, but in general it
|
||||||
# returns (example, result):
|
# returns (example, result):
|
||||||
# <!ENTITY % YN '"Yes"'>
|
# <!ENTITY % YN '"Yes"'>
|
||||||
# ["%", "YN", "'\"Yes\"'", "\""]
|
# ["%", "YN", "'\"Yes\"'", "\""]
|
||||||
# <!ENTITY % YN 'Yes'>
|
# <!ENTITY % YN 'Yes'>
|
||||||
# ["%", "YN", "'Yes'", "s"]
|
# ["%", "YN", "'Yes'", "s"]
|
||||||
# <!ENTITY WhatHeSaid "He said %YN;">
|
# <!ENTITY WhatHeSaid "He said %YN;">
|
||||||
# ["WhatHeSaid", "\"He said %YN;\"", "YN"]
|
# ["WhatHeSaid", "\"He said %YN;\"", "YN"]
|
||||||
# <!ENTITY open-hatch SYSTEM "http://www.textuality.com/boilerplate/OpenHatch.xml">
|
# <!ENTITY open-hatch SYSTEM "http://www.textuality.com/boilerplate/OpenHatch.xml">
|
||||||
# ["open-hatch", "SYSTEM", "\"http://www.textuality.com/boilerplate/OpenHatch.xml\""]
|
# ["open-hatch", "SYSTEM", "\"http://www.textuality.com/boilerplate/OpenHatch.xml\""]
|
||||||
# <!ENTITY open-hatch PUBLIC "-//Textuality//TEXT Standard open-hatch boilerplate//EN" "http://www.textuality.com/boilerplate/OpenHatch.xml">
|
# <!ENTITY open-hatch PUBLIC "-//Textuality//TEXT Standard open-hatch boilerplate//EN" "http://www.textuality.com/boilerplate/OpenHatch.xml">
|
||||||
# ["open-hatch", "PUBLIC", "\"-//Textuality//TEXT Standard open-hatch boilerplate//EN\"", "\"http://www.textuality.com/boilerplate/OpenHatch.xml\""]
|
# ["open-hatch", "PUBLIC", "\"-//Textuality//TEXT Standard open-hatch boilerplate//EN\"", "\"http://www.textuality.com/boilerplate/OpenHatch.xml\""]
|
||||||
# <!ENTITY hatch-pic SYSTEM "../grafix/OpenHatch.gif" NDATA gif>
|
# <!ENTITY hatch-pic SYSTEM "../grafix/OpenHatch.gif" NDATA gif>
|
||||||
# ["hatch-pic", "SYSTEM", "\"../grafix/OpenHatch.gif\"", "\n\t\t\t\t\t\t\tNDATA gif", "gif"]
|
# ["hatch-pic", "SYSTEM", "\"../grafix/OpenHatch.gif\"", "\n\t\t\t\t\t\t\tNDATA gif", "gif"]
|
||||||
def entitydecl content
|
def entitydecl content
|
||||||
end
|
end
|
||||||
# <!NOTATION ...>
|
# <!NOTATION ...>
|
||||||
def notationdecl content
|
def notationdecl content
|
||||||
end
|
end
|
||||||
# Called when %foo; is encountered in a doctype declaration.
|
# Called when %foo; is encountered in a doctype declaration.
|
||||||
# @p content "foo"
|
# @p content "foo"
|
||||||
def entity content
|
def entity content
|
||||||
end
|
end
|
||||||
# Called when <![CDATA[ ... ]]> is encountered in a document.
|
# Called when <![CDATA[ ... ]]> is encountered in a document.
|
||||||
# @p content "..."
|
# @p content "..."
|
||||||
def cdata content
|
def cdata content
|
||||||
end
|
end
|
||||||
# Called when an XML PI is encountered in the document.
|
# Called when an XML PI is encountered in the document.
|
||||||
# EG: <?xml version="1.0" encoding="utf"?>
|
# EG: <?xml version="1.0" encoding="utf"?>
|
||||||
# @p version the version attribute value. EG, "1.0"
|
# @p version the version attribute value. EG, "1.0"
|
||||||
# @p encoding the encoding attribute value, or nil. EG, "utf"
|
# @p encoding the encoding attribute value, or nil. EG, "utf"
|
||||||
# @p standalone the standalone attribute value, or nil. EG, nil
|
# @p standalone the standalone attribute value, or nil. EG, nil
|
||||||
def xmldecl version, encoding, standalone
|
def xmldecl version, encoding, standalone
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,40 +2,40 @@ require 'rexml/encoding'
|
||||||
require 'rexml/source'
|
require 'rexml/source'
|
||||||
|
|
||||||
module REXML
|
module REXML
|
||||||
# NEEDS DOCUMENTATION
|
# NEEDS DOCUMENTATION
|
||||||
class XMLDecl < Child
|
class XMLDecl < Child
|
||||||
include Encoding
|
include Encoding
|
||||||
|
|
||||||
DEFAULT_VERSION = "1.0";
|
DEFAULT_VERSION = "1.0";
|
||||||
DEFAULT_ENCODING = "UTF-8";
|
DEFAULT_ENCODING = "UTF-8";
|
||||||
DEFAULT_STANDALONE = "no";
|
DEFAULT_STANDALONE = "no";
|
||||||
START = '<\?xml';
|
START = '<\?xml';
|
||||||
STOP = '\?>';
|
STOP = '\?>';
|
||||||
|
|
||||||
attr_accessor :version, :standalone
|
attr_accessor :version, :standalone
|
||||||
attr_reader :writeencoding, :writethis
|
attr_reader :writeencoding, :writethis
|
||||||
|
|
||||||
def initialize(version=DEFAULT_VERSION, encoding=nil, standalone=nil)
|
def initialize(version=DEFAULT_VERSION, encoding=nil, standalone=nil)
|
||||||
@writethis = true
|
@writethis = true
|
||||||
@writeencoding = !encoding.nil?
|
@writeencoding = !encoding.nil?
|
||||||
if version.kind_of? XMLDecl
|
if version.kind_of? XMLDecl
|
||||||
super()
|
super()
|
||||||
@version = version.version
|
@version = version.version
|
||||||
self.encoding = version.encoding
|
self.encoding = version.encoding
|
||||||
@writeencoding = version.writeencoding
|
@writeencoding = version.writeencoding
|
||||||
@standalone = version.standalone
|
@standalone = version.standalone
|
||||||
else
|
else
|
||||||
super()
|
super()
|
||||||
@version = version
|
@version = version
|
||||||
self.encoding = encoding
|
self.encoding = encoding
|
||||||
@standalone = standalone
|
@standalone = standalone
|
||||||
end
|
end
|
||||||
@version = DEFAULT_VERSION if @version.nil?
|
@version = DEFAULT_VERSION if @version.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
def clone
|
def clone
|
||||||
XMLDecl.new(self)
|
XMLDecl.new(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
# indent::
|
# indent::
|
||||||
# Ignored. There must be no whitespace before an XML declaration
|
# Ignored. There must be no whitespace before an XML declaration
|
||||||
|
@ -43,35 +43,35 @@ module REXML
|
||||||
# Ignored
|
# Ignored
|
||||||
# ie_hack::
|
# ie_hack::
|
||||||
# Ignored
|
# Ignored
|
||||||
def write(writer, indent=-1, transitive=false, ie_hack=false)
|
def write(writer, indent=-1, transitive=false, ie_hack=false)
|
||||||
return nil unless @writethis or writer.kind_of? Output
|
return nil unless @writethis or writer.kind_of? Output
|
||||||
writer << START.sub(/\\/u, '')
|
writer << START.sub(/\\/u, '')
|
||||||
if writer.kind_of? Output
|
if writer.kind_of? Output
|
||||||
writer << " #{content writer.encoding}"
|
writer << " #{content writer.encoding}"
|
||||||
else
|
else
|
||||||
writer << " #{content encoding}"
|
writer << " #{content encoding}"
|
||||||
end
|
end
|
||||||
writer << STOP.sub(/\\/u, '')
|
writer << STOP.sub(/\\/u, '')
|
||||||
end
|
end
|
||||||
|
|
||||||
def ==( other )
|
def ==( other )
|
||||||
other.kind_of?(XMLDecl) and
|
other.kind_of?(XMLDecl) and
|
||||||
other.version == @version and
|
other.version == @version and
|
||||||
other.encoding == self.encoding and
|
other.encoding == self.encoding and
|
||||||
other.standalone == @standalone
|
other.standalone == @standalone
|
||||||
end
|
end
|
||||||
|
|
||||||
def xmldecl version, encoding, standalone
|
def xmldecl version, encoding, standalone
|
||||||
@version = version
|
@version = version
|
||||||
self.encoding = encoding
|
self.encoding = encoding
|
||||||
@standalone = standalone
|
@standalone = standalone
|
||||||
end
|
end
|
||||||
|
|
||||||
def node_type
|
def node_type
|
||||||
:xmldecl
|
:xmldecl
|
||||||
end
|
end
|
||||||
|
|
||||||
alias :stand_alone? :standalone
|
alias :stand_alone? :standalone
|
||||||
alias :old_enc= :encoding=
|
alias :old_enc= :encoding=
|
||||||
|
|
||||||
def encoding=( enc )
|
def encoding=( enc )
|
||||||
|
@ -108,12 +108,12 @@ module REXML
|
||||||
START.sub(/\\/u, '') + " ... " + STOP.sub(/\\/u, '')
|
START.sub(/\\/u, '') + " ... " + STOP.sub(/\\/u, '')
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def content(enc)
|
def content(enc)
|
||||||
rv = "version='#@version'"
|
rv = "version='#@version'"
|
||||||
rv << " encoding='#{enc}'" if @writeencoding || enc !~ /utf-8/i
|
rv << " encoding='#{enc}'" if @writeencoding || enc !~ /utf-8/i
|
||||||
rv << " standalone='#@standalone'" if @standalone
|
rv << " standalone='#@standalone'" if @standalone
|
||||||
rv
|
rv
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
module REXML
|
module REXML
|
||||||
# Defines a number of tokens used for parsing XML. Not for general
|
# Defines a number of tokens used for parsing XML. Not for general
|
||||||
# consumption.
|
# consumption.
|
||||||
module XMLTokens
|
module XMLTokens
|
||||||
NCNAME_STR= '[\w:][\-\w\d.]*'
|
NCNAME_STR= '[\w:][\-\w\d.]*'
|
||||||
NAME_STR= "(?:#{NCNAME_STR}:)?#{NCNAME_STR}"
|
NAME_STR= "(?:#{NCNAME_STR}:)?#{NCNAME_STR}"
|
||||||
|
|
||||||
NAMECHAR = '[\-\w\d\.:]'
|
NAMECHAR = '[\-\w\d\.:]'
|
||||||
NAME = "([\\w:]#{NAMECHAR}*)"
|
NAME = "([\\w:]#{NAMECHAR}*)"
|
||||||
NMTOKEN = "(?:#{NAMECHAR})+"
|
NMTOKEN = "(?:#{NAMECHAR})+"
|
||||||
NMTOKENS = "#{NMTOKEN}(\\s+#{NMTOKEN})*"
|
NMTOKENS = "#{NMTOKEN}(\\s+#{NMTOKEN})*"
|
||||||
REFERENCE = "(?:&#{NAME};|&#\\d+;|&#x[0-9a-fA-F]+;)"
|
REFERENCE = "(?:&#{NAME};|&#\\d+;|&#x[0-9a-fA-F]+;)"
|
||||||
|
|
||||||
#REFERENCE = "(?:#{ENTITYREF}|#{CHARREF})"
|
#REFERENCE = "(?:#{ENTITYREF}|#{CHARREF})"
|
||||||
#ENTITYREF = "&#{NAME};"
|
#ENTITYREF = "&#{NAME};"
|
||||||
#CHARREF = "&#\\d+;|&#x[0-9a-fA-F]+;"
|
#CHARREF = "&#\\d+;|&#x[0-9a-fA-F]+;"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,65 +2,65 @@ require 'rexml/functions'
|
||||||
require 'rexml/xpath_parser'
|
require 'rexml/xpath_parser'
|
||||||
|
|
||||||
module REXML
|
module REXML
|
||||||
# Wrapper class. Use this class to access the XPath functions.
|
# Wrapper class. Use this class to access the XPath functions.
|
||||||
class XPath
|
class XPath
|
||||||
include Functions
|
include Functions
|
||||||
EMPTY_HASH = {}
|
EMPTY_HASH = {}
|
||||||
|
|
||||||
# Finds and returns the first node that matches the supplied xpath.
|
# Finds and returns the first node that matches the supplied xpath.
|
||||||
# element::
|
# element::
|
||||||
# The context element
|
# The context element
|
||||||
# path::
|
# path::
|
||||||
# The xpath to search for. If not supplied or nil, returns the first
|
# The xpath to search for. If not supplied or nil, returns the first
|
||||||
# node matching '*'.
|
# node matching '*'.
|
||||||
# namespaces::
|
# namespaces::
|
||||||
# If supplied, a Hash which defines a namespace mapping.
|
# If supplied, a Hash which defines a namespace mapping.
|
||||||
#
|
#
|
||||||
# XPath.first( node )
|
# XPath.first( node )
|
||||||
# XPath.first( doc, "//b"} )
|
# XPath.first( doc, "//b"} )
|
||||||
# XPath.first( node, "a/x:b", { "x"=>"http://doofus" } )
|
# XPath.first( node, "a/x:b", { "x"=>"http://doofus" } )
|
||||||
def XPath::first element, path=nil, namespaces=nil, variables={}
|
def XPath::first element, path=nil, namespaces=nil, variables={}
|
||||||
raise "The namespaces argument, if supplied, must be a hash object." unless namespaces.nil? or namespaces.kind_of?(Hash)
|
raise "The namespaces argument, if supplied, must be a hash object." unless namespaces.nil? or namespaces.kind_of?(Hash)
|
||||||
raise "The variables argument, if supplied, must be a hash object." unless variables.kind_of?(Hash)
|
raise "The variables argument, if supplied, must be a hash object." unless variables.kind_of?(Hash)
|
||||||
parser = XPathParser.new
|
parser = XPathParser.new
|
||||||
parser.namespaces = namespaces
|
parser.namespaces = namespaces
|
||||||
parser.variables = variables
|
parser.variables = variables
|
||||||
path = "*" unless path
|
path = "*" unless path
|
||||||
element = [element] unless element.kind_of? Array
|
element = [element] unless element.kind_of? Array
|
||||||
parser.parse(path, element).flatten[0]
|
parser.parse(path, element).flatten[0]
|
||||||
end
|
end
|
||||||
|
|
||||||
# Iterates over nodes that match the given path, calling the supplied
|
# Iterates over nodes that match the given path, calling the supplied
|
||||||
# block with the match.
|
# block with the match.
|
||||||
# element::
|
# element::
|
||||||
# The context element
|
# The context element
|
||||||
# path::
|
# path::
|
||||||
# The xpath to search for. If not supplied or nil, defaults to '*'
|
# The xpath to search for. If not supplied or nil, defaults to '*'
|
||||||
# namespaces::
|
# namespaces::
|
||||||
# If supplied, a Hash which defines a namespace mapping
|
# If supplied, a Hash which defines a namespace mapping
|
||||||
#
|
#
|
||||||
# XPath.each( node ) { |el| ... }
|
# XPath.each( node ) { |el| ... }
|
||||||
# XPath.each( node, '/*[@attr='v']' ) { |el| ... }
|
# XPath.each( node, '/*[@attr='v']' ) { |el| ... }
|
||||||
# XPath.each( node, 'ancestor::x' ) { |el| ... }
|
# XPath.each( node, 'ancestor::x' ) { |el| ... }
|
||||||
def XPath::each element, path=nil, namespaces=nil, variables={}, &block
|
def XPath::each element, path=nil, namespaces=nil, variables={}, &block
|
||||||
raise "The namespaces argument, if supplied, must be a hash object." unless namespaces.nil? or namespaces.kind_of?(Hash)
|
raise "The namespaces argument, if supplied, must be a hash object." unless namespaces.nil? or namespaces.kind_of?(Hash)
|
||||||
raise "The variables argument, if supplied, must be a hash object." unless variables.kind_of?(Hash)
|
raise "The variables argument, if supplied, must be a hash object." unless variables.kind_of?(Hash)
|
||||||
parser = XPathParser.new
|
parser = XPathParser.new
|
||||||
parser.namespaces = namespaces
|
parser.namespaces = namespaces
|
||||||
parser.variables = variables
|
parser.variables = variables
|
||||||
path = "*" unless path
|
path = "*" unless path
|
||||||
element = [element] unless element.kind_of? Array
|
element = [element] unless element.kind_of? Array
|
||||||
parser.parse(path, element).each( &block )
|
parser.parse(path, element).each( &block )
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns an array of nodes matching a given XPath.
|
# Returns an array of nodes matching a given XPath.
|
||||||
def XPath::match element, path=nil, namespaces=nil, variables={}
|
def XPath::match element, path=nil, namespaces=nil, variables={}
|
||||||
parser = XPathParser.new
|
parser = XPathParser.new
|
||||||
parser.namespaces = namespaces
|
parser.namespaces = namespaces
|
||||||
parser.variables = variables
|
parser.variables = variables
|
||||||
path = "*" unless path
|
path = "*" unless path
|
||||||
element = [element] unless element.kind_of? Array
|
element = [element] unless element.kind_of? Array
|
||||||
parser.parse(path,element)
|
parser.parse(path,element)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -419,10 +419,10 @@ module REXML
|
||||||
return @variables[ var_name ]
|
return @variables[ var_name ]
|
||||||
|
|
||||||
# :and, :or, :eq, :neq, :lt, :lteq, :gt, :gteq
|
# :and, :or, :eq, :neq, :lt, :lteq, :gt, :gteq
|
||||||
# TODO: Special case for :or and :and -- not evaluate the right
|
# TODO: Special case for :or and :and -- not evaluate the right
|
||||||
# operand if the left alone determines result (i.e. is true for
|
# operand if the left alone determines result (i.e. is true for
|
||||||
# :or and false for :and).
|
# :or and false for :and).
|
||||||
when :eq, :neq, :lt, :lteq, :gt, :gteq, :and, :or
|
when :eq, :neq, :lt, :lteq, :gt, :gteq, :or
|
||||||
left = expr( path_stack.shift, nodeset.dup, context )
|
left = expr( path_stack.shift, nodeset.dup, context )
|
||||||
#puts "LEFT => #{left.inspect} (#{left.class.name})"
|
#puts "LEFT => #{left.inspect} (#{left.class.name})"
|
||||||
right = expr( path_stack.shift, nodeset.dup, context )
|
right = expr( path_stack.shift, nodeset.dup, context )
|
||||||
|
@ -675,7 +675,7 @@ module REXML
|
||||||
def equality_relational_compare( set1, op, set2 )
|
def equality_relational_compare( set1, op, set2 )
|
||||||
#puts "EQ_REL_COMP(#{set1.inspect} #{op.inspect} #{set2.inspect})"
|
#puts "EQ_REL_COMP(#{set1.inspect} #{op.inspect} #{set2.inspect})"
|
||||||
if set1.kind_of? Array and set2.kind_of? Array
|
if set1.kind_of? Array and set2.kind_of? Array
|
||||||
#puts "#{set1.size} & #{set2.size}"
|
#puts "#{set1.size} & #{set2.size}"
|
||||||
if set1.size == 1 and set2.size == 1
|
if set1.size == 1 and set2.size == 1
|
||||||
set1 = set1[0]
|
set1 = set1[0]
|
||||||
set2 = set2[0]
|
set2 = set2[0]
|
||||||
|
@ -696,7 +696,7 @@ module REXML
|
||||||
return res
|
return res
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
#puts "EQ_REL_COMP: #{set1.inspect} (#{set1.class.name}), #{op}, #{set2.inspect} (#{set2.class.name})"
|
#puts "EQ_REL_COMP: #{set1.inspect} (#{set1.class.name}), #{op}, #{set2.inspect} (#{set2.class.name})"
|
||||||
#puts "COMPARING VALUES"
|
#puts "COMPARING VALUES"
|
||||||
# If one is nodeset and other is number, compare number to each item
|
# If one is nodeset and other is number, compare number to each item
|
||||||
# in nodeset s.t. number op number(string(item))
|
# in nodeset s.t. number op number(string(item))
|
||||||
|
@ -705,7 +705,7 @@ module REXML
|
||||||
# If one is nodeset and other is boolean, compare boolean to each item
|
# If one is nodeset and other is boolean, compare boolean to each item
|
||||||
# in nodeset s.t. boolean op boolean(item)
|
# in nodeset s.t. boolean op boolean(item)
|
||||||
if set1.kind_of? Array or set2.kind_of? Array
|
if set1.kind_of? Array or set2.kind_of? Array
|
||||||
#puts "ISA ARRAY"
|
#puts "ISA ARRAY"
|
||||||
if set1.kind_of? Array
|
if set1.kind_of? Array
|
||||||
a = set1
|
a = set1
|
||||||
b = set2
|
b = set2
|
||||||
|
@ -724,7 +724,7 @@ module REXML
|
||||||
#puts "B = #{b.inspect}"
|
#puts "B = #{b.inspect}"
|
||||||
return a.collect {|v| compare( Functions::number(v), op, b )}
|
return a.collect {|v| compare( Functions::number(v), op, b )}
|
||||||
else
|
else
|
||||||
#puts "Functions::string( #{b}(#{b.class.name}) ) = #{Functions::string(b)}"
|
#puts "Functions::string( #{b}(#{b.class.name}) ) = #{Functions::string(b)}"
|
||||||
b = Functions::string( b )
|
b = Functions::string( b )
|
||||||
return a.collect { |v| compare( Functions::string(v), op, b ) }
|
return a.collect { |v| compare( Functions::string(v), op, b ) }
|
||||||
end
|
end
|
||||||
|
|
|
@ -605,16 +605,16 @@ module XMLRPC
|
||||||
class Proxy
|
class Proxy
|
||||||
|
|
||||||
def initialize(server, prefix, args=[], meth=:call, delim=".")
|
def initialize(server, prefix, args=[], meth=:call, delim=".")
|
||||||
@server = server
|
@server = server
|
||||||
@prefix = prefix ? prefix + delim : ""
|
@prefix = prefix ? prefix + delim : ""
|
||||||
@args = args
|
@args = args
|
||||||
@meth = meth
|
@meth = meth
|
||||||
end
|
end
|
||||||
|
|
||||||
def method_missing(mid, *args)
|
def method_missing(mid, *args)
|
||||||
pre = @prefix + mid.to_s
|
pre = @prefix + mid.to_s
|
||||||
arg = @args + args
|
arg = @args + args
|
||||||
@server.send(@meth, pre, *arg)
|
@server.send(@meth, pre, *arg)
|
||||||
end
|
end
|
||||||
|
|
||||||
end # class Proxy
|
end # class Proxy
|
||||||
|
|
|
@ -15,11 +15,11 @@ module XMLRPC
|
||||||
|
|
||||||
class Abstract
|
class Abstract
|
||||||
def ele(name, *children)
|
def ele(name, *children)
|
||||||
element(name, nil, *children)
|
element(name, nil, *children)
|
||||||
end
|
end
|
||||||
|
|
||||||
def tag(name, txt)
|
def tag(name, txt)
|
||||||
element(name, nil, text(txt))
|
element(name, nil, text(txt))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -27,19 +27,19 @@ module XMLRPC
|
||||||
class Simple < Abstract
|
class Simple < Abstract
|
||||||
|
|
||||||
def document_to_str(doc)
|
def document_to_str(doc)
|
||||||
doc
|
doc
|
||||||
end
|
end
|
||||||
|
|
||||||
def document(*params)
|
def document(*params)
|
||||||
params.join("")
|
params.join("")
|
||||||
end
|
end
|
||||||
|
|
||||||
def pi(name, *params)
|
def pi(name, *params)
|
||||||
"<?#{name} " + params.join(" ") + " ?>"
|
"<?#{name} " + params.join(" ") + " ?>"
|
||||||
end
|
end
|
||||||
|
|
||||||
def element(name, attrs, *children)
|
def element(name, attrs, *children)
|
||||||
raise "attributes not yet implemented" unless attrs.nil?
|
raise "attributes not yet implemented" unless attrs.nil?
|
||||||
if children.empty?
|
if children.empty?
|
||||||
"<#{name}/>"
|
"<#{name}/>"
|
||||||
else
|
else
|
||||||
|
@ -61,27 +61,27 @@ module XMLRPC
|
||||||
class XMLParser < Abstract
|
class XMLParser < Abstract
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
require "xmltreebuilder"
|
require "xmltreebuilder"
|
||||||
end
|
end
|
||||||
|
|
||||||
def document_to_str(doc)
|
def document_to_str(doc)
|
||||||
doc.to_s
|
doc.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
def document(*params)
|
def document(*params)
|
||||||
XML::SimpleTree::Document.new(*params)
|
XML::SimpleTree::Document.new(*params)
|
||||||
end
|
end
|
||||||
|
|
||||||
def pi(name, *params)
|
def pi(name, *params)
|
||||||
XML::SimpleTree::ProcessingInstruction.new(name, *params)
|
XML::SimpleTree::ProcessingInstruction.new(name, *params)
|
||||||
end
|
end
|
||||||
|
|
||||||
def element(name, attrs, *children)
|
def element(name, attrs, *children)
|
||||||
XML::SimpleTree::Element.new(name, attrs, *children)
|
XML::SimpleTree::Element.new(name, attrs, *children)
|
||||||
end
|
end
|
||||||
|
|
||||||
def text(txt)
|
def text(txt)
|
||||||
XML::SimpleTree::Text.new(txt)
|
XML::SimpleTree::Text.new(txt)
|
||||||
end
|
end
|
||||||
|
|
||||||
end # class XMLParser
|
end # class XMLParser
|
||||||
|
@ -111,20 +111,20 @@ module XMLRPC
|
||||||
name = name.to_s
|
name = name.to_s
|
||||||
|
|
||||||
if name !~ /[a-zA-Z0-9_.:\/]+/
|
if name !~ /[a-zA-Z0-9_.:\/]+/
|
||||||
raise ArgumentError, "Wrong XML-RPC method-name"
|
raise ArgumentError, "Wrong XML-RPC method-name"
|
||||||
end
|
end
|
||||||
|
|
||||||
parameter = params.collect do |param|
|
parameter = params.collect do |param|
|
||||||
@writer.ele("param", conv2value(param))
|
@writer.ele("param", conv2value(param))
|
||||||
end
|
end
|
||||||
|
|
||||||
tree = @writer.document(
|
tree = @writer.document(
|
||||||
@writer.pi("xml", 'version="1.0"'),
|
@writer.pi("xml", 'version="1.0"'),
|
||||||
@writer.ele("methodCall",
|
@writer.ele("methodCall",
|
||||||
@writer.tag("methodName", name),
|
@writer.tag("methodName", name),
|
||||||
@writer.ele("params", *parameter)
|
@writer.ele("params", *parameter)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@writer.document_to_str(tree) + "\n"
|
@writer.document_to_str(tree) + "\n"
|
||||||
end
|
end
|
||||||
|
@ -144,23 +144,23 @@ module XMLRPC
|
||||||
def methodResponse(is_ret, *params)
|
def methodResponse(is_ret, *params)
|
||||||
|
|
||||||
if is_ret
|
if is_ret
|
||||||
resp = params.collect do |param|
|
resp = params.collect do |param|
|
||||||
@writer.ele("param", conv2value(param))
|
@writer.ele("param", conv2value(param))
|
||||||
end
|
end
|
||||||
|
|
||||||
resp = [@writer.ele("params", *resp)]
|
resp = [@writer.ele("params", *resp)]
|
||||||
else
|
else
|
||||||
if params.size != 1 or params[0] === XMLRPC::FaultException
|
if params.size != 1 or params[0] === XMLRPC::FaultException
|
||||||
raise ArgumentError, "no valid fault-structure given"
|
raise ArgumentError, "no valid fault-structure given"
|
||||||
end
|
end
|
||||||
resp = @writer.ele("fault", conv2value(params[0].to_h))
|
resp = @writer.ele("fault", conv2value(params[0].to_h))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
tree = @writer.document(
|
tree = @writer.document(
|
||||||
@writer.pi("xml", 'version="1.0"'),
|
@writer.pi("xml", 'version="1.0"'),
|
||||||
@writer.ele("methodResponse", resp)
|
@writer.ele("methodResponse", resp)
|
||||||
)
|
)
|
||||||
|
|
||||||
@writer.document_to_str(tree) + "\n"
|
@writer.document_to_str(tree) + "\n"
|
||||||
end
|
end
|
||||||
|
@ -177,11 +177,11 @@ module XMLRPC
|
||||||
#
|
#
|
||||||
def conv2value(param)
|
def conv2value(param)
|
||||||
|
|
||||||
val = case param
|
val = case param
|
||||||
when Fixnum
|
when Fixnum
|
||||||
@writer.tag("i4", param.to_s)
|
@writer.tag("i4", param.to_s)
|
||||||
|
|
||||||
when Bignum
|
when Bignum
|
||||||
if Config::ENABLE_BIGINT
|
if Config::ENABLE_BIGINT
|
||||||
@writer.tag("i4", param.to_s)
|
@writer.tag("i4", param.to_s)
|
||||||
else
|
else
|
||||||
|
@ -191,14 +191,14 @@ module XMLRPC
|
||||||
raise "Bignum is too big! Must be signed 32-bit integer!"
|
raise "Bignum is too big! Must be signed 32-bit integer!"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
when TrueClass, FalseClass
|
when TrueClass, FalseClass
|
||||||
@writer.tag("boolean", param ? "1" : "0")
|
@writer.tag("boolean", param ? "1" : "0")
|
||||||
|
|
||||||
when Symbol
|
when Symbol
|
||||||
@writer.tag("string", param.to_s)
|
@writer.tag("string", param.to_s)
|
||||||
|
|
||||||
when String
|
when String
|
||||||
@writer.tag("string", param)
|
@writer.tag("string", param)
|
||||||
|
|
||||||
when NilClass
|
when NilClass
|
||||||
if Config::ENABLE_NIL_CREATE
|
if Config::ENABLE_NIL_CREATE
|
||||||
|
@ -207,51 +207,51 @@ module XMLRPC
|
||||||
raise "Wrong type NilClass. Not allowed!"
|
raise "Wrong type NilClass. Not allowed!"
|
||||||
end
|
end
|
||||||
|
|
||||||
when Float
|
when Float
|
||||||
@writer.tag("double", param.to_s)
|
@writer.tag("double", param.to_s)
|
||||||
|
|
||||||
when Struct
|
when Struct
|
||||||
h = param.members.collect do |key|
|
h = param.members.collect do |key|
|
||||||
value = param[key]
|
value = param[key]
|
||||||
@writer.ele("member",
|
@writer.ele("member",
|
||||||
@writer.tag("name", key.to_s),
|
@writer.tag("name", key.to_s),
|
||||||
conv2value(value)
|
conv2value(value)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@writer.ele("struct", *h)
|
@writer.ele("struct", *h)
|
||||||
|
|
||||||
when Hash
|
when Hash
|
||||||
# TODO: can a Hash be empty?
|
# TODO: can a Hash be empty?
|
||||||
|
|
||||||
h = param.collect do |key, value|
|
h = param.collect do |key, value|
|
||||||
@writer.ele("member",
|
@writer.ele("member",
|
||||||
@writer.tag("name", key.to_s),
|
@writer.tag("name", key.to_s),
|
||||||
conv2value(value)
|
conv2value(value)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@writer.ele("struct", *h)
|
@writer.ele("struct", *h)
|
||||||
|
|
||||||
when Array
|
when Array
|
||||||
# TODO: can an Array be empty?
|
# TODO: can an Array be empty?
|
||||||
a = param.collect {|v| conv2value(v) }
|
a = param.collect {|v| conv2value(v) }
|
||||||
|
|
||||||
@writer.ele("array",
|
@writer.ele("array",
|
||||||
@writer.ele("data", *a)
|
@writer.ele("data", *a)
|
||||||
)
|
)
|
||||||
|
|
||||||
when Time, Date, ::DateTime
|
when Time, Date, ::DateTime
|
||||||
@writer.tag("dateTime.iso8601", param.strftime("%Y%m%dT%H:%M:%S"))
|
@writer.tag("dateTime.iso8601", param.strftime("%Y%m%dT%H:%M:%S"))
|
||||||
|
|
||||||
when XMLRPC::DateTime
|
when XMLRPC::DateTime
|
||||||
@writer.tag("dateTime.iso8601",
|
@writer.tag("dateTime.iso8601",
|
||||||
format("%.4d%02d%02dT%02d:%02d:%02d", *param.to_a))
|
format("%.4d%02d%02dT%02d:%02d:%02d", *param.to_a))
|
||||||
|
|
||||||
when XMLRPC::Base64
|
when XMLRPC::Base64
|
||||||
@writer.tag("base64", param.encoded)
|
@writer.tag("base64", param.encoded)
|
||||||
|
|
||||||
else
|
else
|
||||||
if Config::ENABLE_MARSHALLING and param.class.included_modules.include? XMLRPC::Marshallable
|
if Config::ENABLE_MARSHALLING and param.class.included_modules.include? XMLRPC::Marshallable
|
||||||
# convert Ruby object into Hash
|
# convert Ruby object into Hash
|
||||||
ret = {"___class___" => param.class.name}
|
ret = {"___class___" => param.class.name}
|
||||||
|
@ -274,9 +274,9 @@ module XMLRPC
|
||||||
raise "Wrong type!"
|
raise "Wrong type!"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@writer.ele("value", val)
|
@writer.ele("value", val)
|
||||||
end
|
end
|
||||||
|
|
||||||
def wrong_type(value)
|
def wrong_type(value)
|
||||||
|
|
|
@ -156,7 +156,7 @@ private
|
||||||
# parse HTTP headers
|
# parse HTTP headers
|
||||||
while (line=io.gets) !~ /^(\n|\r)/
|
while (line=io.gets) !~ /^(\n|\r)/
|
||||||
if line =~ /^([\w-]+):\s*(.*)$/
|
if line =~ /^([\w-]+):\s*(.*)$/
|
||||||
request.header[$1] = $2.strip
|
request.header[$1] = $2.strip
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -160,11 +160,11 @@ module XMLRPC
|
||||||
class AbstractTreeParser
|
class AbstractTreeParser
|
||||||
|
|
||||||
def parseMethodResponse(str)
|
def parseMethodResponse(str)
|
||||||
methodResponse_document(createCleanedTree(str))
|
methodResponse_document(createCleanedTree(str))
|
||||||
end
|
end
|
||||||
|
|
||||||
def parseMethodCall(str)
|
def parseMethodCall(str)
|
||||||
methodCall_document(createCleanedTree(str))
|
methodCall_document(createCleanedTree(str))
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -174,11 +174,11 @@ module XMLRPC
|
||||||
# and all comments
|
# and all comments
|
||||||
#
|
#
|
||||||
def removeWhitespacesAndComments(node)
|
def removeWhitespacesAndComments(node)
|
||||||
remove = []
|
remove = []
|
||||||
childs = node.childNodes.to_a
|
childs = node.childNodes.to_a
|
||||||
childs.each do |nd|
|
childs.each do |nd|
|
||||||
case _nodeType(nd)
|
case _nodeType(nd)
|
||||||
when :TEXT
|
when :TEXT
|
||||||
# TODO: add nil?
|
# TODO: add nil?
|
||||||
unless %w(i4 int boolean string double dateTime.iso8601 base64).include? node.nodeName
|
unless %w(i4 int boolean string double dateTime.iso8601 base64).include? node.nodeName
|
||||||
|
|
||||||
|
@ -189,190 +189,190 @@ module XMLRPC
|
||||||
else
|
else
|
||||||
remove << nd if nd.nodeValue.strip == ""
|
remove << nd if nd.nodeValue.strip == ""
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
when :COMMENT
|
when :COMMENT
|
||||||
remove << nd
|
remove << nd
|
||||||
else
|
else
|
||||||
removeWhitespacesAndComments(nd)
|
removeWhitespacesAndComments(nd)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
remove.each { |i| node.removeChild(i) }
|
remove.each { |i| node.removeChild(i) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def nodeMustBe(node, name)
|
def nodeMustBe(node, name)
|
||||||
cmp = case name
|
cmp = case name
|
||||||
when Array
|
when Array
|
||||||
name.include?(node.nodeName)
|
name.include?(node.nodeName)
|
||||||
when String
|
when String
|
||||||
name == node.nodeName
|
name == node.nodeName
|
||||||
else
|
else
|
||||||
raise "error"
|
raise "error"
|
||||||
end
|
end
|
||||||
|
|
||||||
if not cmp then
|
if not cmp then
|
||||||
raise "wrong xml-rpc (name)"
|
raise "wrong xml-rpc (name)"
|
||||||
end
|
end
|
||||||
|
|
||||||
node
|
node
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# returns, when successfully the only child-node
|
# returns, when successfully the only child-node
|
||||||
#
|
#
|
||||||
def hasOnlyOneChild(node, name=nil)
|
def hasOnlyOneChild(node, name=nil)
|
||||||
if node.childNodes.to_a.size != 1
|
if node.childNodes.to_a.size != 1
|
||||||
raise "wrong xml-rpc (size)"
|
raise "wrong xml-rpc (size)"
|
||||||
end
|
end
|
||||||
if name != nil then
|
if name != nil then
|
||||||
nodeMustBe(node.firstChild, name)
|
nodeMustBe(node.firstChild, name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def assert(b)
|
def assert(b)
|
||||||
if not b then
|
if not b then
|
||||||
raise "assert-fail"
|
raise "assert-fail"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# the node `node` has empty string or string
|
# the node `node` has empty string or string
|
||||||
def text_zero_one(node)
|
def text_zero_one(node)
|
||||||
nodes = node.childNodes.to_a.size
|
nodes = node.childNodes.to_a.size
|
||||||
|
|
||||||
if nodes == 1
|
if nodes == 1
|
||||||
text(node.firstChild)
|
text(node.firstChild)
|
||||||
elsif nodes == 0
|
elsif nodes == 0
|
||||||
""
|
""
|
||||||
else
|
else
|
||||||
raise "wrong xml-rpc (size)"
|
raise "wrong xml-rpc (size)"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def integer(node)
|
def integer(node)
|
||||||
#TODO: check string for float because to_i returnsa
|
#TODO: check string for float because to_i returnsa
|
||||||
# 0 when wrong string
|
# 0 when wrong string
|
||||||
nodeMustBe(node, %w(i4 int))
|
nodeMustBe(node, %w(i4 int))
|
||||||
hasOnlyOneChild(node)
|
hasOnlyOneChild(node)
|
||||||
|
|
||||||
Convert.int(text(node.firstChild))
|
Convert.int(text(node.firstChild))
|
||||||
end
|
end
|
||||||
|
|
||||||
def boolean(node)
|
def boolean(node)
|
||||||
nodeMustBe(node, "boolean")
|
nodeMustBe(node, "boolean")
|
||||||
hasOnlyOneChild(node)
|
hasOnlyOneChild(node)
|
||||||
|
|
||||||
Convert.boolean(text(node.firstChild))
|
Convert.boolean(text(node.firstChild))
|
||||||
end
|
end
|
||||||
|
|
||||||
def v_nil(node)
|
def v_nil(node)
|
||||||
nodeMustBe(node, "nil")
|
nodeMustBe(node, "nil")
|
||||||
assert( node.childNodes.to_a.size == 0 )
|
assert( node.childNodes.to_a.size == 0 )
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def string(node)
|
def string(node)
|
||||||
nodeMustBe(node, "string")
|
nodeMustBe(node, "string")
|
||||||
text_zero_one(node)
|
text_zero_one(node)
|
||||||
end
|
end
|
||||||
|
|
||||||
def double(node)
|
def double(node)
|
||||||
#TODO: check string for float because to_f returnsa
|
#TODO: check string for float because to_f returnsa
|
||||||
# 0.0 when wrong string
|
# 0.0 when wrong string
|
||||||
nodeMustBe(node, "double")
|
nodeMustBe(node, "double")
|
||||||
hasOnlyOneChild(node)
|
hasOnlyOneChild(node)
|
||||||
|
|
||||||
Convert.double(text(node.firstChild))
|
Convert.double(text(node.firstChild))
|
||||||
end
|
end
|
||||||
|
|
||||||
def dateTime(node)
|
def dateTime(node)
|
||||||
nodeMustBe(node, "dateTime.iso8601")
|
nodeMustBe(node, "dateTime.iso8601")
|
||||||
hasOnlyOneChild(node)
|
hasOnlyOneChild(node)
|
||||||
|
|
||||||
Convert.dateTime( text(node.firstChild) )
|
Convert.dateTime( text(node.firstChild) )
|
||||||
end
|
end
|
||||||
|
|
||||||
def base64(node)
|
def base64(node)
|
||||||
nodeMustBe(node, "base64")
|
nodeMustBe(node, "base64")
|
||||||
#hasOnlyOneChild(node)
|
#hasOnlyOneChild(node)
|
||||||
|
|
||||||
Convert.base64(text_zero_one(node))
|
Convert.base64(text_zero_one(node))
|
||||||
end
|
end
|
||||||
|
|
||||||
def member(node)
|
def member(node)
|
||||||
nodeMustBe(node, "member")
|
nodeMustBe(node, "member")
|
||||||
assert( node.childNodes.to_a.size == 2 )
|
assert( node.childNodes.to_a.size == 2 )
|
||||||
|
|
||||||
[ name(node[0]), value(node[1]) ]
|
[ name(node[0]), value(node[1]) ]
|
||||||
end
|
end
|
||||||
|
|
||||||
def name(node)
|
def name(node)
|
||||||
nodeMustBe(node, "name")
|
nodeMustBe(node, "name")
|
||||||
#hasOnlyOneChild(node)
|
#hasOnlyOneChild(node)
|
||||||
text_zero_one(node)
|
text_zero_one(node)
|
||||||
end
|
end
|
||||||
|
|
||||||
def array(node)
|
def array(node)
|
||||||
nodeMustBe(node, "array")
|
nodeMustBe(node, "array")
|
||||||
hasOnlyOneChild(node, "data")
|
hasOnlyOneChild(node, "data")
|
||||||
data(node.firstChild)
|
data(node.firstChild)
|
||||||
end
|
end
|
||||||
|
|
||||||
def data(node)
|
def data(node)
|
||||||
nodeMustBe(node, "data")
|
nodeMustBe(node, "data")
|
||||||
|
|
||||||
node.childNodes.to_a.collect do |val|
|
node.childNodes.to_a.collect do |val|
|
||||||
value(val)
|
value(val)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def param(node)
|
def param(node)
|
||||||
nodeMustBe(node, "param")
|
nodeMustBe(node, "param")
|
||||||
hasOnlyOneChild(node, "value")
|
hasOnlyOneChild(node, "value")
|
||||||
value(node.firstChild)
|
value(node.firstChild)
|
||||||
end
|
end
|
||||||
|
|
||||||
def methodResponse(node)
|
def methodResponse(node)
|
||||||
nodeMustBe(node, "methodResponse")
|
nodeMustBe(node, "methodResponse")
|
||||||
hasOnlyOneChild(node, %w(params fault))
|
hasOnlyOneChild(node, %w(params fault))
|
||||||
child = node.firstChild
|
child = node.firstChild
|
||||||
|
|
||||||
case child.nodeName
|
case child.nodeName
|
||||||
when "params"
|
when "params"
|
||||||
[ true, params(child,false) ]
|
[ true, params(child,false) ]
|
||||||
when "fault"
|
when "fault"
|
||||||
[ false, fault(child) ]
|
[ false, fault(child) ]
|
||||||
else
|
else
|
||||||
raise "unexpected error"
|
raise "unexpected error"
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def methodName(node)
|
def methodName(node)
|
||||||
nodeMustBe(node, "methodName")
|
nodeMustBe(node, "methodName")
|
||||||
hasOnlyOneChild(node)
|
hasOnlyOneChild(node)
|
||||||
text(node.firstChild)
|
text(node.firstChild)
|
||||||
end
|
end
|
||||||
|
|
||||||
def params(node, call=true)
|
def params(node, call=true)
|
||||||
nodeMustBe(node, "params")
|
nodeMustBe(node, "params")
|
||||||
|
|
||||||
if call
|
if call
|
||||||
node.childNodes.to_a.collect do |n|
|
node.childNodes.to_a.collect do |n|
|
||||||
param(n)
|
param(n)
|
||||||
end
|
end
|
||||||
else # response (only one param)
|
else # response (only one param)
|
||||||
hasOnlyOneChild(node)
|
hasOnlyOneChild(node)
|
||||||
param(node.firstChild)
|
param(node.firstChild)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def fault(node)
|
def fault(node)
|
||||||
nodeMustBe(node, "fault")
|
nodeMustBe(node, "fault")
|
||||||
hasOnlyOneChild(node, "value")
|
hasOnlyOneChild(node, "value")
|
||||||
f = value(node.firstChild)
|
f = value(node.firstChild)
|
||||||
Convert.fault(f)
|
Convert.fault(f)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -380,76 +380,76 @@ module XMLRPC
|
||||||
|
|
||||||
# _nodeType is defined in the subclass
|
# _nodeType is defined in the subclass
|
||||||
def text(node)
|
def text(node)
|
||||||
assert( _nodeType(node) == :TEXT )
|
assert( _nodeType(node) == :TEXT )
|
||||||
assert( node.hasChildNodes == false )
|
assert( node.hasChildNodes == false )
|
||||||
assert( node.nodeValue != nil )
|
assert( node.nodeValue != nil )
|
||||||
|
|
||||||
node.nodeValue.to_s
|
node.nodeValue.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
def struct(node)
|
def struct(node)
|
||||||
nodeMustBe(node, "struct")
|
nodeMustBe(node, "struct")
|
||||||
|
|
||||||
hash = {}
|
hash = {}
|
||||||
node.childNodes.to_a.each do |me|
|
node.childNodes.to_a.each do |me|
|
||||||
n, v = member(me)
|
n, v = member(me)
|
||||||
hash[n] = v
|
hash[n] = v
|
||||||
end
|
end
|
||||||
|
|
||||||
Convert.struct(hash)
|
Convert.struct(hash)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def value(node)
|
def value(node)
|
||||||
nodeMustBe(node, "value")
|
nodeMustBe(node, "value")
|
||||||
nodes = node.childNodes.to_a.size
|
nodes = node.childNodes.to_a.size
|
||||||
if nodes == 0
|
if nodes == 0
|
||||||
return ""
|
return ""
|
||||||
elsif nodes > 1
|
elsif nodes > 1
|
||||||
raise "wrong xml-rpc (size)"
|
raise "wrong xml-rpc (size)"
|
||||||
end
|
end
|
||||||
|
|
||||||
child = node.firstChild
|
child = node.firstChild
|
||||||
|
|
||||||
case _nodeType(child)
|
case _nodeType(child)
|
||||||
when :TEXT
|
when :TEXT
|
||||||
text_zero_one(node)
|
text_zero_one(node)
|
||||||
when :ELEMENT
|
when :ELEMENT
|
||||||
case child.nodeName
|
case child.nodeName
|
||||||
when "i4", "int" then integer(child)
|
when "i4", "int" then integer(child)
|
||||||
when "boolean" then boolean(child)
|
when "boolean" then boolean(child)
|
||||||
when "string" then string(child)
|
when "string" then string(child)
|
||||||
when "double" then double(child)
|
when "double" then double(child)
|
||||||
when "dateTime.iso8601" then dateTime(child)
|
when "dateTime.iso8601" then dateTime(child)
|
||||||
when "base64" then base64(child)
|
when "base64" then base64(child)
|
||||||
when "struct" then struct(child)
|
when "struct" then struct(child)
|
||||||
when "array" then array(child)
|
when "array" then array(child)
|
||||||
when "nil"
|
when "nil"
|
||||||
if Config::ENABLE_NIL_PARSER
|
if Config::ENABLE_NIL_PARSER
|
||||||
v_nil(child)
|
v_nil(child)
|
||||||
else
|
else
|
||||||
raise "wrong/unknown XML-RPC type 'nil'"
|
raise "wrong/unknown XML-RPC type 'nil'"
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
raise "wrong/unknown XML-RPC type"
|
raise "wrong/unknown XML-RPC type"
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
raise "wrong type of node"
|
raise "wrong type of node"
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def methodCall(node)
|
def methodCall(node)
|
||||||
nodeMustBe(node, "methodCall")
|
nodeMustBe(node, "methodCall")
|
||||||
assert( (1..2).include?( node.childNodes.to_a.size ) )
|
assert( (1..2).include?( node.childNodes.to_a.size ) )
|
||||||
name = methodName(node[0])
|
name = methodName(node[0])
|
||||||
|
|
||||||
if node.childNodes.to_a.size == 2 then
|
if node.childNodes.to_a.size == 2 then
|
||||||
pa = params(node[1])
|
pa = params(node[1])
|
||||||
else # no parameters given
|
else # no parameters given
|
||||||
pa = []
|
pa = []
|
||||||
end
|
end
|
||||||
[name, pa]
|
[name, pa]
|
||||||
end
|
end
|
||||||
|
|
||||||
end # module TreeParserMixin
|
end # module TreeParserMixin
|
||||||
|
@ -635,34 +635,34 @@ module XMLRPC
|
||||||
private
|
private
|
||||||
|
|
||||||
def _nodeType(node)
|
def _nodeType(node)
|
||||||
tp = node.nodeType
|
tp = node.nodeType
|
||||||
if tp == XML::SimpleTree::Node::TEXT then :TEXT
|
if tp == XML::SimpleTree::Node::TEXT then :TEXT
|
||||||
elsif tp == XML::SimpleTree::Node::COMMENT then :COMMENT
|
elsif tp == XML::SimpleTree::Node::COMMENT then :COMMENT
|
||||||
elsif tp == XML::SimpleTree::Node::ELEMENT then :ELEMENT
|
elsif tp == XML::SimpleTree::Node::ELEMENT then :ELEMENT
|
||||||
else :ELSE
|
else :ELSE
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def methodResponse_document(node)
|
def methodResponse_document(node)
|
||||||
assert( node.nodeType == XML::SimpleTree::Node::DOCUMENT )
|
assert( node.nodeType == XML::SimpleTree::Node::DOCUMENT )
|
||||||
hasOnlyOneChild(node, "methodResponse")
|
hasOnlyOneChild(node, "methodResponse")
|
||||||
|
|
||||||
methodResponse(node.firstChild)
|
methodResponse(node.firstChild)
|
||||||
end
|
end
|
||||||
|
|
||||||
def methodCall_document(node)
|
def methodCall_document(node)
|
||||||
assert( node.nodeType == XML::SimpleTree::Node::DOCUMENT )
|
assert( node.nodeType == XML::SimpleTree::Node::DOCUMENT )
|
||||||
hasOnlyOneChild(node, "methodCall")
|
hasOnlyOneChild(node, "methodCall")
|
||||||
|
|
||||||
methodCall(node.firstChild)
|
methodCall(node.firstChild)
|
||||||
end
|
end
|
||||||
|
|
||||||
def createCleanedTree(str)
|
def createCleanedTree(str)
|
||||||
doc = XML::SimpleTreeBuilder.new.parse(str)
|
doc = XML::SimpleTreeBuilder.new.parse(str)
|
||||||
doc.documentElement.normalize
|
doc.documentElement.normalize
|
||||||
removeWhitespacesAndComments(doc)
|
removeWhitespacesAndComments(doc)
|
||||||
doc
|
doc
|
||||||
end
|
end
|
||||||
|
|
||||||
end # class XMLParser
|
end # class XMLParser
|
||||||
|
@ -676,21 +676,21 @@ module XMLRPC
|
||||||
private
|
private
|
||||||
|
|
||||||
def _nodeType(node)
|
def _nodeType(node)
|
||||||
node.nodeType
|
node.nodeType
|
||||||
end
|
end
|
||||||
|
|
||||||
def methodResponse_document(node)
|
def methodResponse_document(node)
|
||||||
methodResponse(node)
|
methodResponse(node)
|
||||||
end
|
end
|
||||||
|
|
||||||
def methodCall_document(node)
|
def methodCall_document(node)
|
||||||
methodCall(node)
|
methodCall(node)
|
||||||
end
|
end
|
||||||
|
|
||||||
def createCleanedTree(str)
|
def createCleanedTree(str)
|
||||||
doc = ::NQXML::TreeParser.new(str).document.rootNode
|
doc = ::NQXML::TreeParser.new(str).document.rootNode
|
||||||
removeWhitespacesAndComments(doc)
|
removeWhitespacesAndComments(doc)
|
||||||
doc
|
doc
|
||||||
end
|
end
|
||||||
|
|
||||||
end # class NQXMLTreeParser
|
end # class NQXMLTreeParser
|
||||||
|
@ -715,7 +715,7 @@ module XMLRPC
|
||||||
|
|
||||||
def parse(str)
|
def parse(str)
|
||||||
parser = REXML::Document.parse_stream(str, self)
|
parser = REXML::Document.parse_stream(str, self)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -37,7 +37,7 @@ module XMLRPC
|
||||||
def create
|
def create
|
||||||
# if set_writer was not already called then call it now
|
# if set_writer was not already called then call it now
|
||||||
if @create.nil? then
|
if @create.nil? then
|
||||||
set_writer(Config::DEFAULT_WRITER.new)
|
set_writer(Config::DEFAULT_WRITER.new)
|
||||||
end
|
end
|
||||||
@create
|
@create
|
||||||
end
|
end
|
||||||
|
@ -45,7 +45,7 @@ module XMLRPC
|
||||||
def parser
|
def parser
|
||||||
# if set_parser was not already called then call it now
|
# if set_parser was not already called then call it now
|
||||||
if @parser.nil? then
|
if @parser.nil? then
|
||||||
set_parser(Config::DEFAULT_PARSER.new)
|
set_parser(Config::DEFAULT_PARSER.new)
|
||||||
end
|
end
|
||||||
@parser
|
@parser
|
||||||
end
|
end
|
||||||
|
|
|
@ -1464,7 +1464,7 @@ EOA
|
||||||
_assert_maker_atom_element(feed_type, maker_readers, feed_readers,
|
_assert_maker_atom_element(feed_type, maker_readers, feed_readers,
|
||||||
maker_extractor, feed_extractor,
|
maker_extractor, feed_extractor,
|
||||||
&block)
|
&block)
|
||||||
end
|
end
|
||||||
|
|
||||||
def assert_maker_atom_generator(feed_type, maker_readers, feed_readers,
|
def assert_maker_atom_generator(feed_type, maker_readers, feed_readers,
|
||||||
not_set_error_name=nil, &block)
|
not_set_error_name=nil, &block)
|
||||||
|
|
|
@ -1260,7 +1260,7 @@ class TestArray < Test::Unit::TestCase
|
||||||
assert_equal(@cls[1,2], @cls[1, 2] | @cls[1, 2])
|
assert_equal(@cls[1,2], @cls[1, 2] | @cls[1, 2])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_combination
|
def test_combination
|
||||||
assert_equal(@cls[[]], @cls[1,2,3,4].combination(0).to_a)
|
assert_equal(@cls[[]], @cls[1,2,3,4].combination(0).to_a)
|
||||||
assert_equal(@cls[[1],[2],[3],[4]], @cls[1,2,3,4].combination(1).to_a)
|
assert_equal(@cls[[1],[2],[3],[4]], @cls[1,2,3,4].combination(1).to_a)
|
||||||
assert_equal(@cls[[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]], @cls[1,2,3,4].combination(2).to_a)
|
assert_equal(@cls[[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]], @cls[1,2,3,4].combination(2).to_a)
|
||||||
|
|
|
@ -263,5 +263,5 @@ EOS
|
||||||
# assert_raise(SyntaxError) { "\uDFFF" } # surrogate block
|
# assert_raise(SyntaxError) { "\uDFFF" } # surrogate block
|
||||||
# assert_raise(SyntaxError) { "\uD847\uDD9A" } # surrogate pair
|
# assert_raise(SyntaxError) { "\uD847\uDD9A" } # surrogate pair
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,7 +16,7 @@ class TestIOScanf < Test::Unit::TestCase;end
|
||||||
|
|
||||||
module ScanfTests
|
module ScanfTests
|
||||||
|
|
||||||
def tests
|
def tests
|
||||||
[
|
[
|
||||||
|
|
||||||
# Scratchpad
|
# Scratchpad
|
||||||
|
@ -284,8 +284,8 @@ def tests
|
||||||
[" [%d,%f", " [10,1.1", [10,1.1] ],
|
[" [%d,%f", " [10,1.1", [10,1.1] ],
|
||||||
|
|
||||||
]
|
]
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class TestStringScanf
|
class TestStringScanf
|
||||||
include Scanf
|
include Scanf
|
||||||
|
|
Loading…
Add table
Reference in a new issue