1
require 'rexml/xmltokens'
2
require 'rexml/light/node'
4
# [ :element, parent, name, attributes, children* ]
6
# a << "B" # => <a>B</a>
7
# a.b # => <a>B<b/></a>
8
# a.b[1] # => <a>B<b/><b/><a>
9
# a.b[1]["x"] = "y" # => <a>B<b/><b x="y"/></a>
10
# a.b[0].c # => <a>B<b><c/></b><b x="y"/></a>
11
# a.b.c << "D" # => <a>B<b><c>D</c></b><b x="y"/></a>
14
# Represents a tagged XML element. Elements are characterized by
15
# having children, attributes, and names, and can themselves be
18
NAMESPLIT = /^(?:(#{XMLTokens::NCNAME_STR}):)?(#{XMLTokens::NCNAME_STR})/u
19
PARENTS = [ :element, :document, :doctype ]
20
# Create a new element.
21
def initialize node=nil
23
if node.kind_of? String
24
node = [ :text, node ]
26
node = [ :document, nil, nil ]
27
elsif node[0] == :start_element
29
elsif node[0] == :start_doctype
31
elsif node[0] == :start_document
37
if PARENTS.include? @node[0]
45
size.times { |x| yield( at(x+4) ) }
52
def name=( name_str, ns=nil )
54
pfx = "#{prefix(ns)}:" if ns
55
_old_put(2, "#{pfx}#{name_str}")
67
def local_name=( name_str )
68
_old_put( 1, "#@prefix:#{name_str}" )
71
def prefix( namespace=nil )
72
prefix_of( self, namespace )
75
def namespace( prefix=prefix() )
76
namespace_of( self, prefix )
79
def namespace=( namespace )
80
@prefix = prefix( namespace )
82
pfx = "#@prefix:" if @prefix.size > 0
83
_old_put(1, "#{pfx}#@name")
86
def []( reference, ns=nil )
87
if reference.kind_of? String
89
pfx = "#{prefix(ns)}:" if ns
90
at(3)["#{pfx}#{reference}"]
91
elsif reference.kind_of? Range
92
_old_get( Range.new(4+reference.begin, reference.end, reference.exclude_end?) )
94
_old_get( 4+reference )
99
XPath.match( self, path )
102
# Doesn't handle namespaces yet
103
def []=( reference, ns, value=nil )
104
if reference.kind_of? String
105
value = ns unless value
106
at( 3 )[reference] = value
107
elsif reference.kind_of? Range
108
_old_put( Range.new(3+reference.begin, reference.end, reference.exclude_end?), ns )
111
_old_put( 4+reference, ns, value )
113
_old_put( 4+reference, ns )
118
# Append a child to this element, optionally under a provided namespace.
119
# The namespace argument is ignored if the element argument is an Element
120
# object. Otherwise, the element argument is a string, the namespace (if
121
# provided) is the namespace the element is created in.
123
if node_type() == :text
126
newnode = Node.new( element )
127
newnode.parent = self
138
replace = at(4).kind_of?(String)? 1 : 0
139
self._old_put(4,replace, normalizefoo)
144
context = context.at(1) while context.at(1)
147
def has_name?( name, namespace = '' )
148
at(3) == name and namespace() == namespace
166
return if @name.defined?
172
def namespace_of( node, prefix=nil )
179
to_find = "xmlns:#{prefix}" if not prefix.nil?
180
ns = at(3)[ to_find ]
181
ns ? ns : namespace_of( @node[0], prefix )
184
def prefix_of( node, namespace=nil )
190
ns = at(3).find { |k,v| v == namespace }
191
ns ? ns : prefix_of( node.parent, namespace )