Class: OM::XML::Term

Inherits:
Object
  • Object
show all
Includes:
TreeNode
Defined in:
lib/om/xml/term.rb

Overview

Special options: data_type, index_as, attributes, is_root_term, required

Defined Under Namespace

Classes: Builder

Instance Attribute Summary collapse

Attributes included from TreeNode

#ancestors

Class Method Summary collapse

Instance Method Summary collapse

Methods included from TreeNode

#add_child, #parent, #retrieve_child, #set_parent

Constructor Details

#initialize(name, opts = {}, terminology = nil) ⇒ Term

h2. Namespaces By default, OM assumes you have no namespace defined unless it is explicitly defined at the root of your document. If you want to specify which namespace a term is using, use:

namspace_prefix => "bar"

This value defaults to nil, in which case if a default namespace is set in the termnology, that namespace will be used.



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/om/xml/term.rb', line 173

def initialize(name, opts={}, terminology=nil)
  opts = {:ancestors=>[], :children=>{}}.merge(opts)
  [:children, :ancestors,:path, :index_as, :required, :type, :variant_of, :path, :attributes, :default_content_path, :namespace_prefix].each do |accessor_name|
    instance_variable_set("@#{accessor_name}", opts.fetch(accessor_name, nil) )
  end
  unless terminology.nil?
    if opts[:namespace_prefix].nil?
      unless terminology.namespaces["xmlns"].nil?
        @namespace_prefix = "oxns"
      end
    end
  end
  @name = name
  if @path.nil? || @path.empty?
    @path = name.to_s
  end
end

Instance Attribute Details

#attributesObject

Any XML attributes that qualify the Term.

Examples:

Declare a Term that has a given attribute (ie. //title)

t.english_title(:path=>"title", :attributes=>{"xml:lang"=>"eng"}

Use nil to point to nodes that do not have a given attribute (ie. //title)

t.title_without_lang_attribute(:path=>"title", :attributes=>{"xml:lang"=>nil})


144
145
146
# File 'lib/om/xml/term.rb', line 144

def attributes
  @attributes
end

#childrenObject

Returns the value of attribute children.



136
137
138
# File 'lib/om/xml/term.rb', line 136

def children
  @children
end

#data_typeObject

Returns the value of attribute data_type.



135
136
137
# File 'lib/om/xml/term.rb', line 135

def data_type
  @data_type
end

#default_content_pathObject

Returns the value of attribute default_content_path.



135
136
137
# File 'lib/om/xml/term.rb', line 135

def default_content_path
  @default_content_path
end

#index_asObject

Returns the value of attribute index_as.



135
136
137
# File 'lib/om/xml/term.rb', line 135

def index_as
  @index_as
end

#internal_xmlObject

Returns the value of attribute internal_xml.



136
137
138
# File 'lib/om/xml/term.rb', line 136

def internal_xml
  @internal_xml
end

#is_root_termObject

Returns the value of attribute is_root_term.



135
136
137
# File 'lib/om/xml/term.rb', line 135

def is_root_term
  @is_root_term
end

#nameObject

Returns the value of attribute name.



135
136
137
# File 'lib/om/xml/term.rb', line 135

def name
  @name
end

#namespace_prefixObject

Namespace Prefix (xmlns) for the Term.

By default, OM assumes that all terms in a Terminology have the namespace set in the root of the document. If you want to set a different namespace for a Term, pass :namespace_prefix into its initializer (or call .namespace_prefix= on its builder) If a node has no namespace, you must explicitly set namespace_prefix to nil. Currently you have to do this on each term, you can’t set namespace_prefix to nil for an entire Terminology.

Examples:

# For xml like this
<foo xmlns="http://foo.com/schemas/fooschema" xmlns:bar="http://bar.com/schemas/barschema">
  <address>1400 Pennsylvania Avenue</address>
  <bar:latitude>56</bar:latitude>
</foo>

# The Terminology would look like this
OM::XML::Terminology::Builder.new do |t|
  t.root(:name=>:foo, :path=>"foo", :xmlns=>"http://foo.com/schemas/fooschema", "xmlns:bar"=>"http://bar.com/schemas/barschema")
  t.address
  t.latitude(:namespace_prefix=>"bar")
end


165
166
167
# File 'lib/om/xml/term.rb', line 165

def namespace_prefix
  @namespace_prefix
end

#pathObject

Returns the value of attribute path.



135
136
137
# File 'lib/om/xml/term.rb', line 135

def path
  @path
end

#requiredObject

Returns the value of attribute required.



135
136
137
# File 'lib/om/xml/term.rb', line 135

def required
  @required
end

#terminologyObject

Returns the value of attribute terminology.



136
137
138
# File 'lib/om/xml/term.rb', line 136

def terminology
  @terminology
end

#variant_ofObject

Returns the value of attribute variant_of.



135
136
137
# File 'lib/om/xml/term.rb', line 135

def variant_of
  @variant_of
end

#xpathObject

Returns the value of attribute xpath.



135
136
137
# File 'lib/om/xml/term.rb', line 135

def xpath
  @xpath
end

#xpath_constrainedObject

Returns the value of attribute xpath_constrained.



135
136
137
# File 'lib/om/xml/term.rb', line 135

def xpath_constrained
  @xpath_constrained
end

#xpath_relativeObject

Returns the value of attribute xpath_relative.



135
136
137
# File 'lib/om/xml/term.rb', line 135

def xpath_relative
  @xpath_relative
end

Class Method Details

.from_node(mapper_xml) ⇒ Object



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/om/xml/term.rb', line 191

def self.from_node(mapper_xml)
  name = mapper_xml.attribute("name").text.to_sym
  attributes = {}
  mapper_xml.xpath("./attribute").each do |a|
    attributes[a.attribute("name").text.to_sym] = a.attribute("value").text
  end
  new_mapper = self.new(name, :attributes=>attributes)
  [:index_as, :required, :type, :variant_of, :path, :default_content_path, :namespace_prefix].each do |accessor_name|
    attribute =  mapper_xml.attribute(accessor_name.to_s)
    unless attribute.nil?
      new_mapper.instance_variable_set("@#{accessor_name}", attribute.text )
    end
  end
  new_mapper.internal_xml = mapper_xml

  mapper_xml.xpath("./mapper").each do |child_node|
    child = self.from_node(child_node)
    new_mapper.add_child(child)
  end

  return new_mapper
end

Instance Method Details

#generate_xpath_queries!Object

Generates absolute, relative, and constrained xpaths for the term, setting xpath, xpath_relative, and xpath_constrained accordingly. Also triggers update_xpath_values! on all child nodes, as their absolute paths rely on those of their parent nodes.



275
276
277
278
279
280
281
# File 'lib/om/xml/term.rb', line 275

def generate_xpath_queries!
  self.xpath = OM::XML::TermXpathGenerator.generate_absolute_xpath(self)
  self.xpath_constrained = OM::XML::TermXpathGenerator.generate_constrained_xpath(self)
  self.xpath_relative = OM::XML::TermXpathGenerator.generate_relative_xpath(self)
  self.children.each_value {|child| child.generate_xpath_queries! }
  return self
end

#is_root_term?Boolean

Returns:

  • (Boolean)


233
234
235
# File 'lib/om/xml/term.rb', line 233

def is_root_term?
  @is_root_term == true
end

#retrieve_term(*pointers) ⇒ Object

crawl down into mapper’s children hash to find the desired mapper ie. @test_mapper.retrieve_mapper(:conference, :role, :text)



216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/om/xml/term.rb', line 216

def retrieve_term(*pointers)
  children_hash = self.children
  pointers.each do |p|
    if children_hash.has_key?(p)
      target = children_hash[p]
      if pointers.index(p) == pointers.length-1
        return target
      else
        children_hash = target.children
      end
    else
      return nil
    end
  end
  return target
end

#to_xml(options = {}, document = Nokogiri::XML::Document.new) ⇒ Nokogiri::XML::Document

Return an XML representation of the Term

Examples:

If :children=>false, skips rendering child Terms

term.to_xml(:children=>false)

You can provide your own Nokogiri document to insert the xml into

doc = Nokogiri::XML::Document.new
term.to_xml({}, document=doc)

Parameters:

  • options, (Hash)

    the term will be added to it. If :children=>false, skips rendering child Terms

  • (optional) (Nokogiri::XML::Document)

    document to insert the term xml into

Returns:

  • (Nokogiri::XML::Document)


292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
# File 'lib/om/xml/term.rb', line 292

def to_xml(options={}, document=Nokogiri::XML::Document.new)
  builder = Nokogiri::XML::Builder.with(document) do |xml|
    xml.term(:name=>name) {
      if is_root_term?
        xml.is_root_term("true")
      end
      xml.path path
      xml.namespace_prefix namespace_prefix
      unless attributes.nil? || attributes.empty?
        xml.attributes {
          attributes.each_pair do |attribute_name, attribute_value|
            xml.send("#{attribute_name}_".to_sym, attribute_value)
          end
        }
      end
      xml.index_as {
        unless index_as.nil?
          index_as.each  { |index_type| xml.index_type }
        end
      }
      xml.required required
      xml.data_type data_type
      unless variant_of.nil?
        xml.variant_of variant_of
      end
      unless default_content_path.nil?
        xml.default_content_path default_content_path
      end
      xml.xpath {
        xml.relative xpath_relative
        xml.absolute xpath
        xml.constrained xpath_constrained
      }
      if options.fetch(:children, true)
        xml.children
      end
    }
  end
  doc = builder.doc
  if options.fetch(:children, true)
    children.values.each {|child| child.to_xml(options, doc.xpath("//term[@name=\"#{name}\"]/children").first)}
  end
  return doc
end

#xml_builder_template(extra_opts = {}) ⇒ Object

term_pointers reference to the property you want to generate a builder template for



243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
# File 'lib/om/xml/term.rb', line 243

def xml_builder_template(extra_opts = {})
  extra_attributes = extra_opts.fetch(:attributes, {})

  node_options = []
  node_child_template = ""
  if !self.default_content_path.nil?
    node_child_options = ["\':::builder_new_value:::\'"]
    node_child_template = " { xml.#{self.default_content_path}( #{OM::XML.delimited_list(node_child_options)} ) }"
  else
    node_options = ["\':::builder_new_value:::\'"]
  end
  if !self.attributes.nil?
    self.attributes.merge(extra_attributes).each_pair do |k,v|
      node_options << "\'#{k}\'=>\'#{v}\'"
    end
  end
  if self.path.include?(":")
    ns_prefix = self.path[0..path.index(":")-1]
    path_name = self.path[path.index(":")+1..-1]
    template = "xml['#{ns_prefix}'].#{path_name}( #{OM::XML.delimited_list(node_options)} )" + node_child_template
  elsif !self.namespace_prefix.nil? and self.namespace_prefix != 'oxns'
    template = "xml['#{self.namespace_prefix}'].#{self.path}( #{OM::XML.delimited_list(node_options)} )" + node_child_template
  elsif self.path.kind_of?(Hash) && self.path[:attribute]
    template = "xml.@#{self.path[:attribute]}( #{OM::XML.delimited_list(node_options)} )" + node_child_template
  else
    template = "xml.#{self.path}( #{OM::XML.delimited_list(node_options)} )" + node_child_template
  end
  return template.gsub( /:::(.*?):::/ ) { '#{'+$1+'}' }
end

#xpath_absoluteObject



237
238
239
# File 'lib/om/xml/term.rb', line 237

def xpath_absolute
  @xpath
end