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 +10 -5
- data/lib/nom/xml/decorators/terminology.rb +11 -3
- data/lib/nom/xml/nokogiri_extension.rb +1 -1
- data/lib/nom/xml/term.rb +4 -0
- data/lib/nom/xml/terminology.rb +7 -1
- data/lib/nom/xml/version.rb +1 -1
- data/spec/examples/mods_example_spec.rb +93 -0
- data/spec/examples/template_registry_example_spec.rb +1 -1
- data/spec/fixtures/mods_document.xml +106 -0
- data/spec/lib/terminology_decorator_spec.rb +2 -2
- metadata +8 -4
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
|
-
|
13
|
-
|
14
|
-
[
|
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 |
|
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
|
data/lib/nom/xml/term.rb
CHANGED
data/lib/nom/xml/terminology.rb
CHANGED
@@ -1,12 +1,18 @@
|
|
1
1
|
module Nom::XML
|
2
2
|
class Terminology < Term
|
3
|
-
|
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
|
data/lib/nom/xml/version.rb
CHANGED
@@ -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
|
@@ -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.
|
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.
|
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
|
+
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-
|
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:
|
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:
|
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
|