om 3.1.0 → 3.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
```
|