om 3.1.0 → 3.1.1
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.
- checksums.yaml +4 -4
- data/{COMMON_OM_PATTERNS.textile → COMMON_OM_PATTERNS.md} +136 -126
- data/CONTRIBUTING.md +2 -2
- data/GETTING_FANCY.md +153 -0
- data/GETTING_STARTED.md +329 -0
- data/Gemfile +1 -1
- data/History.md +164 -0
- data/LICENSE +15 -20
- data/QUERYING_DOCUMENTS.md +162 -0
- data/README.md +2 -2
- data/UPDATING_DOCUMENTS.md +6 -0
- data/gemfiles/gemfile.rails3 +1 -1
- data/gemfiles/gemfile.rails4 +1 -1
- data/lib/om/version.rb +1 -1
- data/lib/om/xml/dynamic_node.rb +42 -51
- data/lib/tasks/om.rake +1 -1
- data/om.gemspec +1 -2
- data/spec/integration/differentiated_elements_spec.rb +2 -2
- data/spec/integration/element_value_spec.rb +13 -13
- data/spec/integration/proxies_and_ref_spec.rb +10 -10
- data/spec/integration/querying_documents_spec.rb +20 -27
- data/spec/integration/rights_metadata_integration_example_spec.rb +4 -4
- data/spec/integration/selective_querying_spec.rb +1 -1
- data/spec/integration/serialization_spec.rb +15 -15
- data/spec/integration/set_reentrant_terminology_spec.rb +6 -6
- data/spec/integration/subclass_terminology_spec.rb +8 -8
- data/spec/integration/xpathy_stuff_spec.rb +10 -10
- data/spec/unit/container_spec.rb +27 -27
- data/spec/unit/document_spec.rb +24 -24
- data/spec/unit/dynamic_node_spec.rb +60 -49
- data/spec/unit/named_term_proxy_spec.rb +12 -7
- data/spec/unit/node_generator_spec.rb +4 -4
- data/spec/unit/nokogiri_sanity_spec.rb +17 -18
- data/spec/unit/om_spec.rb +2 -2
- data/spec/unit/template_registry_spec.rb +51 -51
- data/spec/unit/term_builder_spec.rb +45 -44
- data/spec/unit/term_spec.rb +55 -55
- data/spec/unit/term_value_operators_spec.rb +205 -205
- data/spec/unit/term_xpath_generator_spec.rb +33 -36
- data/spec/unit/terminology_builder_spec.rb +50 -47
- data/spec/unit/terminology_spec.rb +92 -92
- data/spec/unit/validation_spec.rb +12 -12
- data/spec/unit/xml_serialization_spec.rb +20 -20
- data/spec/unit/xml_spec.rb +3 -3
- data/spec/unit/xml_terminology_based_solrizer_spec.rb +18 -18
- metadata +11 -38
- data/GETTING_FANCY.textile +0 -145
- data/GETTING_STARTED.textile +0 -254
- data/History.textile +0 -186
- data/QUERYING_DOCUMENTS.textile +0 -139
- data/UPDATING_DOCUMENTS.textile +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 47b327a1e5c5c97aaced259dfada9e0272a7e011
|
4
|
+
data.tar.gz: 43198216111873a28f12a414d420bccf3f1453f6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 509267f8bedd654a287e8c97dbd55076f6c21beb31e6af88b0910a5b33c505e2e1efff7f36ae5b831731e58fe4d9723c9e6e56da568bdc12e56f7321bb87fab5
|
7
|
+
data.tar.gz: 717a6650a821571adac1077be22ef1e56d4c56d74821601c3372f48caa29ce2217a1c2d47fdb9c2be2356f3c09cd3225db80037f9a36065f057f4a1ec3aa1b12
|
@@ -1,10 +1,10 @@
|
|
1
|
-
|
1
|
+
# Common Patterns You’ll Use with OM
|
2
2
|
|
3
|
-
|
3
|
+
## Common Terminology Patterns
|
4
4
|
|
5
|
-
Let
|
5
|
+
Let’s say we have xml like this:
|
6
6
|
|
7
|
-
|
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
|
-
|
26
|
+
```
|
27
27
|
|
28
|
-
|
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
|
-
|
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
|
-
|
44
|
+
```
|
46
45
|
|
47
|
-
This results in :elementA having a value of
|
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
|
-
|
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
|
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
|
-
|
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
|
-
|
66
|
+
```
|
67
67
|
|
68
|
-
This results in :elementC having a value of
|
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
|
-
|
71
|
+
#### element value given absence of a specific attribute
|
71
72
|
|
72
|
-
We want an OM term for an element
|
73
|
+
We want an OM term for an element’s value, but only if the element does
|
74
|
+
not have a specific attribute.
|
73
75
|
|
74
|
-
|
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
|
-
|
85
|
+
```
|
85
86
|
|
86
|
-
This results in both :elementB and :
|
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
|
-
|
94
|
-
|
95
|
-
|
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
|
-
|
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
|
-
|
113
|
+
#### an example with :proxy and :ref
|
113
114
|
|
114
|
-
|
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
|
-
|
148
|
+
```
|
149
149
|
|
150
|
-
This results in
|
151
|
-
:ead_fedora_pid has value
|
152
|
-
:ead_ds_label has value
|
153
|
-
:ead_size has value
|
154
|
-
:ead_md5 has value
|
155
|
-
:ead_sha1 has value
|
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”
|
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
|
-
:
|
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
|
-
|
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
|
-
|
177
|
+
```
|
180
178
|
|
181
|
-
We want an OM term corresponding to the
|
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
|
-
|
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
|
-
|
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.
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
</
|
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
|
-
|
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
|
-
|
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
|
281
|
-
|
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
|
-
|
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
|
-
|
308
|
+
```
|
302
309
|
|
303
310
|
In the Datastream model:
|
304
311
|
|
305
|
-
|
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
|
-
|
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
|
-
|
343
|
+
### Arguments that can be used in the terminology
|
335
344
|
|
336
|
-
e.g. :path, :
|
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
|
-
|
351
|
+
Like Nokogiri …
|
342
352
|
|
343
|
-
|
353
|
+
### Namespaces
|
354
|
+
- oxns
|
355
|
+
- document namespaces & node namespaces
|
356
|
+
- *no namespace* (suppressing oxns in xpath queries)
|
344
357
|
|
345
|
-
|
346
|
-
oxns
|
347
|
-
document namespaces & node namespaces
|
348
|
-
_no namespace_ (suppressing oxns in xpath queries)
|
358
|
+
### :ref and :proxy Terms
|
349
359
|
|
350
|
-
|
360
|
+
If needed (as a differentiator) you can use the root element as a member
|
361
|
+
of the proxy address:
|
351
362
|
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
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
|
+
```
|
data/CONTRIBUTING.md
CHANGED
@@ -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.
|
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
|
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_
|
data/GETTING_FANCY.md
ADDED
@@ -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
|
+
```
|