nom-xml 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
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