om 1.2.5 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COMMON_OM_PATTERNS.textile +127 -0
- data/GETTING_FANCY.textile +15 -13
- data/GETTING_STARTED.textile +89 -51
- data/QUERYING_DOCUMENTS.textile +30 -25
- data/README.rdoc +5 -1
- data/README.textile +4 -0
- data/lib/om/samples/mods_article.rb +7 -4
- data/lib/om/version.rb +1 -1
- data/lib/om/xml/document.rb +10 -2
- data/lib/om/xml/named_term_proxy.rb +7 -2
- data/lib/om/xml/term.rb +59 -9
- data/lib/om/xml/term_value_operators.rb +3 -0
- data/lib/om/xml/terminology.rb +29 -0
- data/lib/om/xml.rb +3 -0
- data/spec/fixtures/mods_article_terminology.xml +2882 -0
- data/spec/unit/document_spec.rb +12 -0
- data/spec/unit/named_term_proxy_spec.rb +22 -9
- data/spec/unit/term_builder_spec.rb +1 -1
- data/spec/unit/term_spec.rb +20 -3
- data/spec/unit/term_value_operators_spec.rb +24 -0
- data/spec/unit/terminology_spec.rb +5 -5
- data/spec/unit/xml_serialization_spec.rb +63 -0
- metadata +12 -8
- data/VERSION +0 -1
@@ -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.
|
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
data/lib/om/xml/document.rb
CHANGED
@@ -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:
|
61
|
-
#
|
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:
|
2
|
-
#
|
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
|
-
|
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 << "
|
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
|
data/lib/om/xml/terminology.rb
CHANGED
@@ -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
|