Module: Rsxml::Namespace
- Defined in:
- lib/rsxml/namespace.rb
Class Method Summary collapse
-
.compact_attr_qnames(ns_stack, attrs) ⇒ Object
compact all attribute QNames to Strings.
-
.compact_qname(ns_stack, name) ⇒ Object
produce a QName String from a [LocalPart, prefix, URI] triple.
-
.explode_attr_qnames(ns_stack, attrs) ⇒ Object
explode attribute QNames to [LocalPart, prefix, URI] triples,.
-
.explode_qname(ns_stack, qname, attr = false) ⇒ Object
split a QName into [LocalPart, prefix, URI] triple.
-
.exploded_namespace_declarations(ns) ⇒ Object
produce a Hash of namespace declaration attributes with exploded QNames, from a Hash of namespace prefix bindings.
-
.extract_declared_namespace_bindings(attrs) ⇒ Object
extract a Hash of prefix=>uri mappings declared in attributes.
-
.extract_explicit_namespace_bindings(tag, attrs) ⇒ Object
extract a Hash of prefix=>uri mappings from exploded QName tag and attrs.
-
.find_namespace_uri(ns_stack, prefix, uri_check = nil) ⇒ Object
returns the namespace uri for a prefix, if declared in the stack.
-
.merge_namespace_bindings(ns1, ns2) ⇒ Object
merges two sets of namespace bindings, raising error on clash.
-
.namespace_bindings_declarations(ns_stack, tag, attrs) ⇒ Object
given the existing
ns_stack
of ns bindings, atag
and it’sattributes
, return a pair[ns_bindings, ns_additional_decls]
containing ns bindings for the stack, and additional required (exploded) namespace declarations to be added to the attributes. -
.split_qname(qname) ⇒ Object
split a qname String into a [local_part, prefix] pair.
-
.undeclared_namespace_bindings(ns_stack, ns_explicit) ⇒ Object
figure out which explicit namespaces need declaring.
Class Method Details
.compact_attr_qnames(ns_stack, attrs) ⇒ Object
compact all attribute QNames to Strings
6 7 8 9 10 |
# File 'lib/rsxml/namespace.rb', line 6 def compact_attr_qnames(ns_stack, attrs) Hash[attrs.map do |name,value| [compact_qname(ns_stack, name), value] end] end |
.compact_qname(ns_stack, name) ⇒ Object
produce a QName String from a [LocalPart, prefix, URI] triple
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/rsxml/namespace.rb', line 26 def compact_qname(ns_stack, name) return name if name.is_a?(String) local_part, prefix, uri = name raise "invalid name: #{name}" if !prefix && uri if prefix if prefix!="xmlns" ns = find_namespace_uri(ns_stack, prefix, uri) raise "namespace prefix not bound to a namespace: '#{prefix}'" if ! ns end [prefix, local_part].map{|s| s.to_s unless s.to_s.empty?}.compact.join(':') else local_part end end |
.explode_attr_qnames(ns_stack, attrs) ⇒ Object
explode attribute QNames to [LocalPart, prefix, URI] triples,
13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/rsxml/namespace.rb', line 13 def explode_attr_qnames(ns_stack, attrs) Hash[attrs.map do |name, value| uq_name = explode_qname(ns_stack, name, true) local_name, prefix, uri = uq_name if !prefix || prefix=="" [local_name, value] else [uq_name, value] end end] end |
.explode_qname(ns_stack, qname, attr = false) ⇒ Object
split a QName into [LocalPart, prefix, URI] triple
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/rsxml/namespace.rb', line 43 def explode_qname(ns_stack, qname, attr=false) if qname.is_a?(Array) if qname.length>1 && !qname[1].nil? return qname elsif qname.length>1 && qname[1].nil? && !qname[2].nil? raise "invalid name: #{qname.inspect}" else return qname[0] end end local_part, prefix = split_qname(qname) if prefix if prefix=="xmlns" && attr [local_part, prefix] else uri = find_namespace_uri(ns_stack, prefix) raise "namespace prefix not bound: '#{prefix}'" if ! uri [local_part, prefix, uri] end else if attr local_part else default_uri = find_namespace_uri(ns_stack, "") if default_uri [local_part, "", default_uri] else local_part end end end end |
.exploded_namespace_declarations(ns) ⇒ Object
produce a Hash of namespace declaration attributes with exploded QNames, from a Hash of namespace prefix bindings
138 139 140 141 142 143 144 145 146 |
# File 'lib/rsxml/namespace.rb', line 138 def exploded_namespace_declarations(ns) Hash[ns.map do |prefix, uri| if prefix=="" ["xmlns", uri] else [[prefix, "xmlns"], uri] end end] end |
.extract_declared_namespace_bindings(attrs) ⇒ Object
extract a Hash of prefix=>uri mappings declared in attributes
98 99 100 101 102 103 104 105 106 107 |
# File 'lib/rsxml/namespace.rb', line 98 def extract_declared_namespace_bindings(attrs) Hash[attrs.map do |name,value| local_part, prefix, uri = split_qname(name) if (prefix && prefix == "xmlns") [local_part, value] elsif (!prefix && local_part == "xmlns") ["", value] end end.compact] end |
.extract_explicit_namespace_bindings(tag, attrs) ⇒ Object
extract a Hash of prefix=>uri mappings from exploded QName tag and attrs
110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/rsxml/namespace.rb', line 110 def extract_explicit_namespace_bindings(tag, attrs) tag_local_part, tag_prefix, tag_uri = tag ns = {} ns[tag_prefix] = tag_uri if tag_prefix && tag_uri attrs.each do |name, value| attr_local_part, attr_prefix, attr_uri = name if attr_prefix && attr_uri raise "bindings clash: '#{attr_prefix}'=>'#{ns[attr_prefix]}' , '#{attr_prefix}'=>'#{attr_uri}'" if ns.has_key?(attr_prefix) && ns[attr_prefix]!=attr_uri ns[attr_prefix] = attr_uri end end ns end |
.find_namespace_uri(ns_stack, prefix, uri_check = nil) ⇒ Object
returns the namespace uri for a prefix, if declared in the stack
89 90 91 92 93 94 |
# File 'lib/rsxml/namespace.rb', line 89 def find_namespace_uri(ns_stack, prefix, uri_check=nil) tns = ns_stack.reverse.find{|ns| ns.has_key?(prefix)} uri = tns[prefix] if tns raise "prefix: '#{prefix}' is bound to uri: '#{uri}', but should be '#{uri_check}'" if uri_check && uri && uri!=uri_check uri end |
.merge_namespace_bindings(ns1, ns2) ⇒ Object
merges two sets of namespace bindings, raising error on clash
149 150 151 152 153 154 155 156 |
# File 'lib/rsxml/namespace.rb', line 149 def merge_namespace_bindings(ns1, ns2) m = ns1.clone ns2.each do |k,v| raise "bindings clash: '#{k}'=>'#{m[k]}' , '#{k}'=>'#{v}'" if m.has_key?(k) && m[k]!=v m[k]=v end m end |
.namespace_bindings_declarations(ns_stack, tag, attrs) ⇒ Object
given the existing ns_stack
of ns bindings, a tag
and it’s attributes
, return a pair [ns_bindings, ns_additional_decls]
containing ns bindings for the stack, and additional required (exploded) namespace declarations to be added to the attributes
162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/rsxml/namespace.rb', line 162 def namespace_bindings_declarations(ns_stack, tag, attrs) ns_declared = extract_declared_namespace_bindings(attrs) ns_explicit = extract_explicit_namespace_bindings(tag, attrs) ns_undeclared = undeclared_namespace_bindings(ns_stack + [ns_declared], ns_explicit) ns_bindings = merge_namespace_bindings(ns_declared, ns_undeclared) # and declarations for undeclared namespaces ns_additional_decls = exploded_namespace_declarations(ns_undeclared) [ns_bindings, ns_additional_decls] end |
.split_qname(qname) ⇒ Object
split a qname String into a [local_part, prefix] pair
78 79 80 81 82 83 84 85 86 |
# File 'lib/rsxml/namespace.rb', line 78 def split_qname(qname) return qname if qname.is_a?(Array) if qname =~ /^[^:]+:[^:]+$/ [*qname.split(':')].reverse else qname end end |
.undeclared_namespace_bindings(ns_stack, ns_explicit) ⇒ Object
figure out which explicit namespaces need declaring
ns_stack
is the stack of namespace bindings ns_explicit
is the explicit refs for a tag
129 130 131 132 133 |
# File 'lib/rsxml/namespace.rb', line 129 def undeclared_namespace_bindings(ns_stack, ns_explicit) Hash[ns_explicit.map do |prefix,uri| [prefix, uri] if !find_namespace_uri(ns_stack, prefix, uri) end.compact] end |