aboutsummaryrefslogtreecommitdiffstats
path: root/lib/rexml/light
diff options
context:
space:
mode:
authorser <ser@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-06-10 01:31:01 +0000
committerser <ser@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-06-10 01:31:01 +0000
commitea7a527a2ae7024a5cf2885dee8f7a5c21fedd5d (patch)
treed3e1f95a5acf262a9dd46e9663b7034bb285b406 /lib/rexml/light
parentca02190d8887ecd852e4e3f18f3a3ea91e9c6f7a (diff)
downloadruby-ea7a527a2ae7024a5cf2885dee8f7a5c21fedd5d.tar.gz
Initial revision
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3925 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/rexml/light')
-rw-r--r--lib/rexml/light/node.rb232
1 files changed, 232 insertions, 0 deletions
diff --git a/lib/rexml/light/node.rb b/lib/rexml/light/node.rb
new file mode 100644
index 0000000000..5b7b95a7dc
--- /dev/null
+++ b/lib/rexml/light/node.rb
@@ -0,0 +1,232 @@
+require 'rexml/xmltokens'
+require 'rexml/light/node'
+
+# Development model
+# document = Node.new
+
+# Add an element "foo" to the document
+# foo = document << "foo"
+# # Set attribute "attr" on foo
+# foo["attr"] = "la"
+# # Set another attribute in a different namespace
+# foo["attr", "namespace"] = "too"
+# # Swap foo into another namespace
+# foo.namespace = "blah"
+# # Add a couple of element nodes to foo
+# foo << "a"
+# foo << "b"
+# # Access the children of foo in various ways
+# a = foo[0]
+# foo.each { |child|
+# #...
+# }
+# # Add text to foo
+# # Add instruction
+# # Add comment
+# # Get the root of the document
+# document == a.root
+# # Write the document out
+# puts document.to_s
+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 < Array
+ alias :_old_get :[]
+ alias :_old_put :[]=
+
+ NAMESPLIT = /^(?:(#{XMLTokens::NCNAME_STR}):)?(#{XMLTokens::NCNAME_STR})/u
+ # Create a new element.
+ def initialize node=nil
+ if node.kind_of? String
+ node = [ :text, node ]
+ elsif node.nil?
+ node = [ :start_document, nil, nil ]
+ end
+ replace( node )
+ _old_put( 1, 0, 1 )
+ _old_put( 1, nil )
+ end
+
+ def size
+ el!()
+ super-4
+ end
+
+ def each( &block )
+ el!()
+ size.times { |x| yield( at(x+4) ) }
+ end
+
+ def name
+ el!()
+ at(2)
+ end
+
+ def name=( name_str, ns=nil )
+ el!()
+ pfx = ''
+ pfx = "#{prefix(ns)}:" if ns
+ _old_put(1, "#{pfx}#{name_str}")
+ end
+
+ def parent=( node )
+ _old_put(1,node)
+ end
+
+ def local_name
+ el!()
+ namesplit
+ @name
+ end
+
+ def local_name=( name_str )
+ el!()
+ _old_put( 1, "#@prefix:#{name_str}" )
+ end
+
+ def prefix( namespace=nil )
+ el!()
+ prefix_of( self, namespace )
+ end
+
+ def namespace( prefix=prefix() )
+ el!()
+ namespace_of( self, prefix )
+ end
+
+ def namespace=( namespace )
+ el!()
+ @prefix = prefix( namespace )
+ pfx = ''
+ pfx = "#@prefix:" if @prefix.size > 0
+ _old_put(1, "#{pfx}#@name")
+ end
+
+ def []( reference, ns=nil )
+ el!()
+ 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
+
+ # Doesn't handle namespaces yet
+ def []=( reference, ns, value=nil )
+ el!()
+ 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 text?
+ at(-1) << element
+ else
+ newnode = Node.new( element )
+ newnode.parent = self
+ self.push( newnode )
+ end
+ at(-1)
+ end
+
+ def node_type
+ self[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 element?
+ at(0) == :start_element
+ end
+
+ def has_name?( name, namespace = '' )
+ el!()
+ at(3) == name and namespace() == namespace
+ end
+
+ def children
+ el!()
+ self
+ end
+
+ def parent
+ at(1)
+ end
+
+ def text?
+ at(0) == :text
+ end
+
+ def to_s
+
+ end
+
+ def el!
+ if text?()
+ _old_put( 0, :start_element )
+ push({})
+ end
+ 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