om 1.2.5 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,11 +3,15 @@ class OM::Samples::ModsArticle
3
3
  include OM::XML::Document
4
4
 
5
5
  set_terminology do |t|
6
- t.root(:path=>"mods", :xmlns=>"http://www.loc.gov/mods/v3", :schema=>"http://www.loc.gov/standards/mods/v3/mods-3-2.xsd")
6
+ t.root(:path=>"mods", :xmlns=>"http://www.loc.gov/mods/v3", :schema=>"http://www.loc.gov/standards/mods/v3/mods-3-2.xsd", "xmlns:foo"=>"http://my.custom.namespace")
7
7
 
8
8
 
9
9
  t.title_info(:path=>"titleInfo") {
10
- t.main_title(:index_as=>[:facetable],:path=>"title", :label=>"title")
10
+ t.main_title(:index_as=>[:facetable],:path=>"title", :label=>"title") {
11
+ t.main_title_lang(:path=>{:attribute=> "xml:lang"})
12
+ }
13
+ t.french_title(:ref=>[:title_info,:main_title], :attributes=>{"xml:lang"=>"fre"})
14
+
11
15
  t.language(:index_as=>[:facetable],:path=>{:attribute=>"lang"})
12
16
  }
13
17
  t.language{
@@ -71,8 +75,7 @@ class OM::Samples::ModsArticle
71
75
  t.url(:path=>"url")
72
76
  }
73
77
  t.publication_url(:proxy=>[:location,:url])
74
- t.peer_reviewed(:proxy=>[:journal,:origin_info,:issuance], :index_as=>[:facetable])
75
- t.title(:proxy=>[:mods,:title_info, :main_title])
78
+ t.title(:proxy=>[:title_info, :main_title])
76
79
  t.journal_title(:proxy=>[:journal, :title_info, :main_title])
77
80
  end
78
81
 
data/lib/om/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Om
2
- VERSION = "1.2.5"
2
+ VERSION = "1.3.0"
3
3
  end
@@ -57,8 +57,10 @@ module OM::XML::Document
57
57
 
58
58
 
59
59
  # +term_pointer+ Variable length array of values in format [:accessor_name, :accessor_name ...] or [{:accessor_name=>index}, :accessor_name ...]
60
- # example: {:person => 1}, :first_name
61
- # example: [:person, 1, :first_name]
60
+ # @example:
61
+ # find_by_terms( {:person => 1}, :first_name )
62
+ # @example
63
+ # find_by_terms( [:person, 1, :first_name] )
62
64
  # Currently, indexes must be integers.
63
65
  def find_by_terms(*term_pointer)
64
66
  xpath = self.class.terminology.xpath_with_indexes(*term_pointer)
@@ -68,6 +70,12 @@ module OM::XML::Document
68
70
  return ng_xml.xpath(xpath, ox_namespaces)
69
71
  end
70
72
  end
73
+
74
+ # Test whether the document has a node corresponding to the given term_pointer
75
+ # @param [Array] term_pointer to test
76
+ def node_exists?(*term_pointer)
77
+ !find_by_terms(*term_pointer).empty?
78
+ end
71
79
 
72
80
  # Access the class's template registry
73
81
  def template_registry
@@ -23,9 +23,14 @@ class OM::XML::NamedTermProxy
23
23
 
24
24
  def proxied_term
25
25
  if self.parent.nil?
26
- self.terminology.retrieve_term(*self.proxy_pointer)
26
+ pt = self.terminology.retrieve_term(*self.proxy_pointer)
27
27
  else
28
- self.parent.retrieve_term(*self.proxy_pointer)
28
+ pt = self.parent.retrieve_term(*self.proxy_pointer)
29
+ end
30
+ if pt.nil?
31
+ raise OM::XML::Terminology::BadPointerError "The #{name} proxy term points to #{proxy_pointer.inspect} but that term doesn't exist."
32
+ else
33
+ return pt
29
34
  end
30
35
  end
31
36
 
data/lib/om/xml/term.rb CHANGED
@@ -1,5 +1,6 @@
1
- # Special options: data_type, attributes, index_as
2
- # is_root_term
1
+ # Special options:
2
+ # data_type, index_as, attributes,
3
+ # is_root_term, required
3
4
  #
4
5
  class OM::XML::Term
5
6
 
@@ -38,12 +39,7 @@ class OM::XML::Term
38
39
  if self.terminology_builder.nil?
39
40
  raise "Cannot perform lookup_ref for the #{self.name} builder. It doesn't have a reference to any terminology builder"
40
41
  end
41
- begin
42
- target = self.terminology_builder.retrieve_term_builder(*@settings[:ref])
43
- rescue OM::XML::Terminology::BadPointerError
44
- # Clarify message on BadPointerErrors
45
- raise OM::XML::Terminology::BadPointerError, "#{self.name} refers to a Term Builder that doesn't exist. The bad pointer is #{@settings[:ref].inspect}"
46
- end
42
+ target = self.terminology_builder.retrieve_term_builder(*@settings[:ref])
47
43
 
48
44
  # Fail on circular references and return an intelligible error message
49
45
  if nodes_visited.include?(target)
@@ -216,7 +212,7 @@ class OM::XML::Term
216
212
  end
217
213
  if !self.attributes.nil?
218
214
  self.attributes.merge(extra_attributes).each_pair do |k,v|
219
- node_options << ":#{k}=>\'#{v}\'"
215
+ node_options << "\'#{k}\'=>\'#{v}\'"
220
216
  end
221
217
  end
222
218
  template = "xml.#{self.path}( #{OM::XML.delimited_list(node_options)} )" + node_child_template
@@ -233,6 +229,60 @@ class OM::XML::Term
233
229
  return self
234
230
  end
235
231
 
232
+ # Return an XML representation of the Term
233
+ # @param [Hash] options, the term will be added to it. If :children=>false, skips rendering child Terms
234
+ # @param [Nokogiri::XML::Document] (optional) document to insert the term xml into
235
+ # @return [Nokogiri::XML::Document]
236
+ # @example If :children=>false, skips rendering child Terms
237
+ # term.to_xml(:children=>false)
238
+ # @example You can provide your own Nokogiri document to insert the xml into
239
+ # doc = Nokogiri::XML::Document.new
240
+ # term.to_xml({}, document=doc)
241
+ def to_xml(options={}, document=Nokogiri::XML::Document.new)
242
+ builder = Nokogiri::XML::Builder.with(document) do |xml|
243
+ xml.term(:name=>name) {
244
+ if is_root_term?
245
+ xml.is_root_term("true")
246
+ end
247
+ xml.path path
248
+ xml.namespace_prefix namespace_prefix
249
+ unless attributes.nil? || attributes.empty?
250
+ xml.attributes {
251
+ attributes.each_pair do |attribute_name, attribute_value|
252
+ xml.send("#{attribute_name}_".to_sym, attribute_value)
253
+ end
254
+ }
255
+ end
256
+ xml.index_as {
257
+ unless index_as.nil?
258
+ index_as.each { |index_type| xml.index_type }
259
+ end
260
+ }
261
+ xml.required required
262
+ xml.data_type data_type
263
+ unless variant_of.nil?
264
+ xml.variant_of variant_of
265
+ end
266
+ unless default_content_path.nil?
267
+ xml.default_content_path default_content_path
268
+ end
269
+ xml.xpath {
270
+ xml.relative xpath_relative
271
+ xml.absolute xpath
272
+ xml.constrained xpath_constrained
273
+ }
274
+ if options.fetch(:children, true)
275
+ xml.children
276
+ end
277
+ }
278
+ end
279
+ doc = builder.doc
280
+ if options.fetch(:children, true)
281
+ children.values.each {|child| child.to_xml(options, doc.xpath("//term[@name=\"#{name}\"]/children").first)}
282
+ end
283
+ return doc
284
+ end
285
+
236
286
  # private :update_xpath_values
237
287
 
238
288
  end
@@ -161,6 +161,9 @@ module OM::XML::TermValueOperators
161
161
  until !starting_point.empty?
162
162
  to_build = [parent_select.pop] + to_build
163
163
  starting_point = find_by_terms(*parent_select)
164
+ if starting_point.empty? && parent_select.empty?
165
+ raise OM::XML::TemplateMissingException, "Cannot insert nodes into the document because it is empty."
166
+ end
164
167
  end
165
168
  to_build.each do |term_pointer|
166
169
  parent_select << term_pointer
@@ -220,6 +220,35 @@ class OM::XML::Terminology
220
220
  terms.values.select {|term| term.is_root_term? }
221
221
  end
222
222
 
223
+ # Return an XML representation of the Terminology and its terms
224
+ # @param [Hash] options, the term will be added to it. If :children=>false, skips rendering child Terms
225
+ # @param [Nokogiri::XML::Document] (optional) document to insert the term xml into
226
+ # @return [Nokogiri::XML::Document]
227
+ # @example If :children=>false, skips rendering child Terms
228
+ # terminology.to_xml(:children=>false)
229
+ # @example You can provide your own Nokogiri document to insert the xml into
230
+ # doc = Nokogiri::XML::Document.new
231
+ # terminology.to_xml({}, document=doc)
232
+ def to_xml(options={}, document=Nokogiri::XML::Document.new)
233
+ builder = Nokogiri::XML::Builder.with(document) do |xml|
234
+ xml.terminology {
235
+ xml.schema schema
236
+ xml.namespaces {
237
+ namespaces.each_pair do |ns_name, ns_value|
238
+ xml.namespace {
239
+ xml.name ns_name
240
+ xml.identifier ns_value
241
+ }
242
+ end
243
+ }
244
+ xml.terms
245
+ }
246
+ end
247
+ document = builder.doc
248
+ terms.values.each {|term| term.to_xml(options,document.xpath("//terms").first)}
249
+ return document
250
+ end
251
+
223
252
  def self.term_generic_name(*pointers)
224
253
  pointers_to_flat_array(pointers, false).join("_")
225
254
  end
data/lib/om/xml.rb CHANGED
@@ -13,6 +13,9 @@ require "om/xml/template_registry"
13
13
 
14
14
  module OM::XML
15
15
 
16
+ # Raised when the XML document or XML template can't be found during an operation
17
+ class TemplateMissingException < StandardError; end
18
+
16
19
  attr_accessor :ng_xml
17
20
 
18
21
  # Module Methods -- These methods can be called directly on the Module itself