om 3.1.0 → 3.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/{COMMON_OM_PATTERNS.textile → COMMON_OM_PATTERNS.md} +136 -126
  3. data/CONTRIBUTING.md +2 -2
  4. data/GETTING_FANCY.md +153 -0
  5. data/GETTING_STARTED.md +329 -0
  6. data/Gemfile +1 -1
  7. data/History.md +164 -0
  8. data/LICENSE +15 -20
  9. data/QUERYING_DOCUMENTS.md +162 -0
  10. data/README.md +2 -2
  11. data/UPDATING_DOCUMENTS.md +6 -0
  12. data/gemfiles/gemfile.rails3 +1 -1
  13. data/gemfiles/gemfile.rails4 +1 -1
  14. data/lib/om/version.rb +1 -1
  15. data/lib/om/xml/dynamic_node.rb +42 -51
  16. data/lib/tasks/om.rake +1 -1
  17. data/om.gemspec +1 -2
  18. data/spec/integration/differentiated_elements_spec.rb +2 -2
  19. data/spec/integration/element_value_spec.rb +13 -13
  20. data/spec/integration/proxies_and_ref_spec.rb +10 -10
  21. data/spec/integration/querying_documents_spec.rb +20 -27
  22. data/spec/integration/rights_metadata_integration_example_spec.rb +4 -4
  23. data/spec/integration/selective_querying_spec.rb +1 -1
  24. data/spec/integration/serialization_spec.rb +15 -15
  25. data/spec/integration/set_reentrant_terminology_spec.rb +6 -6
  26. data/spec/integration/subclass_terminology_spec.rb +8 -8
  27. data/spec/integration/xpathy_stuff_spec.rb +10 -10
  28. data/spec/unit/container_spec.rb +27 -27
  29. data/spec/unit/document_spec.rb +24 -24
  30. data/spec/unit/dynamic_node_spec.rb +60 -49
  31. data/spec/unit/named_term_proxy_spec.rb +12 -7
  32. data/spec/unit/node_generator_spec.rb +4 -4
  33. data/spec/unit/nokogiri_sanity_spec.rb +17 -18
  34. data/spec/unit/om_spec.rb +2 -2
  35. data/spec/unit/template_registry_spec.rb +51 -51
  36. data/spec/unit/term_builder_spec.rb +45 -44
  37. data/spec/unit/term_spec.rb +55 -55
  38. data/spec/unit/term_value_operators_spec.rb +205 -205
  39. data/spec/unit/term_xpath_generator_spec.rb +33 -36
  40. data/spec/unit/terminology_builder_spec.rb +50 -47
  41. data/spec/unit/terminology_spec.rb +92 -92
  42. data/spec/unit/validation_spec.rb +12 -12
  43. data/spec/unit/xml_serialization_spec.rb +20 -20
  44. data/spec/unit/xml_spec.rb +3 -3
  45. data/spec/unit/xml_terminology_based_solrizer_spec.rb +18 -18
  46. metadata +11 -38
  47. data/GETTING_FANCY.textile +0 -145
  48. data/GETTING_STARTED.textile +0 -254
  49. data/History.textile +0 -186
  50. data/QUERYING_DOCUMENTS.textile +0 -139
  51. data/UPDATING_DOCUMENTS.textile +0 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 774ca56c42282c5d31bef07b86d7f6e5e54d74b7
4
- data.tar.gz: bcf4d74285aa0283c8c4a926e988b5444f0706ae
3
+ metadata.gz: 47b327a1e5c5c97aaced259dfada9e0272a7e011
4
+ data.tar.gz: 43198216111873a28f12a414d420bccf3f1453f6
5
5
  SHA512:
6
- metadata.gz: 8c277df99dae62c250a6747bd05f68aa058477ccec12c03861818880e2ce828f20e21a1203bda0204d088830ecf59b9769caba20929fd0643bd3d28362c38091
7
- data.tar.gz: d145e98cd6c1387c58b6c98715d502b5bdb30e970050f0ab75c52c1c7fdb00b23ee83f09fdcf1c70565bd5fb6aecd3ab1794bc86b59d83dc0a2aaa1ed7a0d1a4
6
+ metadata.gz: 509267f8bedd654a287e8c97dbd55076f6c21beb31e6af88b0910a5b33c505e2e1efff7f36ae5b831731e58fe4d9723c9e6e56da568bdc12e56f7321bb87fab5
7
+ data.tar.gz: 717a6650a821571adac1077be22ef1e56d4c56d74821601c3372f48caa29ce2217a1c2d47fdb9c2be2356f3c09cd3225db80037f9a36065f057f4a1ec3aa1b12
@@ -1,10 +1,10 @@
1
- h1. Common Patterns You'll Use with OM
1
+ # Common Patterns Youll Use with OM
2
2
 
3
- h2. Common Terminology Patterns
3
+ ## Common Terminology Patterns
4
4
 
5
- Let's say we have xml like this:
5
+ Lets say we have xml like this:
6
6
 
7
- <pre>
7
+ ```text/xml
8
8
  <outer outerId="hypatia:outer" type="outer type">
9
9
  <elementA>valA</elementA>
10
10
  <elementB>valB1</elementB>
@@ -23,16 +23,15 @@ Let's say we have xml like this:
23
23
  </file>
24
24
  </resource>
25
25
  </outer>
26
- </pre>
26
+ ```
27
27
 
28
- h4. element value
28
+ #### element value
29
29
 
30
- We want an OM term for the value of an element.
30
+ We want an OM term for the value of an element.
31
31
 
32
32
  In the Datastream Model:
33
33
 
34
- <pre>
35
- # defines the expected OM terminology for example xml
34
+ ```ruby
36
35
  class ExampleXMLDS < ActiveFedora::NokogiriDatastream
37
36
  # OM (Opinionated Metadata) terminology mapping
38
37
  set_terminology do |t|
@@ -42,18 +41,19 @@ class ExampleXMLDS < ActiveFedora::NokogiriDatastream
42
41
  t.elC(:path => "elementC", :namespace_prefix => nil)
43
42
  end
44
43
  end
45
- </pre>
44
+ ```
46
45
 
47
- This results in :elementA having a value of "valA" and :elB having two values of "valB1" and "valB2", and :elC having a value of "valC"
46
+ This results in :elementA having a value of valA and :elB having two
47
+ values of “valB1” and “valB2”, and :elC having a value of “valC”
48
48
 
49
- h4. element value given a specific attribute value
49
+ #### Element value given a specific attribute value
50
50
 
51
- We want an OM term for the value of an element, but only if the element has a specific attribute value.
51
+ We want an OM term for the value of an element, but only if the element
52
+ has a specific attribute value.
52
53
 
53
54
  In the Datastream Model:
54
55
 
55
- <pre>
56
- # defines the expected OM terminology for example xml
56
+ ```ruby
57
57
  class ExampleXMLDS < ActiveFedora::NokogiriDatastream
58
58
  # OM (Opinionated Metadata) terminology mapping
59
59
  set_terminology do |t|
@@ -63,16 +63,17 @@ class ExampleXMLDS < ActiveFedora::NokogiriDatastream
63
63
  t.there(:path=>"resource", :attributes=>{:type=>"nowhere"}, :namespace_prefix => nil)
64
64
  end
65
65
  end
66
- </pre>
66
+ ```
67
67
 
68
- This results in :elementC having a value of "valC" and :here having a value of "123 456", and :there having a value of nil (or is it ""?)
68
+ This results in :elementC having a value of valC and :here having a
69
+ value of “123 456”, and :there having a value of nil (or is it “”?)
69
70
 
70
- h4. element value given absence of a specific attribute
71
+ #### element value given absence of a specific attribute
71
72
 
72
- We want an OM term for an element's value, but only if the element does not have a specific attribute.
73
+ We want an OM term for an elements value, but only if the element does
74
+ not have a specific attribute.
73
75
 
74
- <pre>
75
- # defines the expected OM terminology for example xml
76
+ ```ruby
76
77
  class ExampleXMLDS < ActiveFedora::NokogiriDatastream
77
78
  # OM (Opinionated Metadata) terminology mapping
78
79
  set_terminology do |t|
@@ -81,19 +82,18 @@ class ExampleXMLDS < ActiveFedora::NokogiriDatastream
81
82
  t.no_attrib(:path => "elementB", :attributes=>{:animal=>:none}, :namespace_prefix => nil)
82
83
  end
83
84
  end
84
- </pre>
85
+ ```
85
86
 
86
- This results in both :elementB and :no_attib having the single value "valB1"
87
+ This results in both :elementB and :no\_attib having the single value
88
+ “valB1”
87
89
 
88
-
89
- h4. attribute value
90
+ #### attribute value
90
91
 
91
92
  We want an OM term for an attribute value
92
93
 
93
- <pre>
94
- # defines the expected OM terminology for example xml
95
- class ExampleXMLDS < ActiveFedora::NokogiriDatastream
96
- # OM (Opinionated Metadata) terminology mapping
94
+ ```ruby
95
+ class ExampleXMLDS < ActiveFedora::NokogiriDatastream
96
+ # OM (Opinionated Metadata) terminology mapping
97
97
  set_terminology do |t|
98
98
  t.root(:path => "outer", :xmlns => '', :namespace_prefix => nil)
99
99
  t.elementB {
@@ -102,17 +102,17 @@ class ExampleXMLDS < ActiveFedora::NokogiriDatastream
102
102
  t.alternate(:path => "elementB/@animal", :namespace_prefix => nil)
103
103
  t.another(:proxy=>[:elementB, :my_attr_])
104
104
  t.animal_attrib(:path => {:attribute=>"animal"}, :namespace_prefix => nil)
105
- end
105
+ end
106
106
  end
107
- </pre>
108
-
109
- This results in :my_attr, :alternate and :another all having the single value of "vole", and :animal_attrib having the values "vole" and "seagull"
107
+ ```
110
108
 
109
+ This results in :my\_attr, :alternate and :another all having the single
110
+ value of “vole”, and :animal\_attrib having the values “vole” and
111
+ “seagull”
111
112
 
112
- h4. an example with :proxy and :ref
113
+ #### an example with :proxy and :ref
113
114
 
114
- <pre>
115
- # defines the expected OM terminology for example xml
115
+ ```ruby
116
116
  class ExampleXMLDS < ActiveFedora::NokogiriDatastream
117
117
  # OM (Opinionated Metadata) terminology mapping
118
118
  set_terminology do |t|
@@ -145,27 +145,25 @@ class ExampleXMLDS < ActiveFedora::NokogiriDatastream
145
145
  t.image_sha1(:proxy=>[:image, :file, :sha1])
146
146
  end
147
147
  end
148
- </pre>
148
+ ```
149
149
 
150
- This results in
151
- :ead_fedora_pid has value "hypatia:ead_file_asset_fixture"
152
- :ead_ds_label has value "my_ead.xml"
153
- :ead_size has value "47570"
154
- :ead_md5 has value"123"
155
- :ead_sha1 has value "456"
150
+ This results in:
151
+ - :ead_fedora_pid has value hypatia:ead\_file\_asset\_fixture”
152
+ - :ead_ds_label has value “my\_ead.xml
153
+ - :ead_size has value 47570
154
+ - :ead_md5 has value123
155
+ - :ead_sha1 has value 456
156
+ - :image_fedora_pid has value “hypatia:coll_img_file_asset_fixture”
157
+ - :image_ds_label has value “my_image.jpg”
158
+ - :image_size has value “302080”
159
+ - :image_md5 has value “789”
160
+ - :image_sha1 has value “666”
156
161
 
157
- :image_fedora_pid has value "hypatia:coll_img_file_asset_fixture"
158
- :image_ds_label has value "my_image.jpg"
159
- :image_size has value "302080"
160
- :image_md5 has value "789"
161
- :image_sha1 has value "666"
162
+ #### xpath-y stuff, also using :ref and :proxy and namespaces
162
163
 
164
+ Let’s say we have xml like this:
163
165
 
164
- h4. xpath-y stuff, also using :ref and :proxy and namespaces
165
-
166
- Let's say we have xml like this:
167
-
168
- <pre>
166
+ ```text/xml
169
167
  <contentMetadata>
170
168
  <resource type="file" id="BU3A5" objectId="val2">
171
169
  <file id="BURCH1" format="BINARY">
@@ -176,14 +174,16 @@ Let's say we have xml like this:
176
174
  </file>
177
175
  </resource>
178
176
  </contentMetadata>
179
- </pre>
177
+ ```
180
178
 
181
- We want an OM term corresponding to the <file> element based on the value of the <location> element. That is, we want to have a :content term when the value of <location> is "content" and an :html term when the value of <location> is "html".
179
+ We want an OM term corresponding to the `<file>` element based on the
180
+ value of the `<location>` element. That is, we want to have a :content
181
+ term when the value of `<location>` is “content” and an :html term when
182
+ the value of `<location>` is “html”.
182
183
 
183
184
  In the Datastream Model:
184
185
 
185
- <pre>
186
- # defines the expected OM terminology for example xml
186
+ ```ruby
187
187
  class ExampleXMLDS < ActiveFedora::NokogiriDatastream
188
188
  # OM (Opinionated Metadata) terminology mapping
189
189
  t.root(:path=>"contentMetadata", :xmlns => '', :namespace_prefix => nil)
@@ -208,47 +208,50 @@ class ExampleXMLDS < ActiveFedora::NokogiriDatastream
208
208
  t.html_filename(:proxy=>[:html, :filename])
209
209
  t.html_format(:proxy=>[:html, :format])
210
210
  end
211
- </pre>
211
+ ```
212
212
 
213
213
  Another example from Molly Pickral of UVa:
214
214
 
215
- We want to access just the author and the advisor from the XML below. The two <name> elements must be distinguished by their <roleTerm> value, a grandchild of the <name> element.
216
- We want an :author term with value "Mary Pickral", and an :advisor term with value "David Jones".
217
-
218
- <pre>
219
- <mods xmlns="http://www.loc.gov/mods/v3"
220
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.3"
221
- xsi:schemaLocation="http://www.loc.gov/mods/v3
222
- http://www.loc.gov/standards/mods/v3/mods-3-3.xsd">
223
- <name type="personal">
224
- <namePart type="given">Mary</namePart>
225
- <namePart type="family">Pickral</namePart>
226
- <affiliation>University of Virginia</affiliation>
227
- <namePart>mpc3c</namePart>
228
- <affiliation>University of Virginia Library</affiliation>
229
- <role>
230
- <roleTerm authority="marcrelator" type="code">aut</roleTerm>
231
- <roleTerm authority="marcrelator" type="text">author</roleTerm>
232
- </role>
233
- </name>
234
- <name type="personal">
235
- <namePart>der5y</namePart>
236
- <namePart type="given">David</namePart>
237
- <namePart type="family">Jones</namePart>
238
- <affiliation>University of Virginia</affiliation>
239
- <affiliation>Architectural History Dept.</affiliation>
240
- <role>
241
- <roleTerm authority="marcrelator" type="code">ths</roleTerm>
242
- <roleTerm authority="marcrelator" type="text">advisor</roleTerm>
243
- </role>
244
- </name>
245
- </mods>
246
- </pre>
215
+ We want to access just the author and the advisor from the XML below.
216
+ The two `<name>` elements must be distinguished by their `<roleTerm>` value,
217
+ a grandchild of the `<name>` element.
218
+
219
+ We want an :author term with value “Mary Pickral”, and an :advisor term
220
+ with value “David Jones”.
221
+
222
+ ```text/xml
223
+ <mods xmlns="http://www.loc.gov/mods/v3"
224
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.3"
225
+ xsi:schemaLocation="http://www.loc.gov/mods/v3
226
+ http://www.loc.gov/standards/mods/v3/mods-3-3.xsd">
227
+ <name type="personal">
228
+ <namePart type="given">Mary</namePart>
229
+ <namePart type="family">Pickral</namePart>
230
+ <affiliation>University of Virginia</affiliation>
231
+ <namePart>mpc3c</namePart>
232
+ <affiliation>University of Virginia Library</affiliation>
233
+ <role>
234
+ <roleTerm authority="marcrelator" type="code">aut</roleTerm>
235
+ <roleTerm authority="marcrelator" type="text">author</roleTerm>
236
+ </role>
237
+ </name>
238
+ <name type="personal">
239
+ <namePart>der5y</namePart>
240
+ <namePart type="given">David</namePart>
241
+ <namePart type="family">Jones</namePart>
242
+ <affiliation>University of Virginia</affiliation>
243
+ <affiliation>Architectural History Dept.</affiliation>
244
+ <role>
245
+ <roleTerm authority="marcrelator" type="code">ths</roleTerm>
246
+ <roleTerm authority="marcrelator" type="text">advisor</roleTerm>
247
+ </role>
248
+ </name>
249
+ </mods>
250
+ ```
247
251
 
248
252
  In the Datastream Model:
249
253
 
250
- <pre>
251
- # defines the expected OM terminology for mods thesis example xml
254
+ ```ruby
252
255
  class ModsThesis < ActiveFedora::NokogiriDatastream
253
256
  set_terminology do |t|
254
257
  t.root(:path=>"mods", :xmlns=>"http://www.loc.gov/mods/v3"))
@@ -269,20 +272,24 @@ class ModsThesis < ActiveFedora::NokogiriDatastream
269
272
  t.advisor_family(:proxy=>[:advisor, :family])
270
273
  end
271
274
  end
272
- </pre>
273
-
274
- This isn't quite what the doctor ordered, but :author_given and :author_family can be used to get the author name; similarly for advisor.
275
-
275
+ ```
276
276
 
277
+ This isn’t quite what the doctor ordered, but :author\_given and
278
+ :author\_family can be used to get the author name; similarly for
279
+ advisor.
277
280
 
278
281
  And a variant on the previous example using namespace prefixes.
279
282
 
280
- We want to access just the creator and the repository from the XML below. The two <name> elements must be distinguished by their <roleTerm> value, a grandchild of the <name> element.
281
- We want a :creator term with value "David Small", and a :repository term with value "Graphic Novel Repository".
283
+ We want to access just the creator and the repository from the XML
284
+ below. The two `<name>` elements must be distinguished by their `<roleTerm>`
285
+ value, a grandchild of the `<name>` element.
286
+
287
+ We want a :creator term with value “David Small”, and a :repository term
288
+ with value “Graphic Novel Repository”.
282
289
 
283
290
  Our xml:
284
291
 
285
- <pre>
292
+ ```text/xml
286
293
  <mods:mods xmlns:mods="http://www.loc.gov/mods/v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.3" xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-3.xsd">
287
294
 
288
295
  <mods:name type="personal">
@@ -298,12 +305,11 @@ Our xml:
298
305
  </mods:role>
299
306
  </mods:name>
300
307
  </mods:mods>
301
- </pre>
308
+ ```
302
309
 
303
310
  In the Datastream model:
304
311
 
305
- <pre>
306
- # defines the expected OM terminology for mods name example xml
312
+ ```ruby
307
313
  class ModsName < ActiveFedora::NokogiriDatastream
308
314
  t.root(:path=>"mods", :xmlns=>"http://www.loc.gov/mods/v3", :schema=>"http://www.loc.gov/standards/mods/v3/mods-3-3.xsd", :namespace_prefix => "mods")
309
315
 
@@ -326,37 +332,41 @@ class ModsName < ActiveFedora::NokogiriDatastream
326
332
  t.corporate(:proxy=>[:corporate_full, :name_part])
327
333
  t.repository(:ref=>:corporate, :path=>'name[mods:role/mods:roleTerm="repository"]', :xmlns=>"http://www.loc.gov/mods/v3", :namespace_prefix => "mods")
328
334
  end
329
- </pre>
330
-
331
- This terminology not only gives the :creator and :repository values as desired, but also has :person and :corporate terms for more generic <name> xml. The :person_full and :corporate_full values include the value of the <roleTerm> field, which is undesirable for display, if not the index.
335
+ ```
332
336
 
337
+ This terminology not only gives the :creator and :repository values as
338
+ desired, but also has :person and :corporate terms for more generic
339
+ `<name>` xml. The `:person_full` and `:corporate_full` values include the
340
+ value of the `<roleTerm>` field, which is undesirable for display, if not
341
+ the index.
333
342
 
334
- h3. Arguments that can be used in the terminology
343
+ ### Arguments that can be used in the terminology
335
344
 
336
- e.g. :path, :default_content_path, :namespace_prefix ...
345
+ e.g. :path, :default\_content\_path, :namespace\_prefix
337
346
 
338
- ok if this is a link to the rdoc that describes ALL of these with
347
+ ok if this is a link to the rdoc that describes ALL of these with
339
348
 
349
+ ### Reserved method names (ie. id\_, root\_)
340
350
 
341
- h3. Reserved method names (ie. id_, root_)
351
+ Like Nokogiri
342
352
 
343
- Like Nokogiri ...
353
+ ### Namespaces
354
+ - oxns
355
+ - document namespaces & node namespaces
356
+ - *no namespace* (suppressing oxns in xpath queries)
344
357
 
345
- h3. Namespaces
346
- oxns
347
- document namespaces & node namespaces
348
- _no namespace_ (suppressing oxns in xpath queries)
358
+ ### :ref and :proxy Terms
349
359
 
350
- h3. :ref and :proxy Terms
360
+ If needed (as a differentiator) you can use the root element as a member
361
+ of the proxy address:
351
362
 
352
- If needed (as a differentiator) you can use the root element as a member of the proxy address:
353
- <pre>
354
- t.root(:path=>"mods")
355
- t.titleInfo {
356
- t.title
357
- }
358
- This produces a relative xpath: (e.g. //titleInfo/title)
359
- t.title(:proxy=>[:titleInfo, :title])
360
- This produces an absolute query (e.g. /mods/titleInfo/title)
361
- t.title(:proxy=>[:mods, :titleInfo, :title])
362
- </pre>
363
+ ```ruby
364
+ t.root(:path=>"mods")
365
+ t.titleInfo {
366
+ t.title
367
+ }
368
+ This produces a relative xpath: (e.g. //titleInfo/title)
369
+ t.title(:proxy=>[:titleInfo, :title])
370
+ This produces an absolute query (e.g. /mods/titleInfo/title)
371
+ t.title(:proxy=>[:mods, :titleInfo, :title])
372
+ ```
@@ -39,7 +39,7 @@ You should also add yourself to the `CONTRIBUTORS.md` file in the root of the pr
39
39
  * Please avoid working directly on the `master` branch.
40
40
  * You may find the [hub suite of commands](https://github.com/defunkt/hub) helpful
41
41
  * Make commits of logical units.
42
- * Your commit should include a high level description of your work in HISTORY.textile
42
+ * Your commit should include a high level description of your work in HISTORY.md
43
43
  * Check for unnecessary whitespace with `git diff --check` before committing.
44
44
  * Make sure your commit messages are [well formed](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
45
45
  * If you created an issue, you can close it by including "Closes #issue" in your commit message. See [Github's blog post for more details](https://github.com/blog/1386-closing-issues-via-commit-messages)
@@ -96,7 +96,7 @@ You should also add yourself to the `CONTRIBUTORS.md` file in the root of the pr
96
96
 
97
97
  ### Merging Changes
98
98
 
99
- * It is considered "poor from" to merge your own request.
99
+ * It is considered "poor form" to merge your own request.
100
100
  * Please take the time to review the changes and get a sense of what is being changed. Things to consider:
101
101
  * Does the commit message explain what is going on?
102
102
  * Does the code changes have tests? _Not all changes need new tests, some changes are refactorings_
@@ -0,0 +1,153 @@
1
+ # Getting Fancy
2
+
3
+ ## Alternative ways to Manipulate Terms, Terminologies and their Builders
4
+
5
+ There is more than one way to build a terminology.
6
+
7
+ ### OM::XML::Terminology::Builder Block Syntax
8
+
9
+ The simplest way to create an OM Terminology is to use the
10
+ [OM::XML::Terminology::Builder](OM/XML/Terminology/Builder.html) block
11
+ syntax.
12
+
13
+ In the following examples, we will show different ways of building this
14
+ Terminology:
15
+
16
+ ```ruby
17
+ builder = OM::XML::Terminology::Builder.new do |t|
18
+ t.root(:path=>"grants", :xmlns=>"http://yourmediashelf.com/schemas/hydra-dataset/v0", :schema=>"http://example.org/schemas/grants-v1.xsd")
19
+ t.grant {
20
+ t.org(:path=>"organization", :attributes=>{:type=>"funder"}) {
21
+ t.name(:index_as=>:searchable)
22
+ }
23
+ t.number
24
+ }
25
+ end
26
+ another_terminology = builder.build
27
+ ```
28
+
29
+ ### Using [OM::XML::Term](OM/XML/Term.html)::Builders
30
+
31
+ First, create the Terminology Builder object:
32
+
33
+ ```ruby
34
+ terminology_builder = OM::XML::Terminology::Builder.new
35
+ ```
36
+
37
+ The .root method handles creating the root term and setting namespaces,
38
+ schema, etc. on the Terminology:
39
+
40
+ ```ruby
41
+ terminology_builder.root(:path=>"grants", :xmlns=>"http://yourmediashelf.com/schemas/hydra-dataset/v0", :schema=>"http://example.org/schemas/grants-v1.xsd")
42
+ ```
43
+
44
+ This sets the namespaces for you and created the “grants” root term:
45
+
46
+ ```ruby
47
+ terminology_builder.namespaces
48
+ => {"oxns"=>"http://yourmediashelf.com/schemas/hydra-dataset/v0", "xmlns"=>"http://yourmediashelf.com/schemas/hydra-dataset/v0"}
49
+ terminology_builder.term_builders
50
+ ```
51
+
52
+ Create Term Builders for each of the Terms:
53
+
54
+ ```ruby
55
+ term1_builder = OM::XML::Term::Builder.new("grant", terminology_builder).path("grant")
56
+ subterm1_builder = OM::XML::Term::Builder.new("org", terminology_builder).attributes(:type=>"funder")
57
+ subsubterm_builder = OM::XML::Term::Builder.new("name", terminology_builder).index_as(:searchable)
58
+ subterm2_builder = OM::XML::Term::Builder.new("number", terminology_builder)
59
+ ```
60
+
61
+ Assemble the tree of Term builders by adding child builders to their
62
+ parents; then add the top level terms to the root term in the
63
+ Terminology builder:
64
+
65
+ ```ruby
66
+ subterm1_builder.add_child(subsubterm_builder)
67
+ term1_builder.add_child(subterm1_builder)
68
+ term1_builder.add_child(subterm2_builder)
69
+ terminology_builder.term_builders["grant"] = term1_builder
70
+ ```
71
+
72
+ Now build the Terminology, which will also call .build on each of the
73
+ Term Builders in the tree:
74
+
75
+ ```ruby
76
+ built_terminology = terminology_builder.build
77
+ ```
78
+
79
+ Test it out:
80
+
81
+ ```ruby
82
+ built_terminology.retrieve_term(:grant, :org, :name)
83
+ built_terminology.xpath_for(:grant, :org, :name)
84
+ built_terminology.root_terms
85
+ built_terminology.terms.keys # This will only return the Terms at the root of the terminology hierarchy
86
+ built_terminology.retrieve_term(:grant).children.keys
87
+ ```
88
+
89
+ ### Creating Terms & Terminologies without any Builders
90
+
91
+ If you want to manipulate Terms and Terminologies directly rather than
92
+ using the Builder classes, you can consume their APIs at any time.
93
+
94
+ People don’t often do this, but the option is there if you need it.
95
+
96
+ Create the Terminology, set its namespaces & (optional) schema:
97
+ (Note that you have to set the :oxns namespaces to match :xmlns. This is
98
+ usually done for you by the Terminology::Builder.root method.)
99
+
100
+ ```ruby
101
+ handcrafted_terminology = OM::XML::Terminology.new
102
+ handcrafted_terminology.namespaces[:xmlns] = "http://yourmediashelf.com/schemas/hydra-dataset/v0"
103
+ handcrafted_terminology.namespaces[:oxns] = "http://yourmediashelf.com/schemas/hydra-dataset/v0"
104
+ handcrafted_terminology.schema = "http://example.org/schemas/grants-v1.xsd"
105
+ ```
106
+
107
+ Create the Terms:
108
+
109
+ ```ruby
110
+ # Create term1 (the root) and set it as the root term
111
+ root_term = OM::XML::Term.new("grants")
112
+ root_term.is_root_term = true
113
+
114
+ # Create term1 (grant) and its subterms
115
+ term1 = OM::XML::Term.new("grant")
116
+
117
+ subterm1 = OM::XML::Term.new("org")
118
+ subterm1.path = "organization"
119
+ subterm1.attributes = {:type=>"funder"}
120
+
121
+ subsubterm = OM::XML::Term.new("name")
122
+ subsubterm.index_as = :searchable
123
+
124
+ subterm2 = OM::XML::Term.new("number")
125
+ ```
126
+
127
+ Assemble the tree of terms by adding child terms to their parents, then
128
+ add those to the Terminology.
129
+
130
+ ```ruby
131
+ subterm1.add_child(subsubterm)
132
+ term1.add_child(subterm1)
133
+ term1.add_child(subterm2)
134
+ handcrafted_terminology.add_term(root_term)
135
+ handcrafted_terminology.add_term(term1)
136
+ ```
137
+
138
+ Generate the xpath queries for each term. This is usually done for you
139
+ by the Term Builder.build method:
140
+
141
+ ```ruby
142
+ [root_term, term1, subterm1, subsubterm, subterm2].each {|t| t.generate_xpath_queries!}
143
+ ```
144
+
145
+ Test it out:
146
+
147
+ ```ruby
148
+ handcrafted_terminology.retrieve_term(:grant, :org, :name)
149
+ handcrafted_terminology.xpath_for(:grant, :org, :name)
150
+ handcrafted_terminology.root_terms
151
+ handcrafted_terminology.terms.keys # This will only return the Terms at the root of the terminology hierarchy
152
+ handcrafted_terminology.retrieve_term(:grant).children.keys
153
+ ```