vcdom 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/vcdom/attr.rb +70 -0
- data/lib/vcdom/attr_node_map.rb +30 -0
- data/lib/vcdom/attr_ns.rb +38 -0
- data/lib/vcdom/character_data.rb +22 -0
- data/lib/vcdom/child.rb +53 -0
- data/lib/vcdom/document.rb +126 -0
- data/lib/vcdom/element.rb +332 -0
- data/lib/vcdom/element_ns.rb +44 -0
- data/lib/vcdom/node.rb +278 -0
- data/lib/vcdom/node_list.rb +32 -0
- data/lib/vcdom/parent.rb +126 -0
- data/lib/vcdom/text.rb +23 -0
- data/lib/vcdom/xml_parser.rb +368 -0
- data/lib/vcdom/xml_serializer.rb +55 -0
- metadata +48 -81
- data/History.txt +0 -4
- data/Manifest.txt +0 -34
- data/PostInstall.txt +0 -7
- data/README.rdoc +0 -51
- data/Rakefile +0 -26
- data/lib/vcdom/minidom/attr.rb +0 -139
- data/lib/vcdom/minidom/attr_ns.rb +0 -47
- data/lib/vcdom/minidom/cdata_section.rb +0 -34
- data/lib/vcdom/minidom/character_data.rb +0 -263
- data/lib/vcdom/minidom/comment.rb +0 -34
- data/lib/vcdom/minidom/document.rb +0 -245
- data/lib/vcdom/minidom/dom_exception.rb +0 -51
- data/lib/vcdom/minidom/dom_implementation.rb +0 -214
- data/lib/vcdom/minidom/element.rb +0 -512
- data/lib/vcdom/minidom/element_ns.rb +0 -42
- data/lib/vcdom/minidom/mini_parser.rb +0 -9
- data/lib/vcdom/minidom/mini_serializer.rb +0 -118
- data/lib/vcdom/minidom/minidom_standard_error.rb +0 -9
- data/lib/vcdom/minidom/mod_child_node.rb +0 -51
- data/lib/vcdom/minidom/mod_elements_getter.rb +0 -49
- data/lib/vcdom/minidom/mod_namespaceuri_manageable.rb +0 -152
- data/lib/vcdom/minidom/mod_parent_node.rb +0 -307
- data/lib/vcdom/minidom/named_node_map_attr.rb +0 -277
- data/lib/vcdom/minidom/node.rb +0 -178
- data/lib/vcdom/minidom/node_list.rb +0 -41
- data/lib/vcdom/minidom/text.rb +0 -77
- data/lib/vcdom/minidom/xml_reg_exp.rb +0 -39
- data/lib/vcdom/minidom.rb +0 -9
- data/lib/vcdom.rb +0 -6
- data/script/console +0 -10
- data/script/destroy +0 -14
- data/script/generate +0 -14
- data/test/test_helper.rb +0 -3
- data/test/test_vcdom.rb +0 -11
data/lib/vcdom/attr.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# coding : utf-8
|
2
|
+
|
3
|
+
require "vcdom/node"
|
4
|
+
require "vcdom/parent"
|
5
|
+
|
6
|
+
module VCDOM
|
7
|
+
class Attr < Node
|
8
|
+
|
9
|
+
include Parent
|
10
|
+
|
11
|
+
def initialize( doc, name )
|
12
|
+
initialize_parent()
|
13
|
+
super( doc )
|
14
|
+
@owner_element = nil
|
15
|
+
@local_name = name
|
16
|
+
end
|
17
|
+
|
18
|
+
def node_type
|
19
|
+
ATTRIBUTE_NODE
|
20
|
+
end
|
21
|
+
|
22
|
+
def owner_element
|
23
|
+
@owner_element
|
24
|
+
end
|
25
|
+
def _set_owner_element( elem )
|
26
|
+
@owner_element = elem
|
27
|
+
end
|
28
|
+
|
29
|
+
def name
|
30
|
+
@local_name.to_s()
|
31
|
+
end
|
32
|
+
alias :node_name :name
|
33
|
+
|
34
|
+
def local_name
|
35
|
+
nil
|
36
|
+
end
|
37
|
+
|
38
|
+
def value
|
39
|
+
val = String.new()
|
40
|
+
self.each_child_node do |n|
|
41
|
+
# Text のみを考慮
|
42
|
+
val << n.node_value
|
43
|
+
end
|
44
|
+
return val
|
45
|
+
end
|
46
|
+
def value=(val)
|
47
|
+
while self.first_child do
|
48
|
+
self.remove_child( self.first_child )
|
49
|
+
end
|
50
|
+
self.append_child( self.owner_document.create_text_node( val ) )
|
51
|
+
end
|
52
|
+
|
53
|
+
def append_child( new_child )
|
54
|
+
# ノードのタイプチェックなど
|
55
|
+
if not new_child.is_a? Node then
|
56
|
+
raise ArgumentError.new( "the argument [#{new_child.inspect}] is not an object of the expected class." )
|
57
|
+
end
|
58
|
+
# Text, EntityReference
|
59
|
+
case new_child.node_type
|
60
|
+
when TEXT_NODE, ENTITY_REFERENCE_NODE then
|
61
|
+
# OK
|
62
|
+
else
|
63
|
+
# ERROR
|
64
|
+
raise "ERROR"
|
65
|
+
end
|
66
|
+
_append_child( new_child )
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding : utf-8
|
2
|
+
|
3
|
+
require "vcdom/node"
|
4
|
+
|
5
|
+
module VCDOM
|
6
|
+
class AttrNodeMap #< NamedNodeMap
|
7
|
+
|
8
|
+
include Enumerable
|
9
|
+
|
10
|
+
def initialize( nodes )
|
11
|
+
@nodes = nodes
|
12
|
+
end
|
13
|
+
def item( index )
|
14
|
+
@nodes[index]
|
15
|
+
end
|
16
|
+
def length
|
17
|
+
@nodes.length
|
18
|
+
end
|
19
|
+
def each
|
20
|
+
@nodes.each do |n|
|
21
|
+
yield n
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def inspect
|
26
|
+
"#<VCXML::DOM::AttrNodeMap>"
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# coding : utf-8
|
2
|
+
|
3
|
+
require "vcdom/node"
|
4
|
+
require "vcdom/attr"
|
5
|
+
|
6
|
+
module VCDOM
|
7
|
+
class AttrNS < Attr
|
8
|
+
|
9
|
+
def initialize( doc, namespace_uri, prefix, local_name )
|
10
|
+
super( doc, local_name )
|
11
|
+
@namespace_uri = namespace_uri
|
12
|
+
@prefix = prefix
|
13
|
+
end
|
14
|
+
|
15
|
+
def name
|
16
|
+
if @prefix then
|
17
|
+
"#{@prefix.to_s}:#{@local_name.to_s}"
|
18
|
+
else
|
19
|
+
@local_name.to_s()
|
20
|
+
end
|
21
|
+
end
|
22
|
+
alias :node_name :name
|
23
|
+
|
24
|
+
def prefix
|
25
|
+
@prefix.nil? ? nil : @prefix.to_s()
|
26
|
+
end
|
27
|
+
def prefix=(val)
|
28
|
+
@prefix = val.nil? ? nil : val.intern
|
29
|
+
end
|
30
|
+
def local_name
|
31
|
+
@local_name.to_s()
|
32
|
+
end
|
33
|
+
def namespace_uri
|
34
|
+
@namespace_uri.nil? ? nil : @namespace_uri.to_s()
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# coding : utf-8
|
2
|
+
|
3
|
+
require "vcdom/node"
|
4
|
+
|
5
|
+
module VCDOM
|
6
|
+
class CharacterData < Node
|
7
|
+
|
8
|
+
def initialize( doc, data )
|
9
|
+
super( doc )
|
10
|
+
@data = data
|
11
|
+
end
|
12
|
+
|
13
|
+
def data
|
14
|
+
@data.to_s
|
15
|
+
end
|
16
|
+
alias :node_value :data
|
17
|
+
def length
|
18
|
+
@data.to_s.length
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
data/lib/vcdom/child.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# coding : utf-8
|
2
|
+
|
3
|
+
require "vcdom/node_list"
|
4
|
+
|
5
|
+
module VCDOM
|
6
|
+
module Child
|
7
|
+
|
8
|
+
def initialize_child()
|
9
|
+
@parent_node = nil
|
10
|
+
@next_sibling = nil
|
11
|
+
@prev_sibling = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def parent_node
|
15
|
+
@parent_node
|
16
|
+
end
|
17
|
+
def _set_parent_node( parent_node )
|
18
|
+
@parent_node = parent_node
|
19
|
+
end
|
20
|
+
def _set_next_sibling( next_node )
|
21
|
+
next_node.previous_sibling = self
|
22
|
+
next_node.next_sibling = self.next_sibling
|
23
|
+
self.next_sibling.previous_sibling = next_node until self.next_sibling.nil?
|
24
|
+
self.next_sibling = next_node
|
25
|
+
end
|
26
|
+
def previous_sibling
|
27
|
+
@prev_sibling
|
28
|
+
end
|
29
|
+
def previous_sibling=(node)
|
30
|
+
@prev_sibling = node
|
31
|
+
end
|
32
|
+
protected :previous_sibling=
|
33
|
+
def next_sibling
|
34
|
+
@next_sibling
|
35
|
+
end
|
36
|
+
def next_sibling=(node)
|
37
|
+
@next_sibling = node
|
38
|
+
end
|
39
|
+
protected :next_sibling=
|
40
|
+
def _leave_from_tree()
|
41
|
+
@parent_node = nil
|
42
|
+
if @next_sibling then
|
43
|
+
@next_sibling.previous_sibling = @prev_sibling
|
44
|
+
@next_sibling = nil
|
45
|
+
end
|
46
|
+
if @prev_sibling then
|
47
|
+
@prev_sibling.next_sibling = @next_sibling
|
48
|
+
@prev_sibling = nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
# coding : utf-8
|
2
|
+
|
3
|
+
require "vcdom/node"
|
4
|
+
require "vcdom/parent"
|
5
|
+
require "vcdom/element"
|
6
|
+
require "vcdom/element_ns"
|
7
|
+
require "vcdom/attr"
|
8
|
+
require "vcdom/attr_ns"
|
9
|
+
require "vcdom/text"
|
10
|
+
|
11
|
+
module VCDOM
|
12
|
+
class Document < Node
|
13
|
+
|
14
|
+
include Parent
|
15
|
+
|
16
|
+
|
17
|
+
def initialize()
|
18
|
+
initialize_parent()
|
19
|
+
super( nil )
|
20
|
+
end
|
21
|
+
|
22
|
+
def node_type
|
23
|
+
DOCUMENT_NODE
|
24
|
+
end
|
25
|
+
|
26
|
+
def append_child( new_child )
|
27
|
+
# ノードのタイプチェックなど
|
28
|
+
if not new_child.is_a? Node then
|
29
|
+
raise ArgumentError.new( "the argument [#{new_child.inspect}] is not an object of the expected class." )
|
30
|
+
end
|
31
|
+
# Element (maximum of one), ProcessingInstruction, Comment, DocumentType (maximum of one)
|
32
|
+
case new_child.node_type
|
33
|
+
when ELEMENT_NODE then
|
34
|
+
# 既に追加されてるかどうかのチェック
|
35
|
+
if @document_element.nil? then
|
36
|
+
@document_element = new_child
|
37
|
+
else
|
38
|
+
raise "HIERARCHY_REQUEST_ERR"
|
39
|
+
end
|
40
|
+
when DOCUMENT_TYPE_NODE then
|
41
|
+
# 既に追加されてるかどうかのチェック
|
42
|
+
when PROCESSING_INSTRUCTION_NODE, COMMENT_NODE then
|
43
|
+
# OK
|
44
|
+
else
|
45
|
+
# ERROR
|
46
|
+
raise "ERROR"
|
47
|
+
end
|
48
|
+
_append_child( new_child )
|
49
|
+
end
|
50
|
+
|
51
|
+
def create_element( tag_name )
|
52
|
+
elem = nil
|
53
|
+
if tag_name.is_a? String then
|
54
|
+
elem = Element._new( self, tag_name.intern )
|
55
|
+
else
|
56
|
+
raise "ERROR"
|
57
|
+
end
|
58
|
+
elem
|
59
|
+
end
|
60
|
+
|
61
|
+
def create_element_ns( namespace_uri, qualified_name )
|
62
|
+
elem = nil
|
63
|
+
if namespace_uri.is_a? String then
|
64
|
+
namespace_uri = namespace_uri.intern
|
65
|
+
elsif not namespace_uri.nil? then
|
66
|
+
raise "ERROR"
|
67
|
+
end
|
68
|
+
if qualified_name.is_a? String then
|
69
|
+
name_parts = qualified_name.split /:/
|
70
|
+
if name_parts.length == 1 then
|
71
|
+
elem = ElementNS._new( self, namespace_uri, nil, name_parts[0].intern )
|
72
|
+
elsif name_parts.length == 2 then
|
73
|
+
elem = ElementNS._new( self, namespace_uri, name_parts[0].intern, name_parts[1].intern )
|
74
|
+
else
|
75
|
+
raise "ERROR"
|
76
|
+
end
|
77
|
+
else
|
78
|
+
raise "ERROR"
|
79
|
+
end
|
80
|
+
elem
|
81
|
+
end
|
82
|
+
|
83
|
+
def create_attribute( name )
|
84
|
+
attr = nil
|
85
|
+
if name.is_a? String then
|
86
|
+
attr = Attr._new( self, name.intern )
|
87
|
+
else
|
88
|
+
raise ArgumentError.new( "the argument [#{new_child.inspect}] is not an object of the expected class." )
|
89
|
+
end
|
90
|
+
attr
|
91
|
+
end
|
92
|
+
|
93
|
+
def create_attribute_ns( namespace_uri, qualified_name )
|
94
|
+
attr = nil
|
95
|
+
if namespace_uri.is_a? String then
|
96
|
+
namespace_uri = namespace_uri.intern
|
97
|
+
elsif not namespace_uri.nil? then
|
98
|
+
raise ArgumentError.new( "the argument *namespace_uri* must be a String object or nil." )
|
99
|
+
end
|
100
|
+
if qualified_name.is_a? String then
|
101
|
+
name_parts = qualified_name.split /:/
|
102
|
+
if name_parts.length == 1 then
|
103
|
+
attr = AttrNS._new( self, namespace_uri, nil, name_parts[0].intern )
|
104
|
+
elsif name_parts.length == 2 then
|
105
|
+
attr = AttrNS._new( self, namespace_uri, name_parts[0].intern, name_parts[1].intern )
|
106
|
+
else
|
107
|
+
raise "ERROR"
|
108
|
+
end
|
109
|
+
else
|
110
|
+
raise "ERROR"
|
111
|
+
end
|
112
|
+
attr
|
113
|
+
end
|
114
|
+
|
115
|
+
def create_text_node( data )
|
116
|
+
node = nil
|
117
|
+
if data.is_a? String then
|
118
|
+
node = Text._new( self, data.intern )
|
119
|
+
else
|
120
|
+
raise ArgumentError.new( "the argument [#{data.inspect}] is not an object of the expected class. the class : #{data.class}" )
|
121
|
+
end
|
122
|
+
node
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,332 @@
|
|
1
|
+
# coding : utf-8
|
2
|
+
|
3
|
+
require "vcdom/node"
|
4
|
+
require "vcdom/parent"
|
5
|
+
require "vcdom/child"
|
6
|
+
require "vcdom/attr_node_map"
|
7
|
+
|
8
|
+
module VCDOM
|
9
|
+
class Element < Node
|
10
|
+
|
11
|
+
include Parent
|
12
|
+
include Child
|
13
|
+
|
14
|
+
def initialize( doc, tag_name )
|
15
|
+
initialize_parent()
|
16
|
+
super( doc )
|
17
|
+
@local_name = tag_name
|
18
|
+
# attributes
|
19
|
+
@attr_nodes = Array.new()
|
20
|
+
@attr_node_map = AttrNodeMap.new( @attr_nodes )
|
21
|
+
end
|
22
|
+
|
23
|
+
def node_type
|
24
|
+
ELEMENT_NODE
|
25
|
+
end
|
26
|
+
|
27
|
+
def tag_name
|
28
|
+
@local_name.to_s()
|
29
|
+
end
|
30
|
+
alias :node_name :tag_name
|
31
|
+
|
32
|
+
def local_name
|
33
|
+
nil
|
34
|
+
end
|
35
|
+
|
36
|
+
def append_child( new_child )
|
37
|
+
# ノードのタイプチェックなど
|
38
|
+
if not new_child.is_a? Node then
|
39
|
+
raise ArgumentError.new( "the argument [#{new_child.inspect}] is not an object of the expected class." )
|
40
|
+
end
|
41
|
+
# Element, Text, Comment, ProcessingInstruction, CDATASection, EntityReference
|
42
|
+
case new_child.node_type
|
43
|
+
when ELEMENT_NODE, TEXT_NODE, CDATA_SECTION_NODE, ENTITY_REFERENCE_NODE, PROCESSING_INSTRUCTION_NODE, COMMENT_NODE then
|
44
|
+
# OK
|
45
|
+
else
|
46
|
+
# ERROR
|
47
|
+
raise "ERROR"
|
48
|
+
end
|
49
|
+
_append_child( new_child )
|
50
|
+
end
|
51
|
+
|
52
|
+
# attributes
|
53
|
+
def attributes
|
54
|
+
@attr_node_map
|
55
|
+
end
|
56
|
+
def each_attr_node
|
57
|
+
@attr_nodes.each do |n|
|
58
|
+
yield n
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# setAttributeNode
|
63
|
+
# Adds a new attribute node. If an attribute with that name (nodeName) is already present in the element,
|
64
|
+
# it is replaced by the new one. Replacing an attribute node by itself has no effect.
|
65
|
+
# To add a new attribute node with a qualified name and namespace URI, use the setAttributeNodeNS method.
|
66
|
+
# @param new_attr The Attr node to add to the attribute list.
|
67
|
+
# @return If the newAttr attribute replaces an existing attribute, the replaced Attr node is returned,
|
68
|
+
# otherwise null is returned.
|
69
|
+
def set_attribute_node( new_attr )
|
70
|
+
if new_attr.owner_document != self.owner_document then
|
71
|
+
raise "WRONG_DOCUMENT_ERR"
|
72
|
+
end
|
73
|
+
if not new_attr.owner_element.nil? then
|
74
|
+
raise "INUSE_ATTRIBUTE_ERR"
|
75
|
+
end
|
76
|
+
old_attr = nil
|
77
|
+
@attr_nodes << new_attr
|
78
|
+
new_attr._set_owner_element( self )
|
79
|
+
old_attr
|
80
|
+
end
|
81
|
+
def set_attribute( name, value )
|
82
|
+
attr = self.owner_document.create_attribute( name )
|
83
|
+
attr.append_child( self.owner_document.create_text_node( value ) )
|
84
|
+
self.set_attribute_node( attr )
|
85
|
+
nil
|
86
|
+
end
|
87
|
+
|
88
|
+
# setAttributeNodeNS introduced in DOM Level 2
|
89
|
+
# Adds a new attribute. If an attribute with that local name and that namespace URI is already present in the element, it is replaced by the new one. Replacing an attribute node by itself has no effect.
|
90
|
+
# Per [XML Namespaces], applications must use the value null as the namespaceURI parameter for methods if they wish to have no namespace.
|
91
|
+
# @param new_attr The Attr node to add to the attribute list.
|
92
|
+
# @return If the newAttr attribute replaces an existing attribute with the same local name and namespace URI, the replaced Attr node is returned, otherwise null is returned.
|
93
|
+
def set_attribute_node_ns( new_attr )
|
94
|
+
if new_attr.owner_document != self.owner_document then
|
95
|
+
raise "WRONG_DOCUMENT_ERR"
|
96
|
+
end
|
97
|
+
if not new_attr.owner_element.nil? then
|
98
|
+
raise "INUSE_ATTRIBUTE_ERR"
|
99
|
+
end
|
100
|
+
old_attr = nil
|
101
|
+
@attr_nodes << new_attr
|
102
|
+
new_attr._set_owner_element( self )
|
103
|
+
old_attr
|
104
|
+
end
|
105
|
+
def set_attribute_ns( namespace_uri, qualified_name, value )
|
106
|
+
attr = self.owner_document.create_attribute_ns( namespace_uri, qualified_name )
|
107
|
+
attr.append_child( self.owner_document.create_text_node( value ) )
|
108
|
+
self.set_attribute_node_ns( attr )
|
109
|
+
nil
|
110
|
+
end
|
111
|
+
def get_attribute_ns( namespace_uri, local_name )
|
112
|
+
@attr_nodes.each do |attr|
|
113
|
+
if attr.namespace_uri == namespace_uri and attr.local_name == local_name then
|
114
|
+
#//////////////////////////
|
115
|
+
# 変更する
|
116
|
+
#//////////////////////////
|
117
|
+
return attr.value
|
118
|
+
end
|
119
|
+
end
|
120
|
+
return ""
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
|
125
|
+
|
126
|
+
|
127
|
+
# 1. 要素が ns uri を持ってるかどうか確認
|
128
|
+
# 1-1. ns uri を持つ : prefix/uri ペア (prefix が nil もあり) の宣言がスコープ内にあるかどうか調べる
|
129
|
+
# 1-1-1. スコープ内にない : 要素の prefix の ns 宣言をする (nil の場合はデフォルト ns 宣言) 既に同じ prefix の宣言があるなら上書きする
|
130
|
+
# 1-2. ns uri を持たない : 要素が localName を持つかどうか確認
|
131
|
+
# 1-2-1 localName を持たない : 不明
|
132
|
+
# 1-2-2 localName を持つ : デフォルト ns 宣言が nil じゃないなら, この要素に nil のデフォルト ns 宣言を付ける
|
133
|
+
# prefix があって ns uri が nil というのは許されない!!!!
|
134
|
+
# 2. ns 宣言以外の属性を 1 個取り出し attr とする
|
135
|
+
# 3. attr が nil でないなら 4 へ
|
136
|
+
# 4. attr が ns を持っているか
|
137
|
+
# 4-1. ns あり : prefix がないか, prefix が宣言されてないか, prefix が既に別の ns に結び付けられている
|
138
|
+
# 4-1-1. prefix がダメ : ns に結び付けられている prefix が既にあるかどうか
|
139
|
+
# 4-1-1-1. ある : prefix をそれに変える
|
140
|
+
# 4-1-1-2. ない : prefix が nil でなく, まだスコープ内で宣言されていないか
|
141
|
+
# 4-1-1-2-1. 宣言されてない : 宣言する
|
142
|
+
# 4-1-1-2-2. prefix が nil または宣言されている : NS+index という prefix (まだ宣言されていないもの) に変え, 宣言する
|
143
|
+
# 4-2. ns なし : localName を持っているかどうか
|
144
|
+
# 4-2-1. localName なし : 不明
|
145
|
+
# 4-2-2. localName あり : 何もしない
|
146
|
+
|
147
|
+
#void Element.normalizeNamespaces()
|
148
|
+
def normalize_namespaces()
|
149
|
+
# non-namespace Attrs of Element
|
150
|
+
non_ns_attrs = Array.new()
|
151
|
+
# Pick up local namespace declarations
|
152
|
+
# for ( all DOM Level 2 valid local namespace declaration attributes of Element ) {
|
153
|
+
# if (the namespace declaration is invalid) {
|
154
|
+
# Note: The prefix xmlns is used only to declare namespace bindings and
|
155
|
+
# is by definition bound to the namespace name http://www.w3.org/2000/xmlns/.
|
156
|
+
# It must not be declared. No other prefix may be bound to this namespace name.
|
157
|
+
# ==> Report an error.
|
158
|
+
# } else {
|
159
|
+
# ==> Record the namespace declaration
|
160
|
+
# }
|
161
|
+
# }
|
162
|
+
#ns = Hash.new()
|
163
|
+
@attr_nodes.each do |n|
|
164
|
+
if n.name == "xmlns" then
|
165
|
+
# ns[nil] = n[0].data
|
166
|
+
elsif n.prefix == "xmlns" then
|
167
|
+
# ns[n.local_name.intern] = n[0].data
|
168
|
+
else
|
169
|
+
non_ns_attrs << n
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
# Fixup element's namespace
|
174
|
+
if self.namespace_uri then
|
175
|
+
# when Element's namespaceURI is not nil
|
176
|
+
# prefix / ns ペアが既にスコープ内に存在するかどうかの確認
|
177
|
+
# この flag チェックは変更しないとダメかも...
|
178
|
+
flag = false
|
179
|
+
if self.prefix.nil? then
|
180
|
+
#///////////////////////////////////
|
181
|
+
# is_default_namespace だとダメー
|
182
|
+
#///////////////////////////////////
|
183
|
+
#if self.is_default_namespace( self.namespace_uri ) then
|
184
|
+
# flag = true
|
185
|
+
#end
|
186
|
+
n = self
|
187
|
+
loop do
|
188
|
+
if n.nil? then
|
189
|
+
break
|
190
|
+
elsif n.node_type == ELEMENT_NODE then
|
191
|
+
if n.get_attribute_ns( "http://www.w3.org/2000/xmlns/", "xmlns" ) == self.namespace_uri then
|
192
|
+
flag = true
|
193
|
+
break
|
194
|
+
end
|
195
|
+
end
|
196
|
+
n = n.parent_node
|
197
|
+
end
|
198
|
+
else
|
199
|
+
#///////////////////////////////////
|
200
|
+
# lookup_namespace_uri だとダメー
|
201
|
+
#///////////////////////////////////
|
202
|
+
#if self.lookup_namespace_uri( self.prefix ) == self.namespace_uri then
|
203
|
+
# flag = true
|
204
|
+
#end
|
205
|
+
if self.prefix == "xml" then
|
206
|
+
# ok?
|
207
|
+
flag = true
|
208
|
+
else
|
209
|
+
n = self
|
210
|
+
loop do
|
211
|
+
if n.nil? then
|
212
|
+
break
|
213
|
+
elsif n.node_type == ELEMENT_NODE then
|
214
|
+
if n.get_attribute_ns( "http://www.w3.org/2000/xmlns/", self.prefix ) == self.namespace_uri then
|
215
|
+
flag = true
|
216
|
+
break
|
217
|
+
end
|
218
|
+
end
|
219
|
+
n = n.parent_node
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
if flag then
|
224
|
+
# when Element's prefix/namespace pair (or default namespace, if no prefix) are within the scope of a binding
|
225
|
+
# ==> do nothing, declaration in scope is inherited
|
226
|
+
# See section "B.1.1: Scope of a binding" for an example
|
227
|
+
else
|
228
|
+
# ==> Create a local namespace declaration attr for this namespace,
|
229
|
+
# with Element's current prefix (or a default namespace, if
|
230
|
+
# no prefix). If there's a conflicting local declaration
|
231
|
+
# already present, change its value to use this namespace.
|
232
|
+
# See section "B.1.2: Conflicting namespace declaration" for an example
|
233
|
+
# // NOTE that this may break other nodes within this Element's
|
234
|
+
# // subtree, if they're already using this prefix.
|
235
|
+
# // They will be repaired when we reach them.
|
236
|
+
if self.prefix.nil? then
|
237
|
+
self.set_attribute_ns( "http://www.w3.org/2000/xmlns/", "xmlns", self.namespace_uri )
|
238
|
+
else
|
239
|
+
self.set_attribute_ns( "http://www.w3.org/2000/xmlns/", "xmlns:#{self.prefix}", self.namespace_uri )
|
240
|
+
end
|
241
|
+
end
|
242
|
+
else
|
243
|
+
# when Element has no namespace URI:
|
244
|
+
if self.local_name.nil? then
|
245
|
+
# when Element's localName is null
|
246
|
+
# // DOM Level 1 node
|
247
|
+
# ==> if in process of validation against a namespace aware schema
|
248
|
+
# (i.e XML Schema) report a fatal error: the processor can not recover
|
249
|
+
# in this situation.
|
250
|
+
# Otherwise, report an error: no namespace fixup will be performed on this node.
|
251
|
+
else
|
252
|
+
# when Element has no pseudo-prefix
|
253
|
+
if self.prefix.nil? and not self.is_default_namespace( nil ) then
|
254
|
+
# when there's a conflicting local default namespace declaration already present
|
255
|
+
# ==> change its value to use this empty namespace.
|
256
|
+
self.set_attribute_ns( "http://www.w3.org/2000/xmlns/", "xmlns", "" )
|
257
|
+
elsif self.prefix and self.lookup_prefix( nil ) == self.prefix then
|
258
|
+
self.set_attribute_ns( "http://www.w3.org/2000/xmlns/", "xmlns:#{self.prefix}", "" )
|
259
|
+
end
|
260
|
+
# // NOTE that this may break other nodes within this Element's
|
261
|
+
# // subtree, if they're already using the default namespaces.
|
262
|
+
# // They will be repaired when we reach them.
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
# Examine and polish the attributes
|
267
|
+
#for ( all non-namespace Attrs of Element )
|
268
|
+
non_ns_attrs.each do |attr|
|
269
|
+
if attr.namespace_uri then
|
270
|
+
if attr.prefix == "xml" then
|
271
|
+
# do nothing
|
272
|
+
# when attr has a namespace URI
|
273
|
+
elsif attr.prefix.nil? or self.lookup_namespace_uri( attr.prefix ) != attr.namespace_uri then
|
274
|
+
# when attribute has no prefix (default namespace decl does not apply to attributes)
|
275
|
+
# OR attribute prefix is not declared OR conflict: attribute has a prefix that conflicts with a binding
|
276
|
+
# already active in scope)
|
277
|
+
if not (new_prefix = self.lookup_prefix( attr.namespace_uri )).nil? then
|
278
|
+
# when (namespaceURI matches an in scope declaration of one or more prefixes)
|
279
|
+
# pick the most local binding available;
|
280
|
+
# if there is more than one pick one arbitrarily
|
281
|
+
# ==> change attribute's prefix.
|
282
|
+
attr.prefix = new_prefix
|
283
|
+
else
|
284
|
+
if not attr.prefix.nil? and self.lookup_namespace_uri( attr.prefix ).nil? then
|
285
|
+
# when the current prefix is not null and it has no in scope declaration
|
286
|
+
# ==> declare this prefix
|
287
|
+
self.set_attribute_ns( "http://www.w3.org/2000/xmlns/", "xmlns:#{attr.prefix}", attr.namespace_uri )
|
288
|
+
else
|
289
|
+
# find a prefix following the pattern "NS" +index (starting at 1)
|
290
|
+
# make sure this prefix is not declared in the current scope.
|
291
|
+
# create a local namespace declaration attribute
|
292
|
+
#==> change attribute's prefix.
|
293
|
+
i = 0
|
294
|
+
loop do
|
295
|
+
i += 1
|
296
|
+
if self.lookup_namespace_uri( "NS#{i}" ).nil? then
|
297
|
+
self.set_attribute_ns( "http://www.w3.org/2000/xmlns/", "xmlns:NS#{i}", attr.namespace_uri )
|
298
|
+
break
|
299
|
+
end
|
300
|
+
end
|
301
|
+
attr.prefix = "NS#{i}"
|
302
|
+
end
|
303
|
+
end
|
304
|
+
end
|
305
|
+
else
|
306
|
+
# attr has no namespace URI
|
307
|
+
if attr.local_name.nil? then
|
308
|
+
# when attr has no localName
|
309
|
+
# = DOM Level 1 node
|
310
|
+
#==> if in process of validation against a namespace aware schema
|
311
|
+
# (i.e XML Schema) report a fatal error: the processor can not recover
|
312
|
+
# in this situation.
|
313
|
+
# Otherwise, report an error: no namespace fixup will be performed on this node.
|
314
|
+
else
|
315
|
+
# attr has no namespace URI and no prefix
|
316
|
+
# no action is required, since attrs don't use default
|
317
|
+
# ==> do nothing
|
318
|
+
end
|
319
|
+
end
|
320
|
+
end # end for-all-Attrs
|
321
|
+
|
322
|
+
# do this recursively
|
323
|
+
#for ( all child elements of Element )
|
324
|
+
self.each_child_node do |c|
|
325
|
+
if c.node_type == ELEMENT_NODE then
|
326
|
+
c.normalize_namespaces()
|
327
|
+
end
|
328
|
+
end # end Element.normalizeNamespaces
|
329
|
+
end
|
330
|
+
|
331
|
+
end
|
332
|
+
end
|