nom-xml 0.0.4 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -2,16 +2,18 @@
2
2
 
3
3
  [![Build Status](https://secure.travis-ci.org/cbeer/nom.png)](http://travis-ci.org/cbeer/nom)
4
4
 
5
- A library to help you tame sprawling XML schemas
5
+ A library to help you tame sprawling XML schemas.
6
6
 
7
- NOM allows you to define a “terminology” to ease translation between XML and ruby objects – you can query the xml for Nodes or node values without ever writing a line of XPath.
7
+ NOM allows you to define a “terminology” to ease translation between XML and ruby objects – you can query the xml for Nodes or node values without ever writing a line of XPath. NOM is built on top of [nokogiri](http://nokogiri.org) decorators, which means you can mix-and-match NOM accessors with nokogiri xpaths, xml manipulation, and traversing and it will just work.
8
8
 
9
9
 
10
10
  Some Handy Links
11
11
  ----------------
12
- [API](http://rubydoc.info/github/cbeer/nom) - A reference to NOM's classes
13
- [#projecthydra](http://webchat.freenode.net/?channels=#projecthydra) on irc.freenode.net
14
- [Project Hydra Google Group](http://groups.google.com/group/hydra-tech) - community mailing list and forum
12
+ Here are some resources to help you learn more about nom-xml:
13
+
14
+ - [API](http://rubydoc.info/github/cbeer/nom) - A reference to NOM's classes
15
+ - [#projecthydra](http://webchat.freenode.net/?channels=#projecthydra) on irc.freenode.net
16
+ - [Project Hydra Google Group](http://groups.google.com/group/hydra-tech) - community mailing list and forum
15
17
 
16
18
  An Example
17
19
  ---------------
@@ -45,6 +47,9 @@ An Example
45
47
  ```
46
48
 
47
49
  ```ruby
50
+ require 'nom/xml'
51
+
52
+ # load the source document as normal
48
53
  doc = Nokogiri::XML my_source_document
49
54
 
50
55
  doc.set_terminology do |t|
@@ -24,8 +24,9 @@ module Nom::XML::Decorators::Terminology
24
24
  self.xpath(xpath, self.document.terminology_namespaces)
25
25
  end
26
26
 
27
+
27
28
  m = t.options[:accessor]
28
- case
29
+ return_value = case
29
30
  when m.nil?
30
31
  result
31
32
  when m.is_a?(Symbol)
@@ -35,6 +36,13 @@ module Nom::XML::Decorators::Terminology
35
36
  else
36
37
  raise "Unknown accessor class: #{m.class}"
37
38
  end
39
+
40
+
41
+ if return_value and (t.options[:single] or (return_value.length == 1 and return_value.first.is_a? Nokogiri::XML::Attr))
42
+ return return_value.first
43
+ end
44
+
45
+ return return_value
38
46
  end
39
47
  end
40
48
 
@@ -48,7 +56,7 @@ module Nom::XML::Decorators::Terminology
48
56
 
49
57
  self.parent.term_accessors.select do |k,term|
50
58
  self.parent.xpath(term.local_xpath, self.document.terminology_namespaces).include? self
51
- end
59
+ end.map { |k, term| term }
52
60
  end
53
61
 
54
62
  protected
@@ -76,7 +84,7 @@ module Nom::XML::Decorators::Terminology
76
84
  def child_terms
77
85
  h = {}
78
86
 
79
- terms.each do |k,term|
87
+ terms.each do |term|
80
88
 
81
89
  term.terms.each do |k1, v1|
82
90
  h[k1] = v1
@@ -22,7 +22,7 @@ module Nom::XML
22
22
 
23
23
  def set_terminology options = {}, &block
24
24
  @terminology_namespaces = options[:namespaces]
25
- @terminology = Nom::XML::Terminology.new &block
25
+ @terminology = Nom::XML::Terminology.new(options, &block)
26
26
  end
27
27
 
28
28
  def terminology_namespaces
@@ -61,6 +61,10 @@ module Nom::XML
61
61
  terms.key? term
62
62
  end
63
63
 
64
+ def flatten
65
+ [self, terms.map { |k,v| v.flatten }].flatten
66
+ end
67
+
64
68
  protected
65
69
  def add_term method, options = {}, *args, &block
66
70
  terms[method] = Term.new(self, method, options, *args, &block)
@@ -1,12 +1,18 @@
1
1
  module Nom::XML
2
2
  class Terminology < Term
3
- def initialize *args, &block
3
+
4
+ def initialize options = {}, *args, &block
4
5
  @terms = {}
6
+ @options = options || {}
5
7
  in_edit_context do
6
8
  yield(self) if block_given?
7
9
  end
8
10
  end
9
11
 
12
+ def namespaces
13
+ options[:namespaces] || {}
14
+ end
15
+
10
16
  def xpath
11
17
  nil
12
18
  end
@@ -1,5 +1,5 @@
1
1
  module Nom
2
2
  module XML
3
- VERSION = '0.0.4'
3
+ VERSION = '0.0.5'
4
4
  end
5
5
  end
@@ -0,0 +1,93 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Namespaces example" do
4
+
5
+ let(:file) { File.open(File.join(File.dirname(__FILE__), '..', 'fixtures', 'mods_document.xml'), 'r') }
6
+ let(:xml) { Nokogiri::XML(file) }
7
+
8
+ subject {
9
+
10
+ xml.set_terminology(:namespaces => { 'mods' => 'http://www.loc.gov/mods/v3'}) do |t|
11
+
12
+ t.author :path => '//mods:name' do |n|
13
+ n.valueURI :path => '@valueURI'
14
+ n.namePart :path => 'mods:namePart', :single => true, :index_as => [:type_1]
15
+ end
16
+
17
+ t.corporate_authors :path => '//mods:name[@type="corporate"]'
18
+ t.personal_authors :path => 'mods:name[@type="personal"]' do |n|
19
+ n.roleTerm :path => 'mods:role/mods:roleTerm', :index_as => [:type_1]
20
+
21
+ n.name_role_pair :path => '.', :accessor => lambda { |node| node.roleTerm.text + ": " + node.namePart.text }
22
+
23
+ # n.name_object :path => '.', :accessor => lambda { |node| ModsName.new node }
24
+ end
25
+
26
+ t.language :path => 'mods:language' do |n|
27
+ n.value :path => 'mods:languageTerm', :accessor => :text
28
+ end
29
+
30
+ end
31
+
32
+ xml.nom!
33
+
34
+ xml
35
+ }
36
+
37
+ it "should return nodesets by default" do
38
+ subject.personal_authors.should be_a_kind_of(Nokogiri::XML::NodeSet)
39
+ end
40
+
41
+ it "should return single elements on demand" do
42
+ subject.personal_authors.first.namePart.should be_a_kind_of(Nokogiri::XML::Element)
43
+ end
44
+
45
+ it "should return attributes as single-valued" do
46
+ subject.personal_authors.first.valueURI.should be_a_kind_of(Nokogiri::XML::Attr)
47
+ end
48
+
49
+ it "should share terms over matched nodes" do
50
+ subject.personal_authors.first.namePart.text.should == "Alterman, Eric"
51
+ end
52
+
53
+ it "should return single elements out of nodesets correctly" do
54
+ subject.personal_authors.namePart.should be_a_kind_of(Nokogiri::XML::NodeSet)
55
+ end
56
+
57
+ it "should create enumerable objects" do
58
+ subject.personal_authors.should respond_to(:each)
59
+ subject.personal_authors.should have(1).node
60
+ end
61
+
62
+ it "should provide accessors" do
63
+ eric =subject.personal_authors.first
64
+
65
+ eric.namePart.text.should == "Alterman, Eric"
66
+ eric.roleTerm.text.should == "creator"
67
+ end
68
+
69
+ it "should let you mix and match xpaths and nom accessors" do
70
+ subject.language.value.should include('eng')
71
+ subject.xpath('//mods:language', 'mods' => 'http://www.loc.gov/mods/v3').value.should include('eng')
72
+ end
73
+
74
+ it "should work with attributes" do
75
+ eric =subject.personal_authors.first
76
+ eric.valueURI.to_s.should == 'http://id.loc.gov/authorities/names/n92101908'
77
+ end
78
+
79
+ it "should allow you to access a term from the node" do
80
+ subject.personal_authors.namePart.terms.map { |term|term.options[:index_as] }.flatten.should include(:type_1)
81
+ end
82
+
83
+ it "should let you go from a terminology to nodes" do
84
+ subject.terminology.flatten.length.should == 10
85
+
86
+ subject.terminology.flatten.select { |x| x.options[:index_as] }.length.should == 2
87
+
88
+ subject.terminology.flatten.select { |x| x.options[:index_as] }.each do |term|
89
+ subject.xpath(term.xpath, subject.terminology.namespaces)
90
+ end
91
+ end
92
+
93
+ end
@@ -23,7 +23,7 @@ describe "Template Registry example" do
23
23
 
24
24
  xml.set_terminology do |t|
25
25
  t.a
26
- t.b
26
+ t.b :template => :asdf
27
27
  t.b_ref :path => 'b'
28
28
 
29
29
  t.c do |c|
@@ -0,0 +1,106 @@
1
+
2
+ <?xml version='1.0' encoding='UTF-8' ?>
3
+ <mods xmlns:xlink="http://www.w3.org/1999/xlink" version="3.4"
4
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.loc.gov/mods/v3"
5
+ xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-4.xsd">
6
+
7
+ <titleInfo>
8
+ <title>Sound and fury</title>
9
+ <subTitle>the making of the punditocracy</subTitle>
10
+ </titleInfo>
11
+
12
+ <name type="personal" authorityURI="http://id.loc.gov/authorities/names"
13
+ valueURI="http://id.loc.gov/authorities/names/n92101908">
14
+ <namePart>Alterman, Eric</namePart>
15
+ <role>
16
+ <roleTerm type="text">creator</roleTerm>
17
+ </role>
18
+ </name>
19
+
20
+ <typeOfResource>text</typeOfResource>
21
+
22
+ <genre authority="marcgt">bibliography</genre>
23
+
24
+ <originInfo>
25
+ <place>
26
+ <placeTerm authority="marccountry" type="code"
27
+ authorityURI="http://id.loc.gov/vocabulary/countries"
28
+ valueURI="http://id.loc.gov/vocabulary/countries/nyu">nyu</placeTerm>
29
+ </place>
30
+ <place>
31
+ <placeTerm type="text">Ithaca, N.Y</placeTerm>
32
+ </place>
33
+ <publisher>Cornell University Press</publisher>
34
+ <dateIssued>c1999</dateIssued>
35
+ <dateIssued encoding="marc">1999</dateIssued>
36
+ <issuance>monographic</issuance>
37
+ </originInfo>
38
+
39
+ <language>
40
+ <languageTerm authority="iso639-2b" type="code"
41
+ authorityURI="http://id.loc.gov/vocabulary/iso639-2"
42
+ valueURI="http://id.loc.gov/vocabulary/iso639-2/eng">eng</languageTerm>
43
+ </language>
44
+
45
+ <physicalDescription>
46
+ <form authority="marcform">print</form>
47
+ <extent>vii, 322 p. ; 23 cm.</extent>
48
+ </physicalDescription>
49
+
50
+ <note type="statement of responsibility">Eric Alterman.</note>
51
+ <note>Includes bibliographical references (p. 291-312) and index.</note>
52
+
53
+ <subject authority="lcsh" authorityURI="http://id.loc.gov/authorities/subjects">
54
+ <topic valueURI="http://id.loc.gov/authorities/subjects/sh85070736">Journalism</topic>
55
+ <topic valueURI="http://id.loc.gov/authorities/subjects/sh00005651">Political aspects</topic>
56
+ <geographic valueURI="http://id.loc.gov/authorities/names/n78095330">United States</geographic>
57
+ </subject>
58
+
59
+ <subject authority="lcsh" authorityURI="http://id.loc.gov/authorities/subjects">
60
+ <geographic valueURI="http://id.loc.gov/authorities/names/n78095330">United States</geographic>
61
+ <topic valueURI="http://id.loc.gov/authorities/subjects/sh2002011436">Politics and
62
+ government</topic>
63
+ <temporal valueURI="http://id.loc.gov/authorities/subjects/sh2002012476">20th century</temporal>
64
+ </subject>
65
+
66
+ <subject authority="lcsh" authorityURI="http://id.loc.gov/authorities/subjects"
67
+ valueURI="http://id.loc.gov/authorities/subjects/sh2008107507">
68
+ <topic valueURI="http://id.loc.gov/authorities/subjects/sh85081863">Mass media</topic>
69
+ <topic valueURI="http://id.loc.gov/authorities/subjects/sh00005651">Political aspects</topic>
70
+ <geographic valueURI="http://id.loc.gov/authorities/names/n78095330">United States</geographic>
71
+ </subject>
72
+
73
+ <subject authority="lcsh" authorityURI="http://id.loc.gov/authorities/subjects"
74
+ valueURI="http://id.loc.gov/authorities/subjects/sh2010115992">
75
+ <topic valueURI="http://id.loc.gov/authorities/subjects/sh85133490">Television and
76
+ politics</topic>
77
+ <geographic valueURI="http://id.loc.gov/authorities/names/n78095330">United States</geographic>
78
+ </subject>
79
+
80
+ <subject authority="lcsh" authorityURI="http://id.loc.gov/authorities/subjects"
81
+ valueURI="http://id.loc.gov/authorities/subjects/sh2008109555">
82
+ <topic valueURI="http://id.loc.gov/authorities/subjects/sh85106514">Press and politics</topic>
83
+ <geographic valueURI="http://id.loc.gov/authorities/names/n78095330">United States</geographic>
84
+ </subject>
85
+
86
+ <subject authority="lcsh" authorityURI="http://id.loc.gov/authorities/subjects" valueURI="http://id.loc.gov/authorities/subjects/sh2010115993.html">
87
+ <topic valueURI="http://id.loc.gov/authorities/subjects/sh2006004518.html">Television talk shows</topic>
88
+ <geographic valueURI="http://id.loc.gov/authorities/names/n78095330">United States</geographic>
89
+ </subject>
90
+
91
+ <classification authority="lcc">PN4888.P6 A48 1999</classification>
92
+ <classification edition="21" authority="ddc">071/.3</classification>
93
+
94
+ <identifier type="isbn">0801486394 (pbk. : acid-free, recycled paper)</identifier>
95
+ <identifier type="lccn">99042030</identifier>
96
+
97
+ <recordInfo>
98
+ <descriptionStandard>aacr</descriptionStandard>
99
+ <recordContentSource>DLC</recordContentSource>
100
+ <recordCreationDate encoding="marc">990730</recordCreationDate>
101
+ <recordChangeDate encoding="iso8601">20000406144503.0</recordChangeDate>
102
+ <recordIdentifier>11761548</recordIdentifier>
103
+ <recordOrigin>Converted from MARCXML to MODS version 3.4 using MARC21slim2MODS3-4.xsl (Revision
104
+ 1.74), valueURIs and authorityURIs added by hand 20120123</recordOrigin>
105
+ </recordInfo>
106
+ </mods>
@@ -114,7 +114,7 @@ describe "Nutrition" do
114
114
  end
115
115
 
116
116
  it "should find the right term" do
117
- subject.terms.keys.should include(:a)
117
+ subject.terms.map { |x| x.name }.should include(:a)
118
118
  end
119
119
  end
120
120
 
@@ -126,7 +126,7 @@ describe "Nutrition" do
126
126
  end
127
127
 
128
128
  it "should find the right terms" do
129
- subject.terms.keys.should include(:b, :b_ref)
129
+ subject.terms.map { |x| x.name }.should include(:b, :b_ref)
130
130
  end
131
131
  end
132
132
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nom-xml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-14 00:00:00.000000000 Z
12
+ date: 2012-11-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -147,9 +147,11 @@ files:
147
147
  - lib/nom/xml/terminology.rb
148
148
  - lib/nom/xml/version.rb
149
149
  - nom.gemspec
150
+ - spec/examples/mods_example_spec.rb
150
151
  - spec/examples/namespaced_example_spec.rb
151
152
  - spec/examples/nutrition_example_spec.rb
152
153
  - spec/examples/template_registry_example_spec.rb
154
+ - spec/fixtures/mods_document.xml
153
155
  - spec/fixtures/nutrition.xml
154
156
  - spec/fixtures/xml_namespaces.xml
155
157
  - spec/lib/nodeset_decorator_spec.rb
@@ -172,7 +174,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
172
174
  version: '0'
173
175
  segments:
174
176
  - 0
175
- hash: 1606554633515477206
177
+ hash: 4581122629078918118
176
178
  required_rubygems_version: !ruby/object:Gem::Requirement
177
179
  none: false
178
180
  requirements:
@@ -181,7 +183,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
181
183
  version: '0'
182
184
  segments:
183
185
  - 0
184
- hash: 1606554633515477206
186
+ hash: 4581122629078918118
185
187
  requirements: []
186
188
  rubyforge_project:
187
189
  rubygems_version: 1.8.23
@@ -189,9 +191,11 @@ signing_key:
189
191
  specification_version: 3
190
192
  summary: asdf
191
193
  test_files:
194
+ - spec/examples/mods_example_spec.rb
192
195
  - spec/examples/namespaced_example_spec.rb
193
196
  - spec/examples/nutrition_example_spec.rb
194
197
  - spec/examples/template_registry_example_spec.rb
198
+ - spec/fixtures/mods_document.xml
195
199
  - spec/fixtures/nutrition.xml
196
200
  - spec/fixtures/xml_namespaces.xml
197
201
  - spec/lib/nodeset_decorator_spec.rb