om 1.6.0 → 1.6.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.
Files changed (37) hide show
  1. data/COMMON_OM_PATTERNS.textile +13 -1
  2. data/Gemfile +7 -4
  3. data/Gemfile.lock +19 -14
  4. data/History.textile +4 -0
  5. data/lib/om/version.rb +1 -1
  6. data/lib/om/xml/document.rb +16 -2
  7. data/lib/om/xml/terminology.rb +5 -0
  8. data/lib/tasks/om.rake +16 -10
  9. data/om.gemspec +1 -0
  10. data/spec/fixtures/mods_articles/hydrangea_article1.xml +7 -0
  11. data/spec/integration/differentiated_elements_spec.rb +39 -0
  12. data/spec/integration/element_value_spec.rb +91 -0
  13. data/spec/integration/proxies_and_ref_spec.rb +81 -0
  14. data/spec/integration/querying_documents_spec.rb +73 -0
  15. data/spec/integration/rights_metadata_integration_example_spec.rb +2 -4
  16. data/spec/integration/selective_querying_spec.rb +89 -0
  17. data/spec/integration/set_reentrant_terminology_spec.rb +134 -0
  18. data/spec/integration/xpathy_stuff_spec.rb +204 -0
  19. data/spec/spec_helper.rb +8 -0
  20. data/spec/unit/container_spec.rb +2 -4
  21. data/spec/unit/document_spec.rb +2 -3
  22. data/spec/unit/dynamic_node_spec.rb +1 -2
  23. data/spec/unit/named_term_proxy_spec.rb +1 -2
  24. data/spec/unit/node_generator_spec.rb +2 -3
  25. data/spec/unit/nokogiri_sanity_spec.rb +2 -3
  26. data/spec/unit/om_spec.rb +2 -4
  27. data/spec/unit/template_registry_spec.rb +1 -2
  28. data/spec/unit/term_builder_spec.rb +2 -3
  29. data/spec/unit/term_spec.rb +1 -2
  30. data/spec/unit/term_value_operators_spec.rb +2 -3
  31. data/spec/unit/term_xpath_generator_spec.rb +1 -2
  32. data/spec/unit/terminology_builder_spec.rb +1 -2
  33. data/spec/unit/terminology_spec.rb +1 -2
  34. data/spec/unit/validation_spec.rb +2 -4
  35. data/spec/unit/xml_serialization_spec.rb +2 -4
  36. data/spec/unit/xml_spec.rb +2 -4
  37. metadata +68 -13
@@ -347,4 +347,16 @@ oxns
347
347
  document namespaces & node namespaces
348
348
  _no namespace_ (suppressing oxns in xpath queries)
349
349
 
350
- h3. :ref and :proxy Terms
350
+ h3. :ref and :proxy Terms
351
+
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>
data/Gemfile CHANGED
@@ -2,11 +2,14 @@ source "http://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'ruby-debug', :platform => :ruby_18
6
- gem 'ruby-debug19', :platform => :ruby_19
7
-
8
5
  group :development, :test do
9
- gem "rcov"
6
+ gem 'ruby-debug', :platform => :ruby_18
7
+ gem "debugger", :platform => :ruby_19
8
+
9
+ gem 'rcov', :platform => :mri_18
10
+ gem 'simplecov', :platform => :mri_19
11
+ gem 'simplecov-rcov', :platform => :mri_19
12
+
10
13
  gem "yard"
11
14
  gem "RedCloth", "~> 4.2.9"
12
15
  end
@@ -9,20 +9,26 @@ GEM
9
9
  remote: http://rubygems.org/
10
10
  specs:
11
11
  RedCloth (4.2.9)
12
- archive-tar-minitar (0.5.2)
13
12
  columnize (0.3.5)
13
+ debugger (1.1.3)
14
+ columnize (>= 0.3.1)
15
+ debugger-linecache (~> 1.1.1)
16
+ debugger-ruby_core_source (~> 1.1.2)
17
+ debugger-linecache (1.1.1)
18
+ debugger-ruby_core_source (>= 1.1.1)
19
+ debugger-ruby_core_source (1.1.3)
14
20
  diff-lcs (1.1.3)
15
21
  equivalent-xml (0.2.8)
16
22
  nokogiri (>= 1.4.3)
17
23
  linecache (0.46)
18
24
  rbx-require-relative (> 0.0.4)
19
- linecache19 (0.5.12)
20
- ruby_core_source (>= 0.1.4)
21
25
  mediashelf-loggable (0.4.9)
22
26
  metaclass (0.0.1)
23
27
  mocha (0.10.0)
24
28
  metaclass (~> 0.0.1)
29
+ multi_json (1.3.6)
25
30
  nokogiri (1.5.0)
31
+ rake (0.9.2.2)
26
32
  rbx-require-relative (0.0.5)
27
33
  rcov (0.9.11)
28
34
  rspec (2.7.0)
@@ -38,16 +44,12 @@ GEM
38
44
  ruby-debug-base (~> 0.10.4.0)
39
45
  ruby-debug-base (0.10.4)
40
46
  linecache (>= 0.3)
41
- ruby-debug-base19 (0.11.25)
42
- columnize (>= 0.3.1)
43
- linecache19 (>= 0.5.11)
44
- ruby_core_source (>= 0.1.4)
45
- ruby-debug19 (0.11.6)
46
- columnize (>= 0.3.1)
47
- linecache19 (>= 0.5.11)
48
- ruby-debug-base19 (>= 0.11.19)
49
- ruby_core_source (0.1.5)
50
- archive-tar-minitar (>= 0.5.2)
47
+ simplecov (0.6.4)
48
+ multi_json (~> 1.0)
49
+ simplecov-html (~> 0.5.3)
50
+ simplecov-html (0.5.3)
51
+ simplecov-rcov (0.2.3)
52
+ simplecov (>= 0.4.1)
51
53
  yard (0.7.4)
52
54
 
53
55
  PLATFORMS
@@ -55,11 +57,14 @@ PLATFORMS
55
57
 
56
58
  DEPENDENCIES
57
59
  RedCloth (~> 4.2.9)
60
+ debugger
58
61
  equivalent-xml (>= 0.2.4)
59
62
  mocha (>= 0.9.8)
60
63
  om!
64
+ rake
61
65
  rcov
62
66
  rspec (~> 2.0)
63
67
  ruby-debug
64
- ruby-debug19
68
+ simplecov
69
+ simplecov-rcov
65
70
  yard
@@ -1,3 +1,7 @@
1
+ h3. 1.6.1
2
+ Integration spec to illustrate selective querying.
3
+ Add #use_terminology and #extend_terminology methods to extend existing OM terminologies
4
+
1
5
  h3. 1.6.0
2
6
  Delegate all methods on the dynamic node to the found values
3
7
  Allow arrays to be set on dynamic nodes
@@ -1,3 +1,3 @@
1
1
  module Om
2
- VERSION = "1.6.0"
2
+ VERSION = "1.6.1"
3
3
  end
@@ -5,12 +5,26 @@ module OM::XML::Document
5
5
 
6
6
  module ClassMethods
7
7
 
8
- attr_accessor :terminology, :template_registry
8
+ attr_accessor :terminology, :terminology_builder, :template_registry
9
9
 
10
10
  # Sets the OM::XML::Terminology for the Document
11
11
  # Expects +&block+ that will be passed into OM::XML::Terminology::Builder.new
12
12
  def set_terminology &block
13
- @terminology = OM::XML::Terminology::Builder.new( &block ).build
13
+ @terminology_builder = OM::XML::Terminology::Builder.new( &block )
14
+
15
+ @terminology = @terminology_builder.build
16
+ end
17
+
18
+ # Update the OM::XML::Terminology with additional terms
19
+ def extend_terminology &block
20
+ @terminology_builder.extend_terminology(&block)
21
+ @terminology = @terminology_builder.build
22
+ end
23
+
24
+ # (Explicitly) inherit terminology from upstream classes
25
+ def use_terminology klass
26
+ @terminology_builder = klass.terminology_builder.dup
27
+ @terminology = @terminology_builder.build
14
28
  end
15
29
 
16
30
  # Define a new node template with the OM::XML::TemplateRegistry.
@@ -102,6 +102,11 @@ class OM::XML::Terminology
102
102
  return current_term
103
103
  end
104
104
 
105
+ # Add additional terms into this terminology
106
+ def extend_terminology &block
107
+ yield self if block_given?
108
+ end
109
+
105
110
  def build
106
111
  terminology = OM::XML::Terminology.new(:schema=>@schema, :namespaces=>@namespaces)
107
112
  root_term_builders.each do |root_term_builder|
@@ -1,22 +1,28 @@
1
1
  desc "Task to execute builds on a Hudson Continuous Integration Server."
2
2
  task :hudson do
3
3
  Rake::Task["om:doc"].invoke
4
- Rake::Task["om:rcov"].invoke
5
- Rake::Task["om:rspec"].invoke
4
+ Rake::Task["coverage"].invoke
5
+ end
6
+
7
+
8
+ desc "Execute specs with coverage"
9
+ task :coverage do
10
+ # Put spec opts in a file named .rspec in root
11
+ ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : "ruby"
12
+ ENV['COVERAGE'] = 'true' unless ruby_engine == 'jruby'
13
+
14
+
15
+ Rake::Task['om:rspec'].invoke
6
16
  end
7
17
 
8
18
  namespace :om do
9
19
 
10
20
  require 'rspec/core/rake_task'
11
21
  RSpec::Core::RakeTask.new(:rspec) do |spec|
12
- spec.pattern = FileList['spec/**/*_spec.rb']
13
- spec.pattern += FileList['spec/*_spec.rb']
14
- end
15
-
16
- RSpec::Core::RakeTask.new(:rcov) do |spec|
17
- spec.pattern = FileList['spec/**/*_spec.rb']
18
- spec.pattern += FileList['spec/*_spec.rb']
19
- spec.rcov = true
22
+ if ENV['COVERAGE'] and RUBY_VERSION =~ /^1.8/
23
+ spec.rcov = true
24
+ spec.rcov_opts = %w{-I../../app -I../../lib --exclude spec\/*,gems\/*,ruby\/* --aggregate coverage.data}
25
+ end
20
26
  end
21
27
 
22
28
  # Use yard to build docs
data/om.gemspec CHANGED
@@ -15,6 +15,7 @@ Gem::Specification.new do |s|
15
15
  s.add_dependency('nokogiri', ">= 1.4.2")
16
16
  s.add_dependency('mediashelf-loggable')
17
17
  s.add_development_dependency "rspec", "~> 2.0"
18
+ s.add_development_dependency "rake"
18
19
  s.add_development_dependency "mocha", ">= 0.9.8"
19
20
  s.add_development_dependency "equivalent-xml", ">= 0.2.4"
20
21
 
@@ -37,6 +37,13 @@
37
37
  </role>
38
38
  </name>
39
39
 
40
+ <name type="corporate">
41
+ <namePart>NSF</namePart>
42
+ <role>
43
+ <roleTerm authority="marcrelator" type="text">funder</roleTerm>
44
+ </role>
45
+ </name>
46
+
40
47
  <typeOfResource>text</typeOfResource>
41
48
  <genre authority="local">journal article</genre>
42
49
 
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe "use the root element as a member of the proxy address" do
4
+ before(:all) do
5
+ class BlahTerminology
6
+ include OM::XML::Document
7
+
8
+ set_terminology do |t|
9
+ t.root :path => 'root_element', :xmlns => "asdf"
10
+ t.relevant_container do
11
+ t.the_thing_we_want
12
+ end
13
+
14
+ t.the_thing_we_want :proxy => [:root_element, :relevant_container, :the_thing_we_want]
15
+ end
16
+ end
17
+ end
18
+
19
+ subject do
20
+ BlahTerminology.from_xml('<root_element xmlns="asdf">
21
+ <arbitrary_container_element>
22
+ <relevant_container>
23
+ <the_thing_we_want but="not really">1</the_thing_we_want>
24
+ </relevant_container>
25
+ </arbitrary_container_element>
26
+ <relevant_container>
27
+ <the_thing_we_want>2</the_thing_we_want>
28
+ </relevant_container>
29
+ </root_element>')
30
+ end
31
+
32
+ it "should pull out all occurences of the_thing_we_want in the relevant_container" do
33
+ subject.relevant_container.the_thing_we_want.should == ["1", "2"]
34
+ end
35
+
36
+ it "should only pull out the_thing_we_want at the root level" do
37
+ subject.the_thing_we_want.should == ["2"]
38
+ end
39
+ end
@@ -0,0 +1,91 @@
1
+ require 'spec_helper'
2
+
3
+ describe "element values" do
4
+ before(:all) do
5
+ class ElementValueTerminology
6
+ include OM::XML::Document
7
+
8
+ set_terminology do |t|
9
+ t.root(:path => "outer", :xmlns => nil)
10
+ t.elementA
11
+ t.elB(:path => "elementB")
12
+ t.elC(:path => "elementC")
13
+
14
+ t.elementC(:attributes=>{:animal=>"seagull"}, :namespace_prefix => nil)
15
+ t.here(:path=>"resource", :attributes=>{:type=>"ead"}, :namespace_prefix => nil)
16
+ t.there(:path=>"resource", :attributes=>{:type=>"nowhere"}, :namespace_prefix => nil)
17
+ t.elementD(:attributes=>{:animal=>:none}, :namespace_prefix => nil)
18
+ t.no_attrib(:path => "elementB", :attributes=>{:animal=>:none}, :namespace_prefix => nil)
19
+
20
+ t.elementB {
21
+ t.my_attr(:path => {:attribute=>"animal"}, :namespace_prefix => nil)
22
+ }
23
+ t.alternate(:path => "elementB/@animal", :namespace_prefix => nil)
24
+ t.another(:proxy=>[:elementB, :my_attr])
25
+ t.animal_attrib(:path => {:attribute=>"animal"}, :namespace_prefix => nil)
26
+ end
27
+ end
28
+ end
29
+
30
+ subject do
31
+ ElementValueTerminology.from_xml <<-EOF
32
+ <outer outerId="hypatia:outer" type="outer type">
33
+ <elementA>valA</elementA>
34
+ <elementB>valB1</elementB>
35
+ <elementB animal="vole">valB2</elementB>
36
+ <elementC type="c type" animal="seagull">valC</elementC>
37
+ <elementD >valD1</elementC>
38
+ <elementD animal="seagull">valD2</elementC>
39
+ <resource type="ead" id="coll.ead" objectId="hypatia:ead_file_asset_fixture">
40
+ <file id="my_ead.xml" format="XML" mimetype="text/xml" size="47570">
41
+ <checksum type="md5">123</checksum>
42
+ <checksum type="sha1">456</checksum>
43
+ </file>
44
+ </resource>
45
+ <resource type="image" id="image" objectId="hypatia:coll_img_file_asset_fixture">
46
+ <file id="my_image.jpg" format="JPG" mimetype="image/jpeg" size="302080">
47
+ <checksum type="md5">789</checksum>
48
+ <checksum type="sha1">666</checksum>
49
+ </file>
50
+ </resource>
51
+ </outer>
52
+ EOF
53
+ end
54
+
55
+ it "should handle single-element terms correctly" do
56
+ subject.elementA.should == ["valA"]
57
+ end
58
+
59
+ it "should handle term paths" do
60
+ subject.elC.should == ["valC"]
61
+ end
62
+
63
+ it "should handle multiple-element, terms with paths correctly" do
64
+ subject.elB.should == ["valB1", "valB2"]
65
+ end
66
+
67
+ it "should handle terms that require specific attributes" do
68
+ subject.elementC.should == ["valC"]
69
+ end
70
+
71
+ it "should handle" do
72
+ subject.here.length.should == 1
73
+ subject.here.first.split(/\W/).should include('123', '456')
74
+ end
75
+
76
+ it "should handle missing terms" do
77
+ subject.there.should be_empty
78
+ end
79
+
80
+ it "should handle element value given the absence of a specific attribute" do
81
+ subject.elementD.should == ["valD1"]
82
+ subject.no_attrib.should == ["valB1"]
83
+ end
84
+
85
+ it "should handle OM terms for an attribute value" do
86
+ subject.elementB.my_attr.should == ["vole"]
87
+ subject.alternate.should == ["vole"]
88
+ subject.another.should == ["vole"]
89
+ subject.animal_attrib.should include("vole", "seagull")
90
+ end
91
+ end
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+
3
+ describe "an example with :proxy and :ref" do
4
+ before(:all) do
5
+ class ExampleProxyAndRefTerminology
6
+ include OM::XML::Document
7
+
8
+ set_terminology do |t|
9
+ t.root(:path => "outer", :xmlns => '', :namespace_prefix => nil)
10
+
11
+ t.resource(:namespace_prefix => nil) {
12
+ t.fedora_pid(:path=>{:attribute=>"objectId"}, :namespace_prefix => nil)
13
+ t.file(:ref=>[:file], :namespace_prefix => nil, :namespace_prefix => nil)
14
+ }
15
+ t.file(:namespace_prefix => nil) {
16
+ t.ds_label(:path=>{:attribute=>"id"}, :namespace_prefix => nil)
17
+ t.size(:path=>{:attribute=>"size"}, :namespace_prefix => nil)
18
+ t.md5(:path=>"checksum", :attributes=>{:type=>"md5"}, :namespace_prefix => nil)
19
+ t.sha1(:path=>"checksum", :attributes=>{:type=>"sha1"}, :namespace_prefix => nil)
20
+ }
21
+ # really want ead where the type is ead and the file format is XML and the file mimetype is text/xml (and the file id is (?coll_ead.xml ... can be whatever the label of the DS is in the FileAsset object))
22
+ t.ead(:ref=>:resource, :attributes=>{:type=>"ead"})
23
+ t.image(:ref=>:resource, :attributes=>{:type=>"image"})
24
+
25
+ t.ead_fedora_pid(:proxy=>[:ead, :fedora_pid])
26
+ t.ead_ds_label(:proxy=>[:ead, :file, :ds_label])
27
+ t.ead_size(:proxy=>[:ead, :file, :size])
28
+ t.ead_md5(:proxy=>[:ead, :file, :md5])
29
+ t.ead_sha1(:proxy=>[:ead, :file, :sha1])
30
+
31
+ t.image_fedora_pid(:proxy=>[:image, :fedora_pid])
32
+ t.image_ds_label(:proxy=>[:image, :file, :ds_label])
33
+ t.image_size(:proxy=>[:image, :file, :size])
34
+ t.image_md5(:proxy=>[:image, :file, :md5])
35
+ t.image_sha1(:proxy=>[:image, :file, :sha1])
36
+ end
37
+ end
38
+ end
39
+
40
+ subject do
41
+ ExampleProxyAndRefTerminology.from_xml <<-EOF
42
+ <outer outerId="hypatia:outer" type="outer type">
43
+ <resource type="ead" id="coll.ead" objectId="hypatia:ead_file_asset_fixture">
44
+ <file id="my_ead.xml" format="XML" mimetype="text/xml" size="47570">
45
+ <checksum type="md5">123</checksum>
46
+ <checksum type="sha1">456</checksum>
47
+ </file>
48
+ </resource>
49
+ <resource type="image" id="image" objectId="hypatia:coll_img_file_asset_fixture">
50
+ <file id="my_image.jpg" format="JPG" mimetype="image/jpeg" size="302080">
51
+ <checksum type="md5">789</checksum>
52
+ <checksum type="sha1">666</checksum>
53
+ </file>
54
+ </resource>
55
+ </outer>
56
+
57
+ EOF
58
+ end
59
+
60
+ describe "image" do
61
+ it "should have the right proxy terms" do
62
+ subject.ead_fedora_pid.should include "hypatia:ead_file_asset_fixture"
63
+ subject.ead_ds_label.should include "my_ead.xml"
64
+ subject.ead_size.should include "47570"
65
+ subject.ead_md5.should include "123"
66
+ subject.ead_sha1.should include "456"
67
+ end
68
+ end
69
+
70
+ describe "ead" do
71
+ it "should have the right proxy terms" do
72
+ subject.image_fedora_pid.should include "hypatia:coll_img_file_asset_fixture"
73
+ subject.image_ds_label.should include "my_image.jpg"
74
+ subject.image_size.should include "302080"
75
+ subject.image_md5.should include "789"
76
+ subject.image_sha1.should include "666"
77
+ end
78
+
79
+ end
80
+
81
+ end
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+ require "om/samples"
3
+
4
+ describe "Rspec tests for QUERYING_DOCUMENTS.textile" do
5
+
6
+ before(:all) do
7
+ @xml_file = "mods_articles/hydrangea_article1.xml"
8
+ @doc = OM::Samples::ModsArticle.from_xml(fixture @xml_file) { |conf|
9
+ conf.default_xml.noblanks
10
+ }
11
+ @term = OM::Samples::ModsArticle.terminology
12
+ end
13
+
14
+ it "xpath_for()" do
15
+ @term.xpath_for(:name).should ==
16
+ '//oxns:name'
17
+ @term.xpath_for(:person).should ==
18
+ '//oxns:name[@type="personal"]'
19
+ @term.xpath_for(:organization).should ==
20
+ '//oxns:name[@type="corporate"]'
21
+ @term.xpath_for(:person, :first_name).should ==
22
+ '//oxns:name[@type="personal"]/oxns:namePart[@type="given"]'
23
+ @term.xpath_for(:journal, :issue, :pages, :start).should ==
24
+ '//oxns:relatedItem[@type="host"]/oxns:part/oxns:extent[@unit="pages"]/oxns:start'
25
+ end
26
+
27
+ it "term_values()" do
28
+ @doc.term_values(:person, :first_name).should == ["GIVEN NAMES", "Siddartha"]
29
+ @doc.term_values(:person, :last_name).should == ["FAMILY NAME", "Gautama"]
30
+ @doc.term_values(:organization, :namePart).should == ['NSF']
31
+ @doc.term_values(:journal, :issue, :pages, :start).should == ['195']
32
+ @doc.term_values(:journal, :title_info, :main_title).should == ["TITLE OF HOST JOURNAL"]
33
+ end
34
+
35
+ it "xpath_for(): relative vs absolute" do
36
+ xp_rel = '//oxns:titleInfo/oxns:title'
37
+ xp_abs = '//oxns:mods/oxns:titleInfo/oxns:title'
38
+ @term.xpath_for( :title_info, :main_title).should == xp_rel
39
+ @term.xpath_for(:mods, :title_info, :main_title).should == xp_abs
40
+ end
41
+
42
+ it "term_values(): relative vs absolute" do
43
+ exp = [
44
+ "ARTICLE TITLE HYDRANGEA ARTICLE 1",
45
+ "Artikkelin otsikko Hydrangea artiklan 1",
46
+ "TITLE OF HOST JOURNAL",
47
+ ]
48
+ xp_abs = '//oxns:mods/oxns:titleInfo/oxns:title'
49
+ @doc.term_values( :title_info, :main_title).should == exp
50
+ @doc.term_values(:mods, :title_info, :main_title).should == exp[0..1]
51
+ end
52
+
53
+ it "find_by_terms()" do
54
+ exp_xml_role = '<role><roleTerm authority="marcrelator" type="text">funder</roleTerm></role>'
55
+ exp_xml_start = '<start>195</start>'
56
+ @doc.find_by_terms(:organization, :role).class.should == Nokogiri::XML::NodeSet
57
+ @doc.find_by_terms(:organization, :role).to_xml.should be_equivalent_to exp_xml_role
58
+ @doc.find_by_terms(:journal, :issue, :pages, :start).to_xml.should == exp_xml_start
59
+ end
60
+
61
+ it "find_by_terms() error" do
62
+ exp_err = OM::XML::Terminology::BadPointerError
63
+ expect { @doc.find_by_terms :journal, :issue, :BLAH, :start }.to raise_error exp_err
64
+ end
65
+
66
+ it "proxies" do
67
+ @term.xpath_for(:title).should ==
68
+ '//oxns:titleInfo/oxns:title'
69
+ @term.xpath_for(:journal_title)
70
+ '//oxns:relatedItem[@type="host"]/oxns:titleInfo/oxns:title'
71
+ end
72
+
73
+ end