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