xml-smart 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/AUTHORS +4 -0
  2. data/COPYING +504 -0
  3. data/README.rdoc +55 -0
  4. data/Rakefile +15 -0
  5. data/example/EXAMPLE.xml +18 -0
  6. data/example/xpath_visual.rb +54 -0
  7. data/lib/xml/XSDtoRNG.xsl +448 -0
  8. data/lib/xml/smart.rb +177 -0
  9. data/lib/xml/smart_dom.rb +118 -0
  10. data/lib/xml/smart_domattribute.rb +34 -0
  11. data/lib/xml/smart_domattributeset.rb +62 -0
  12. data/lib/xml/smart_domelement.rb +213 -0
  13. data/lib/xml/smart_domnamespace.rb +32 -0
  14. data/lib/xml/smart_domnamespaceset.rb +125 -0
  15. data/lib/xml/smart_domnodeset.rb +59 -0
  16. data/lib/xml/smart_domother.rb +16 -0
  17. data/lib/xml/smart_domtext.rb +25 -0
  18. data/lib/xml/smart_qname.rb +34 -0
  19. data/test/1.xml +1 -0
  20. data/test/2.xml +1 -0
  21. data/test/3.xml +1 -0
  22. data/test/EXAMPLE-NS.xml +18 -0
  23. data/test/EXAMPLE-NSE.xml +18 -0
  24. data/test/EXAMPLE.str.xml +6 -0
  25. data/test/EXAMPLE.str.xml.test +6 -0
  26. data/test/EXAMPLE.tmp.xml +4 -0
  27. data/test/EXAMPLE.tmp.xml.test +4 -0
  28. data/test/EXAMPLE.xml +17 -0
  29. data/test/HELLO-MORE.xml +1 -0
  30. data/test/HELLO.rng +9 -0
  31. data/test/HELLO.xml +8 -0
  32. data/test/HELLO.xsd +16 -0
  33. data/test/XSL_BASE.xml +17 -0
  34. data/test/XSL_BASE.xml.test +16 -0
  35. data/test/XSL_DOCUMENT.xml +48 -0
  36. data/test/concurrent.xml +1 -0
  37. data/test/smartrunner.rb +25 -0
  38. data/test/tc_add.rb +21 -0
  39. data/test/tc_basic.rb +108 -0
  40. data/test/tc_concurrent.rb +73 -0
  41. data/test/tc_copy.rb +41 -0
  42. data/test/tc_create.rb +32 -0
  43. data/test/tc_delete.rb +52 -0
  44. data/test/tc_move_elements.rb +24 -0
  45. data/test/tc_namespace_default.rb +70 -0
  46. data/test/tc_namespace_detailed.rb +44 -0
  47. data/test/tc_namespace_find.rb +22 -0
  48. data/test/tc_nested.rb +26 -0
  49. data/test/tc_qname.rb +30 -0
  50. data/test/tc_relaxng.rb +30 -0
  51. data/test/tc_set_or_replace.rb +57 -0
  52. data/test/tc_sort.rb +18 -0
  53. data/test/tc_string.rb +41 -0
  54. data/test/tc_todoc.rb +27 -0
  55. data/test/tc_write.rb +19 -0
  56. data/test/tc_xinclude.rb +26 -0
  57. data/test/tc_xmlschema.rb +30 -0
  58. data/test/tc_xpath.rb +16 -0
  59. data/test/tc_xpath_attrs.rb +24 -0
  60. data/test/tc_xpath_functions.rb +12 -0
  61. data/test/tc_xpath_root.rb +23 -0
  62. data/test/tc_xsl.rb +22 -0
  63. data/xml-smart.gemspec +26 -0
  64. metadata +201 -0
@@ -0,0 +1,118 @@
1
+ module XML
2
+ module Smart
3
+ class Dom
4
+ def initialize(dom)
5
+ @dom = dom
6
+ @save_unformated = false
7
+ end
8
+
9
+ def ===(cls); self.is_a? cls; end
10
+
11
+ def root
12
+ Element.new(@dom.root)
13
+ end
14
+ def root=(nr)
15
+ @dom.root.replace(nr.instance_variable_get(:@element)) if nr.instance_of? Element
16
+ end
17
+
18
+ def find(path)
19
+ Element.new(@dom.root).find(path)
20
+ end
21
+
22
+ def to_s
23
+ @dom.to_s
24
+ end
25
+
26
+ def namespaces
27
+ @dom.custom_namespace_prefixes.merge @dom.user_custom_namespace_prefixes
28
+ end
29
+ def register_namespace(a,b)
30
+ if a.respond_to?(:to_s) && b.respond_to?(:to_s) && !@dom.custom_namespace_prefixes.key?(a.to_s) && @dom.custom_namespace_prefixes.value?(b.to_s)
31
+ @dom.user_custom_namespace_prefixes[a.to_s] = b.to_s
32
+ @dom.ns_update
33
+ true
34
+ else
35
+ false
36
+ end
37
+ end
38
+ def unregister_namespace(a)
39
+ if a.respond_to?(:to_s) && @dom.user_custom_namespace_prefixes.key?(a.to_s)
40
+ @dom.user_custom_namespace_prefixes.delete(a.to_s)
41
+ @dom.ns_update
42
+ true
43
+ else
44
+ false
45
+ end
46
+ end
47
+
48
+ def save_as(name)
49
+ raise Error, 'first parameter has to be a filename or filehandle' unless name.is_a?(String) || name.is_a?(IO)
50
+ begin
51
+ io = name.is_a?(String) ? ::Kernel::open(name,'w') : name
52
+ rescue
53
+ raise Error, "could not open #{name}"
54
+ end
55
+ ftext = if @save_unformated
56
+ @dom.root.serialize(:encoding => 'UTF-8', :save_with => Nokogiri::XML::Node::SaveOptions::NO_DECLARATION | Nokogiri::XML::Node::SaveOptions::AS_XML)
57
+ else
58
+ @dom.root.serialize(:encoding => 'UTF-8', :save_with => Nokogiri::XML::Node::SaveOptions::FORMAT | Nokogiri::XML::Node::SaveOptions::AS_XML)
59
+ end
60
+ io.write ftext
61
+ io.close
62
+ end
63
+
64
+ def save_unformated=(val); @save_unformated = (val.is_a?(TrueClass) ? true : false); end
65
+ def save_unformated?; @save_unformated; end
66
+
67
+ def xinclude!
68
+ Element.new(@dom.root).xinclude!
69
+ end
70
+
71
+ def self::smart_helper(node)
72
+ if node.instance_of? Nokogiri::XML::Element
73
+ Element.new(node)
74
+ elsif node.instance_of? Nokogiri::XML::Attr
75
+ Attribute.new(node)
76
+ elsif node.instance_of? Nokogiri::XML::NodeSet
77
+ NodeSet.new(node)
78
+ elsif node.instance_of?(String) || node.instance_of?(TrueClass) || node.instance_of?(FalseClass) || node.instance_of?(Float)
79
+ node
80
+ elsif node.instance_of? Nokogiri::XML::Text
81
+ Text.new(node)
82
+ elsif node.instance_of? Nokogiri::XML::Namespace
83
+ Namespace.new(node)
84
+ elsif node.instance_of? Nokogiri::XML::Document
85
+ Dom.new(node)
86
+ elsif node.nil?
87
+ nil
88
+ else
89
+ Other.new(node)
90
+ end
91
+ end
92
+
93
+ def validate_against(doc,&errbl)
94
+ raise Error, 'first parameter has to XML::Smart::Dom document' unless doc.instance_of? Dom
95
+ res = if doc.root.namespaces.has_ns?("http://relaxng.org/ns/structure/1.0")
96
+ Nokogiri::XML::RelaxNG.from_document(doc.instance_variable_get(:@dom)).validate(@dom)
97
+ elsif doc.root.namespaces.has_ns?("http://www.w3.org/2001/XMLSchema")
98
+ tdoc = Nokogiri::XSLT.parse(File.read(File.expand_path(File.dirname(__FILE__) + '/XSDtoRNG.xsl')))
99
+ rdoc = tdoc.transform(doc.instance_variable_get(:@dom))
100
+ Nokogiri::XML::RelaxNG.from_document(rdoc).validate(@dom)
101
+ end
102
+ res.each { |err| errbl.call err } if block_given?
103
+ res.empty?
104
+ end
105
+
106
+ def transform_with(doc,params=nil)
107
+ raise Error, 'first parameter has to XML::Smart::Dom document' unless doc.instance_of? Dom
108
+ res = Nokogiri::XSLT::Stylesheet.parse_stylesheet_doc(doc.instance_variable_get(:@dom)).transform(@dom,params)
109
+ if res.children.length != 0 && res.children.first.class == Nokogiri::XML::Text
110
+ Text.new(res.children.first).text
111
+ else
112
+ Dom::smart_helper(res)
113
+ end
114
+ end
115
+
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,34 @@
1
+ module XML
2
+ module Smart
3
+ class Dom
4
+
5
+ class Attribute
6
+ def initialize(attr)
7
+ @attr = attr
8
+ end
9
+
10
+ def ===(cls); self.is_a? cls; end
11
+
12
+ def to_s; @attr.content; end
13
+ def to_i; @attr.content.to_i; end
14
+ def to_f; @attr.content.to_f; end
15
+
16
+ def qname; QName.new @attr; end
17
+ def path; @attr.path; end
18
+
19
+ def value; @attr.content; end;
20
+ def value=(val); @attr.content = val; end;
21
+
22
+ def ==(other)
23
+ return false unless other
24
+ return false unless other.respond_to?(:unique_id)
25
+ unique_id == other.unique_id
26
+ end
27
+ def unique_id; @attr.pointer_id; end
28
+
29
+ def parent; Dom::smart_helper(@attr.parent); end
30
+ end
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,62 @@
1
+ module XML
2
+ module Smart
3
+ class Dom
4
+
5
+ class AttributeSet
6
+ include Enumerable
7
+
8
+ def initialize(element)
9
+ @element = element
10
+ @set = @element.attributes
11
+ end
12
+
13
+ def ===(cls); self.is_a? cls; end
14
+
15
+ def has_attr?(a); @set.has_key?(a) end
16
+ alias :include? :has_attr?
17
+ alias :attr? :has_attr?
18
+ alias :member? :has_attr?
19
+
20
+ def [](name,attr=false)
21
+ return nil unless @set[name]
22
+ if attr == false
23
+ @element[name]
24
+ else
25
+ Attribute.new(@set[name])
26
+ end
27
+ end
28
+ def []=(name,value);
29
+ @element[name] = value
30
+ end
31
+
32
+ def length; @set.length; end
33
+ def empty?; @set.empty?; end
34
+ def delete_all!; @set.each { |k,a| a.remove }; end
35
+
36
+ def each(&block)
37
+ @set.each do |k,node|
38
+ block.call Dom::smart_helper(node)
39
+ end
40
+ end
41
+
42
+ def delete_at!(name)
43
+ tmp = @set[name]
44
+ if tmp === Nokogiri::XML::Attr
45
+ tmp.remove
46
+ true
47
+ else
48
+ false
49
+ end
50
+ end
51
+
52
+ def delete_if!(&block)
53
+ @set.each do |k,node|
54
+ node.remove if block.call(Dom::smart_helper(node))
55
+ end
56
+ end
57
+ end
58
+
59
+ end
60
+ end
61
+ end
62
+
@@ -0,0 +1,213 @@
1
+ module XML
2
+ module Smart
3
+ class Dom
4
+
5
+ class Element
6
+ def initialize(element)
7
+ @element = element
8
+ end
9
+
10
+ def ===(cls); self.is_a? cls; end
11
+
12
+ def find(xpath)
13
+ Dom::smart_helper(@element.xpath_fast(xpath))
14
+ end
15
+
16
+ def add_helper(attrs)
17
+ if attrs.length>0 && attrs[0].is_a?(String)
18
+ pfx = ''
19
+ ns = nil
20
+ if attrs[0].sub!(/([^:]+):/, '')
21
+ pfx = $1
22
+ if @element.document.user_custom_namespace_prefixes.has_key?(pfx)
23
+ @element.document.custom_namespace_prefixes.each do |k,v|
24
+ if @element.document.user_custom_namespace_prefixes[pfx] == v
25
+ ns = @element.document.user_custom_namespace_prefixes[pfx]
26
+ end
27
+ end
28
+ end
29
+ if ns.nil?
30
+ if @element.document.custom_namespace_prefixes.has_key?(pfx)
31
+ ns = @element.document.custom_namespace_prefixes[pfx]
32
+ else
33
+ raise Error, 'No valid namespace'
34
+ end
35
+ end
36
+ end
37
+ tmp = Nokogiri::XML::Node.new attrs[0], @element.document
38
+ unless ns.nil?
39
+ @element.namespace_scopes.each do |nss|
40
+ tmp.namespace = nss if nss.href == ns
41
+ end
42
+ end
43
+ [1,2].each do |i|
44
+ if attrs.length > i
45
+ case attrs[i]
46
+ when Hash
47
+ attrs[i].each do |k,v|
48
+ if k.respond_to?(:to_s)
49
+ tmp[k.to_s] = v.respond_to?(:to_s) ? v.to_s : ''
50
+ else
51
+ raise Error, 'use something that has provides #to_s'
52
+ end
53
+ end
54
+ else
55
+ tmp.content = attrs[i].respond_to?(:to_s) ? attrs[i].to_s : ''
56
+ end
57
+ end
58
+ end
59
+ return [tmp,false]
60
+ end
61
+ if attrs.length == 1 && attrs[0].is_a?(XML::Smart::Dom::Element)
62
+ ele = attrs[0].instance_variable_get(:@element)
63
+ same = ele.document.root.pointer_id == @element.document.root.pointer_id
64
+ return [same ? ele : ele.dup, !same]
65
+ end
66
+ if attrs.length == 1 && attrs[0].is_a?(XML::Smart::Dom::NodeSet)
67
+ nos = attrs[0].instance_variable_get(:@nodeset)
68
+ if nos.length > 0
69
+ same = nos.first.document.root.pointer_id == @element.document.root.pointer_id
70
+ if same
71
+ return [nos, false]
72
+ else
73
+ tnos = nos.map{|e|e.dup}
74
+ return [Nokogiri::XML::NodeSet.new(nos.first.document,tnos), true]
75
+ end
76
+ else
77
+ return [nos, false]
78
+ end
79
+ end
80
+ if attrs.length == 2 && attrs[0].is_a?(XML::Smart::Dom::Element) && (attrs[1] == XML::Smart::COPY || attrs[1] == XML::Smart::MOVE)
81
+ ele = attrs[0].instance_variable_get(:@element)
82
+ same = ele.document.root.pointer_id == @element.document.root.pointer_id
83
+ return [attrs[1] == XML::Smart::COPY ? ele.dup : ele, !same]
84
+ end
85
+ if attrs.length == 2 && attrs[0].is_a?(XML::Smart::Dom::NodeSet) && (attrs[1] == XML::Smart::COPY || attrs[1] == XML::Smart::MOVE)
86
+ nos = attrs[0].instance_variable_get(:@nodeset)
87
+ if nos.length > 0
88
+ same = nos.first.document.root.pointer_id == @element.document.root.pointer_id
89
+ if attrs[1] == XML::Smart::COPY
90
+ tnos = nos.map{|e|e.dup}
91
+ nos = Nokogiri::XML::NodeSet.new(nos.first.document,tnos)
92
+ end
93
+ return [Nokogiri::XML::NodeSet.new(nos.first.document,tnos), true]
94
+ return [nos, !same]
95
+ else
96
+ return [nos, false]
97
+ end
98
+ end
99
+ return [nil, false]
100
+ end
101
+ private :add_helper
102
+ def add(*attrs)
103
+ tmp, update = add_helper(attrs)
104
+ res = Dom::smart_helper(@element.add_child tmp)
105
+ if update
106
+ @element.document.custom_namespace_prefixes_update
107
+ @element.document.ns_update
108
+ end
109
+ res
110
+ end
111
+ def add_before(*attrs)
112
+ tmp, update = add_helper(attrs)
113
+ res = Dom::smart_helper(@element.add_previous_sibling tmp)
114
+ if update
115
+ @element.document.custom_namespace_prefixes_update
116
+ @element.document.ns_update
117
+ end
118
+ res
119
+ end
120
+ def add_after(*attrs)
121
+ tmp, update = add_helper(attrs)
122
+ res = Dom::smart_helper(@element.add_next_sibling tmp)
123
+ if update
124
+ @element.document.custom_namespace_prefixes_update
125
+ @element.document.ns_update
126
+ end
127
+ res
128
+ end
129
+
130
+ def dump; @element.to_s; end
131
+ def to_s; @element.content; end
132
+ def to_i; @element.content.to_i; end
133
+ def to_f; @element.content.to_f; end
134
+
135
+ def namespace?; !@element.namespace.nil?; end
136
+ def namespace; namespace? ? Namespace.new(@element.namespace) : nil; end
137
+ def namespace=(n)
138
+ n = case n
139
+ when Namespace
140
+ n.prefix
141
+ when String
142
+ n
143
+ else
144
+ return
145
+ end
146
+ tmp = @element.document.custom_namespace_prefixes[n] || @element.document.user_custom_namespace_prefixes[n]
147
+ unless tmp.nil?
148
+ @element.namespace_scopes.each do |nss|
149
+ @element.namespace = nss if nss.href == tmp
150
+ end
151
+ end
152
+ end
153
+ def namespaces; NamespaceSet.new(self,@element); end
154
+
155
+ def xinclude!
156
+ @element.do_xinclude
157
+ @element.document.custom_namespace_prefixes_update
158
+ @element.document.ns_update
159
+ true
160
+ end
161
+
162
+ def replace_by(n)
163
+ case n
164
+ when Element; Element.new @element.replace(n.instance_variable_get(:@element))
165
+ when NodeSet; NodeSet.new @element.replace(n.instance_variable_get(:@nodeset))
166
+ else
167
+ nil
168
+ end
169
+ end
170
+
171
+ def qname; QName.new @element; end
172
+ def attributes; AttributeSet.new @element; end
173
+
174
+ def text; @element.xpath_fast("string(text())"); end
175
+ def text=(t); @element.content = t.to_s if t.respond_to? :to_s; end
176
+
177
+ def children; find('*'); end
178
+ def children?; find('*').length > 0 end
179
+ def parent
180
+ Dom::smart_helper(@element.parent)
181
+ end
182
+ def parent?; !@element.parent.nil?; end
183
+
184
+ def empty?; @element.blank?; end
185
+ def mixed?;
186
+ @element.xpath_fast('*').length > 0 && @element.xpath_fast("string(text())") != '';
187
+ end
188
+ def text_only?;
189
+ @element.xpath_fast('*').length == 0 && @element.xpath_fast("string(text())") != '';
190
+ end
191
+ def element_only?;
192
+ @element.xpath_fast('*').length > 0 && @element.xpath_fast("string(text())") == '';
193
+ end
194
+
195
+ def path; @element.path; end
196
+
197
+ def ==(other)
198
+ return false unless other
199
+ return false unless other.respond_to?(:unique_id)
200
+ unique_id == other.unique_id
201
+ end
202
+ def unique_id; @element.pointer_id; end
203
+
204
+ def to_doc
205
+ doc = Nokogiri::XML::Document.new
206
+ doc.root = @element
207
+ dom = Dom.new(doc)
208
+ end
209
+ end
210
+
211
+ end
212
+ end
213
+ end
@@ -0,0 +1,32 @@
1
+ module XML
2
+ module Smart
3
+ class Dom
4
+
5
+ class Namespace
6
+ def initialize(ns)
7
+ @ns = ns
8
+ end
9
+
10
+ def ===(cls); self.is_a? cls; end
11
+
12
+ def href; @ns.href; end
13
+ alias :to_s :href
14
+
15
+ def prefix
16
+ if @ns.prefix
17
+ @ns.prefix
18
+ else
19
+ @ns.document.custom_namespace_prefixes.find{|k,v| v == @ns.href}[0]
20
+ end
21
+ end
22
+
23
+ def ==(other)
24
+ return false unless other
25
+ return false unless other.respond_to?(:to_s)
26
+ to_s == other.to_s
27
+ end
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,125 @@
1
+ module XML
2
+ module Smart
3
+ class Dom
4
+
5
+ class NamespaceSet
6
+ include Enumerable
7
+
8
+ def initialize(parent,node)
9
+ @parent = parent
10
+ @node = node
11
+ end
12
+
13
+ def ===(cls); self.is_a? cls; end
14
+
15
+ def has_ns?(a); @node.namespace_definitions.one?{|e| e.href == a || e.prefix == a}; end
16
+ alias :include? :has_ns?
17
+ alias :ns? :has_ns?
18
+ alias :member? :has_ns?
19
+
20
+ def [](name)
21
+ if name.nil? || name.respond_to?(:to_s)
22
+ name = name.to_s unless name.nil?
23
+ name = nil if name =~ /^xmlns\d*$/
24
+ nd = @node.namespace_definitions.find{|n| n.prefix == name}
25
+ (name.respond_to?(:to_s) || name.nil?) && nd ? Namespace.new(nd) : nil;
26
+ end
27
+ end
28
+ def []=(name,value)
29
+ self.add(name,value)
30
+ end
31
+
32
+ def add(name,value)
33
+ if (name.respond_to?(:to_s) || name.nil?) && value.respond_to?(:to_s)
34
+ nnod = Nokogiri::XML::Node.new(@node.name,@node.document)
35
+ nnew = Element.new(nnod)
36
+ nold = Element.new(@node)
37
+ nold.attributes.each do |attr|
38
+ nnew.attributes[attr.qname.name] = attr.value
39
+ end
40
+ ns = nnod.add_namespace_definition(name,value)
41
+ @node.namespace_definitions.each do |ns|
42
+ nnod.add_namespace_definition(ns.prefix,ns.href)
43
+ end
44
+ nnew.add(nold.children)
45
+ nold.replace_by(nnew)
46
+ @node = nnod
47
+ @parent.instance_variable_set(:@element,@node)
48
+ @node.document.custom_namespace_prefixes_update
49
+ @node.document.ns_update
50
+ Namespace.new(ns)
51
+ end
52
+ end
53
+
54
+ def length; @node.namespace_definitions.length; end
55
+ def empty?; @node.namespace_definitions.empty?; end
56
+ def delete_all!
57
+ nnod = Nokogiri::XML::Node.new(@node.name,@node.document)
58
+ nnew = Element.new(nnod)
59
+ nold = Element.new(@node)
60
+ nold.attributes.each do |attr|
61
+ nnew.attributes[attr.qname.name] = attr.value
62
+ end
63
+ nnew.add(nold.children)
64
+ nold.replace_by(nnew)
65
+ @node = nnod
66
+ @parent.instance_variable_set(:@element,@node)
67
+ @node.document.custom_namespace_prefixes_update
68
+ @node.document.ns_update
69
+ nil
70
+ end
71
+
72
+ def each(&block)
73
+ @node.namespace_definitions.each do |ns|
74
+ block.call Namespace.new(ns)
75
+ end
76
+ end
77
+
78
+ def delete_at(name)
79
+ if (name.respond_to?(:to_s) || name.nil?)
80
+ return false unless @node.namespace_definitions.one?{|e| e.prefix == name}
81
+
82
+ nnod = Nokogiri::XML::Node.new(@node.name,@node.document)
83
+ nnew = Element.new(nnod)
84
+ nold = Element.new(@node)
85
+ nold.attributes.each do |attr|
86
+ nnew.attributes[attr.qname.name] = attr.value
87
+ end
88
+ @node.namespace_definitions.each do |ns|
89
+ nnod.add_namespace_definition(ns.prefix,ns.href) unless ns.prefix == name
90
+ end
91
+ nnew.add(nold.children)
92
+ nold.replace_by(nnew)
93
+ @node = nnod
94
+ @parent.instance_variable_set(:@element,@node)
95
+ @node.document.custom_namespace_prefixes_update
96
+ @node.document.ns_update
97
+ true
98
+ else
99
+ false
100
+ end
101
+ end
102
+
103
+ def delete_if(&block)
104
+ nnod = Nokogiri::XML::Node.new(@node.name,@node.document)
105
+ nnew = Element.new(nnod)
106
+ nold = Element.new(@node)
107
+ nold.attributes.each do |attr|
108
+ nnew.attributes[attr.qname.name] = attr.value
109
+ end
110
+ @node.namespace_definitions.each do |ns|
111
+ nnod.add_namespace_definition(ns.prefix,ns.href) unless block.call(Dom::smart_helper(ns))
112
+ end
113
+ nnew.add(nold.children)
114
+ nold.replace_by(nnew)
115
+ @node = nnod
116
+ @parent.instance_variable_set(:@element,@node)
117
+ @node.document.custom_namespace_prefixes_update
118
+ @node.document.ns_update
119
+ self
120
+ end
121
+ end
122
+
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,59 @@
1
+ module XML
2
+ module Smart
3
+ class Dom
4
+
5
+ class NodeSet
6
+ include Enumerable
7
+
8
+ def initialize(nodeset)
9
+ @nodeset = nodeset
10
+ end
11
+
12
+ def ===(cls); self.is_a? cls; end
13
+
14
+ def first; Dom::smart_helper(@nodeset.first); end
15
+ def last; Dom::smart_helper(@nodeset.last); end
16
+ def at(*a); Dom::smart_helper(@nodeset[*a]); end
17
+ def [](*a); Dom::smart_helper(@nodeset[*a]); end
18
+
19
+ def length; @nodeset.length; end
20
+ def empty?; @nodeset.empty?; end
21
+ def delete_all!; @nodeset.remove; @nodeset.to_a.each { |n| @nodeset.delete(n) }; true end
22
+
23
+ def each(&block)
24
+ @nodeset.each do |node|
25
+ block.call Dom::smart_helper(node)
26
+ end
27
+ end
28
+
29
+ def delete_at(*a)
30
+ tmp = @nodeset[*a]
31
+ case tmp
32
+ when Nokogiri::XML::NodeSet
33
+ tmp.each { |node| @nodeset.delete(node.remove) }
34
+ true
35
+ when Nokogiri::XML::Node
36
+ @nodeset.delete(tmp.remove)
37
+ true
38
+ else
39
+ false
40
+ end
41
+ end
42
+
43
+ def delete_if(&block)
44
+ tmp = []
45
+ @nodeset.each do |node|
46
+ if block.call(Dom::smart_helper(node))
47
+ tmp << node.remove
48
+ end
49
+ end
50
+ tmp.each { |t| @nodeset.delete(t) }
51
+ self
52
+ end
53
+
54
+ end
55
+
56
+ end
57
+ end
58
+ end
59
+
@@ -0,0 +1,16 @@
1
+ module XML
2
+ module Smart
3
+ class Dom
4
+
5
+ class Other < Text
6
+ def otype
7
+ case @text
8
+ when Nokogiri::XML::Comment; :comment
9
+ else; :unknown
10
+ end
11
+ end
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,25 @@
1
+ module XML
2
+ module Smart
3
+ class Dom
4
+
5
+ class Text
6
+ def initialize(text); @text = text; end
7
+
8
+ def ===(cls); self.is_a? cls; end
9
+
10
+ def dump; to_s; end
11
+ def to_s; @text.content.to_s; end
12
+ def to_f; @text.content.to_f; end
13
+ def to_i; @text.content.to_i; end
14
+
15
+ def text; @text.content; end
16
+ def text=(t); @text.content = t.to_s if t.respond_to? :to_s; end
17
+
18
+ def parent; Node.new(@text.parent); end
19
+
20
+ def path; @text.path; end
21
+ end
22
+
23
+ end
24
+ end
25
+ end