milkfarm-onix 0.7.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. data/CHANGELOG +136 -0
  2. data/README.markdown +40 -0
  3. data/TODO +14 -0
  4. data/dtd/2.1r3/iso-amsa.ent +173 -0
  5. data/dtd/2.1r3/iso-amsb.ent +146 -0
  6. data/dtd/2.1r3/iso-amsc.ent +49 -0
  7. data/dtd/2.1r3/iso-amsn.ent +117 -0
  8. data/dtd/2.1r3/iso-amso.ent +77 -0
  9. data/dtd/2.1r3/iso-amsr.ent +205 -0
  10. data/dtd/2.1r3/iso-box.ent +67 -0
  11. data/dtd/2.1r3/iso-cyr1.ent +94 -0
  12. data/dtd/2.1r3/iso-cyr2.ent +53 -0
  13. data/dtd/2.1r3/iso-dia.ent +41 -0
  14. data/dtd/2.1r3/iso-grk3.ent +70 -0
  15. data/dtd/2.1r3/iso-lat1.ent +89 -0
  16. data/dtd/2.1r3/iso-lat2.ent +148 -0
  17. data/dtd/2.1r3/iso-mfrk.ent +79 -0
  18. data/dtd/2.1r3/iso-mopf.ent +53 -0
  19. data/dtd/2.1r3/iso-mscr.ent +79 -0
  20. data/dtd/2.1r3/iso-num.ent +103 -0
  21. data/dtd/2.1r3/iso-num.old.ent +103 -0
  22. data/dtd/2.1r3/iso-pub.ent +110 -0
  23. data/dtd/2.1r3/iso-tech.ent +183 -0
  24. data/dtd/2.1r3/onix-international.dtd +1012 -0
  25. data/dtd/2.1r3/onix-xhtml.elt +672 -0
  26. data/dtd/2.1r3/reference.elt +4758 -0
  27. data/dtd/2.1r3/xhtml-special.ent +79 -0
  28. data/dtd/2.1r3/xhtml-symbol.ent +242 -0
  29. data/lib/onix/addressee_identifier.rb +12 -0
  30. data/lib/onix/apa_product.rb +731 -0
  31. data/lib/onix/audience_range.rb +26 -0
  32. data/lib/onix/common.rb +26 -0
  33. data/lib/onix/contributor.rb +27 -0
  34. data/lib/onix/header.rb +46 -0
  35. data/lib/onix/imprint.rb +15 -0
  36. data/lib/onix/language.rb +14 -0
  37. data/lib/onix/lists/audience_code.rb +17 -0
  38. data/lib/onix/lists/country_code.rb +257 -0
  39. data/lib/onix/lists/language_code.rb +498 -0
  40. data/lib/onix/lists/language_role.rb +18 -0
  41. data/lib/onix/lists/notification_type.rb +19 -0
  42. data/lib/onix/lists/product_availability.rb +32 -0
  43. data/lib/onix/lists/product_form.rb +99 -0
  44. data/lib/onix/lists/product_form_detail.rb +157 -0
  45. data/lib/onix/market_representation.rb +19 -0
  46. data/lib/onix/measure.rb +14 -0
  47. data/lib/onix/media_file.rb +16 -0
  48. data/lib/onix/normaliser.rb +187 -0
  49. data/lib/onix/other_text.rb +17 -0
  50. data/lib/onix/price.rb +21 -0
  51. data/lib/onix/product.rb +73 -0
  52. data/lib/onix/product_identifier.rb +13 -0
  53. data/lib/onix/publisher.rb +16 -0
  54. data/lib/onix/reader.rb +187 -0
  55. data/lib/onix/sales_restriction.rb +12 -0
  56. data/lib/onix/sender_identifier.rb +14 -0
  57. data/lib/onix/series.rb +57 -0
  58. data/lib/onix/series_identifier.rb +13 -0
  59. data/lib/onix/simple_product.rb +47 -0
  60. data/lib/onix/sl_product.rb +131 -0
  61. data/lib/onix/stock.rb +15 -0
  62. data/lib/onix/subject.rb +16 -0
  63. data/lib/onix/supply_detail.rb +32 -0
  64. data/lib/onix/title.rb +17 -0
  65. data/lib/onix/website.rb +14 -0
  66. data/lib/onix/writer.rb +86 -0
  67. data/lib/onix.rb +114 -0
  68. data/spec/apa_product_spec.rb +59 -0
  69. data/spec/audience_range_spec.rb +46 -0
  70. data/spec/contributor_spec.rb +42 -0
  71. data/spec/header_spec.rb +123 -0
  72. data/spec/imprint_spec.rb +39 -0
  73. data/spec/language_spec.rb +42 -0
  74. data/spec/market_representation_spec.rb +41 -0
  75. data/spec/measure_spec.rb +43 -0
  76. data/spec/media_file_spec.rb +42 -0
  77. data/spec/normaliser_spec.rb +125 -0
  78. data/spec/other_text_spec.rb +40 -0
  79. data/spec/price_spec.rb +40 -0
  80. data/spec/product_identifier_spec.rb +40 -0
  81. data/spec/product_spec.rb +96 -0
  82. data/spec/publisher_spec.rb +38 -0
  83. data/spec/reader_spec.rb +131 -0
  84. data/spec/sales_restriction_spec.rb +35 -0
  85. data/spec/sender_identifier.rb +40 -0
  86. data/spec/series_identifier_spec.rb +38 -0
  87. data/spec/series_spec.rb +34 -0
  88. data/spec/sl_product_spec.rb +48 -0
  89. data/spec/stock_spec.rb +44 -0
  90. data/spec/subject_spec.rb +40 -0
  91. data/spec/supply_detail_spec.rb +53 -0
  92. data/spec/title_spec.rb +43 -0
  93. data/spec/website_spec.rb +41 -0
  94. data/spec/writer_spec.rb +81 -0
  95. data/support/entities.txt +1499 -0
  96. data/support/extract.rb +25 -0
  97. data/support/switch-onix-2.1-short-to-reference.xsl +23 -0
  98. data/support/switch-onix-tagnames-1.1.xsl +25 -0
  99. data/support/switch-onix-tagnames-2.0.xsl +37 -0
  100. metadata +209 -0
@@ -0,0 +1,187 @@
1
+ # coding: utf-8
2
+
3
+ require 'stringio'
4
+
5
+ module ONIX
6
+
7
+ # This is the primary class for reading data from an ONIX file, and there's
8
+ # really not much to it
9
+ #
10
+ # Each file should contain a single header, and 1 or more products:
11
+ #
12
+ # reader = ONIX::Reader.new("somefile.xml")
13
+ #
14
+ # puts reader.header.inspect
15
+ #
16
+ # reader.each do |product|
17
+ # puts product.inspect
18
+ # end
19
+ #
20
+ # The header will be returned as an ONIX::Header object, and the product will
21
+ # be an ONIX::Product.
22
+ #
23
+ # The ONIX::Product class can be a bit of a hassle to work with, as data can be
24
+ # nested in it fairly deeply. To wrap all the products returned by the reader
25
+ # in a shim that provides simple accessor access to common attributes, pass the
26
+ # shim class as a second argument
27
+ #
28
+ # reader = ONIX::Reader.new("somefile.xml", ONIX::APAProduct)
29
+ #
30
+ # puts reader.header.inspect
31
+ #
32
+ # reader.each do |product|
33
+ # puts product.inspect
34
+ # end
35
+ #
36
+ # APAProduct stands for Australian Publishers Association and provides simple
37
+ # access to the ONIX attributes that are commonly used in the Australian market.
38
+ #
39
+ # As well as accessing the file header, there are handful of other read only
40
+ # attributes that might be useful
41
+ #
42
+ # reader = ONIX::Reader.new("somefile.xml", ONIX::APAProduct)
43
+ #
44
+ # puts reader.version
45
+ # puts reader.xml_lang
46
+ # puts reader.xml_version
47
+ # puts reader.encoding
48
+ #
49
+ # The version attribute is particuarly useful. There are multiple revisions of the
50
+ # ONIX spec, and you may need to handle the file differently based on what
51
+ # version it is.
52
+ #
53
+ class Reader
54
+ include Enumerable
55
+
56
+ attr_reader :header , :version, :xml_lang, :xml_version, :encoding
57
+
58
+ def initialize(input, product_klass = ::ONIX::Product)
59
+ if input.kind_of?(String)
60
+ @reader = LibXML::XML::Reader.file(input)
61
+ elsif input.kind_of?(IO)
62
+ @reader = LibXML::XML::Reader.io(input)
63
+ else
64
+ raise ArgumentError, "Unable to read from file or IO stream"
65
+ end
66
+
67
+ @product_klass = product_klass
68
+
69
+ @header = read_next
70
+
71
+ @xml_lang ||= @reader.xml_lang
72
+ @xml_version ||= @reader.xml_version.to_f
73
+ @encoding ||= encoding_const_to_name(@reader.encoding)
74
+ end
75
+
76
+ # Iterate over all the products in an ONIX file
77
+ #
78
+ def each(&block)
79
+ while obj = read_next
80
+ yield obj
81
+ end
82
+ end
83
+
84
+ def close
85
+ @reader.close if @reader
86
+ end
87
+
88
+ private
89
+
90
+ # Walk the ONIX file, and grab the next header or product fragment.
91
+ #
92
+ def read_next
93
+ while @reader.read
94
+
95
+ if @reader.node_type == LibXML::XML::Reader::TYPE_DOCUMENT_TYPE
96
+ # TODO restore ONIX version extraction. The following expand()
97
+ # call is triggering unpredictable behaviour in libxml-ruby
98
+ # 1.1.3 with libxml2 2.7.3. Sometimes segfaults, othertimes
99
+ # cryptic errors about the input file being truncated or
100
+ # incomplete
101
+ #uri = @reader.expand.to_s.dup
102
+ #m, major, minor, rev = *uri.match(/.+(\d)\.(\d)\/(\d*).*/)
103
+ #@version = [major.to_i, minor.to_i, rev.to_i]
104
+ elsif @reader.node_type == LibXML::XML::Reader::TYPE_ELEMENT
105
+ if @reader.name == "Header"
106
+ str = normalise_string_encoding(@reader.read_outer_xml.to_s.dup)
107
+ if str.size == 0
108
+ return ONIX::Header.new
109
+ else
110
+ return ONIX::Header.from_xml(str)
111
+ end
112
+ elsif @reader.name == "Product"
113
+ str = normalise_string_encoding(@reader.read_outer_xml.to_s.dup)
114
+ if str.size == 0
115
+ return @product_klass.new
116
+ else
117
+ return @product_klass.from_xml(str)
118
+ end
119
+ end
120
+ end
121
+ end
122
+
123
+ return nil
124
+ rescue LibXML::XML::Error => e
125
+ return nil
126
+ end
127
+
128
+ # XML::Reader seems to transparently convert all input data to utf-8, howver
129
+ # on Ruby 1.9 it fails to correctly set the encoding on the strings.
130
+ #
131
+ def normalise_string_encoding(str)
132
+ if RUBY_VERSION >= "1.9"
133
+ return str.dup.force_encoding("utf-8")
134
+ else
135
+ str
136
+ end
137
+ end
138
+
139
+ # simple mapping of encoding constants to a string
140
+ #
141
+ def encoding_const_to_name(const)
142
+ return nil if const.nil?
143
+ case const
144
+ when LibXML::XML::Encoding::UTF_8
145
+ "utf-8"
146
+ when LibXML::XML::Encoding::UTF_16LE
147
+ "utf-16le"
148
+ when LibXML::XML::Encoding::UTF_16BE
149
+ "utf-16be"
150
+ when LibXML::XML::Encoding::UCS_4LE
151
+ "ucs-4le"
152
+ when LibXML::XML::Encoding::UCS_4BE
153
+ "ucs-4be"
154
+ when LibXML::XML::Encoding::UCS_2
155
+ "ucs-2"
156
+ when LibXML::XML::Encoding::ISO_8859_1
157
+ "iso-8859-1"
158
+ when LibXML::XML::Encoding::ISO_8859_2
159
+ "iso-8859-2"
160
+ when LibXML::XML::Encoding::ISO_8859_3
161
+ "iso-8859-3"
162
+ when LibXML::XML::Encoding::ISO_8859_4
163
+ "iso-8859-4"
164
+ when LibXML::XML::Encoding::ISO_8859_5
165
+ "iso-8859-5"
166
+ when LibXML::XML::Encoding::ISO_8859_6
167
+ "iso-8859-6"
168
+ when LibXML::XML::Encoding::ISO_8859_7
169
+ "iso-8859-7"
170
+ when LibXML::XML::Encoding::ISO_8859_8
171
+ "iso-8859-8"
172
+ when LibXML::XML::Encoding::ISO_8859_9
173
+ "iso-8859-9"
174
+ when LibXML::XML::Encoding::ISO_2022_JP
175
+ "iso-2022-jp"
176
+ when LibXML::XML::Encoding::SHIFT_JIS
177
+ "shift-jis"
178
+ when LibXML::XML::Encoding::EUC_JP
179
+ "euc-jp"
180
+ when LibXML::XML::Encoding::ASCII
181
+ "ascii"
182
+ else
183
+ nil
184
+ end
185
+ end
186
+ end
187
+ end
@@ -0,0 +1,12 @@
1
+ # coding: utf-8
2
+
3
+ module ONIX
4
+ class SalesRestriction
5
+ include ROXML
6
+ include ONIX::Common
7
+
8
+ xml_name "SalesRestriction"
9
+
10
+ xml_accessor :sales_restriction_type, :from =>"SalesRestrictionType", :as => Fixnum, :to_xml => ONIX::Formatters.two_digit
11
+ end
12
+ end
@@ -0,0 +1,14 @@
1
+ # coding: utf-8
2
+
3
+ module ONIX
4
+ class SenderIdentifier
5
+ include ROXML
6
+ include ONIX::Common
7
+
8
+ xml_name "SenderIdentifier"
9
+
10
+ xml_accessor :sender_id_type, :from => "SenderIDType", :as => Fixnum, :to_xml => ONIX::Formatters.two_digit
11
+ xml_accessor :id_type_name, :from => "IDTypeName"
12
+ xml_accessor :id_value, :from => "IDValue"
13
+ end
14
+ end
@@ -0,0 +1,57 @@
1
+ # coding: utf-8
2
+
3
+ module ONIX
4
+ class Series
5
+ include ROXML
6
+ include ONIX::Common
7
+
8
+ xml_name "Series"
9
+
10
+ xml_accessor :series_identifiers, :from => "SeriesIdentifier", :as => [ONIX::SeriesIdentifier]
11
+ xml_accessor :title_of_series, :from => "TitleOfSeries"
12
+
13
+ def initialize
14
+ self.series_identifiers = []
15
+ end
16
+
17
+ # retrieve the proprietary series ID
18
+ def proprietary_series_id
19
+ series_identifier(1).andand.id_value
20
+ end
21
+
22
+ # set a new proprietary series ID
23
+ def proprietary_series_id=(id)
24
+ series_identifier_set(1, id)
25
+ end
26
+
27
+ # retrieve the issn
28
+ def issn
29
+ series_identifier(2).andand.id_value
30
+ end
31
+
32
+ # set a new issn
33
+ def issn=(id)
34
+ series_identifier_set(2, id)
35
+ end
36
+
37
+ # retrieve the value of a particular ID
38
+ def series_identifier(type)
39
+ identifier = series_identifiers.find { |id| id.series_id_type == type }
40
+ end
41
+
42
+ # set the value of a particular ID
43
+ def series_identifier_set(type, value)
44
+ series_indentifier_id = series_identifiers.find { |id| id.series_id_type == type }
45
+
46
+ # create a new series identifier record if we need to
47
+ if series_indentifier_id.nil?
48
+ series_indentifier_id = ONIX::SeriesIdentifier.new
49
+ end
50
+
51
+ series_indentifier_id.series_id_type = type
52
+ series_indentifier_id.id_value = value
53
+
54
+ series_identifiers << series_indentifier_id
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,13 @@
1
+ # coding: utf-8
2
+
3
+ module ONIX
4
+ class SeriesIdentifier
5
+ include ROXML
6
+ include ONIX::Common
7
+
8
+ xml_name "SeriesIdentifier"
9
+
10
+ xml_accessor :series_id_type, :from => "SeriesIDType", :as => Fixnum, :to_xml => ONIX::Formatters.two_digit
11
+ xml_accessor :id_value, :from => "IDValue"
12
+ end
13
+ end
@@ -0,0 +1,47 @@
1
+ # coding: utf-8
2
+
3
+ require 'forwardable'
4
+
5
+ module ONIX
6
+ # super class for some simplified ONIX::Product wrappers
7
+ class SimpleProduct
8
+
9
+ def initialize(product = nil)
10
+ @product = product || ::ONIX::Product.new
11
+ end
12
+
13
+ class << self
14
+
15
+ include Forwardable
16
+
17
+ def from_xml(xml)
18
+ self.new(::ONIX::Product.from_xml(xml))
19
+ end
20
+
21
+ def parse_file(filename)
22
+ self.new(::ONIX::Product.parse(File.read(filename)))
23
+ end
24
+
25
+ def parse(xml)
26
+ self.new(::ONIX::Product.parse(xml))
27
+ end
28
+
29
+ protected
30
+
31
+ def delegate(*args)
32
+ def_delegators :@product, *args
33
+ end
34
+ end
35
+
36
+ def product
37
+ @product
38
+ end
39
+
40
+ def to_xml
41
+ product.to_xml
42
+ end
43
+
44
+ # TODO: add method missing magic to proxy through to the underlying product?
45
+
46
+ end
47
+ end
@@ -0,0 +1,131 @@
1
+ # coding: utf-8
2
+
3
+ module ONIX
4
+ class SLProduct < APAProduct
5
+
6
+ delegate :audience_code, :audience_code=
7
+ delegate :copyright_year, :copyright_year=
8
+ delegate :product_form_detail, :product_form_detail=
9
+
10
+ alias_method :old_initialize, :initialize
11
+ def initialize(*args)
12
+ result = old_initialize(*args)
13
+ result.audience_code = 4 # Primary & secondary/elementary & high school
14
+ result
15
+ end
16
+
17
+ # retrieve the value of a particular ID
18
+ def series(str)
19
+ product.series.find { |id| id.title_of_series == str }
20
+ end
21
+
22
+ # set the value of a particular ID
23
+ def series=(value)
24
+ # process based on value type
25
+ if value.is_a?(Series)
26
+ str = value.title_of_series
27
+ series_id = value
28
+ else
29
+ str = value
30
+ series_id = ONIX::Series.new
31
+ series_id.title_of_series = value
32
+ end
33
+ # check if exists already
34
+ unless series(str)
35
+ product.series << series_id
36
+ end
37
+ end
38
+
39
+ # retrieve the "language of text" (role=1) language code for this particular product
40
+ def language_code
41
+ language(1).andand.language_code
42
+ end
43
+
44
+ # set a new "language of text" (role=1) language code for this particular product
45
+ def language_code=(str)
46
+ language_set(1, str)
47
+ end
48
+
49
+ # retrieve the "language of text" (role=1) country code for this particular product
50
+ def country_code
51
+ language(1).andand.country_code
52
+ end
53
+
54
+ # set a new "language of text" (role=1) country code for this particular product
55
+ def country_code=(str)
56
+ language_set(1, language_code, str)
57
+ end
58
+
59
+ # retrieve the value of a particular language
60
+ def language(type)
61
+ product.languages.find { |l| l.language_role == type }
62
+ end
63
+
64
+ # set the value of a particular language
65
+ def language_set(type, value, value2=nil)
66
+ l = language(type)
67
+
68
+ # create a new language record if we need to
69
+ if l.nil?
70
+ l = ONIX::Language.new
71
+ l.language_role = type
72
+ product.languages << l
73
+ end
74
+
75
+ # cannot set country_code without language_code
76
+ unless value.nil?
77
+ l.language_code = value.to_s # mandatory
78
+ l.country_code = value2.to_s if value2 # optional
79
+ end
80
+ end
81
+
82
+ # retrieve the dewey for this title
83
+ def dewey
84
+ product.subjects.find { |sub| sub.subject_scheme_id.to_i == 1 } # dewey = 1, abridged dewey = 2
85
+ end
86
+
87
+ # add a dewey to the product
88
+ def dewey=(code)
89
+ add_subject code, "1" # dewey = 1, abridged dewey = 2
90
+ end
91
+
92
+ # audience_range_qualifier: 11 = US school grades
93
+ # audience_range_precision: 1 = exact, 3 = from, 4 = to
94
+ def us_grade_range
95
+ audience_range(11)
96
+ end
97
+
98
+ # set a new "audience of text" (role=1) country code for this particular product
99
+ def us_grade_range=(range=[])
100
+ audience_range_set(11, range[0], range[1])
101
+ end
102
+
103
+ # retrieve the value of a particular audience range
104
+ def audience_range(type)
105
+ product.audience_ranges.find { |a| a.audience_range_qualifier == type }
106
+ end
107
+
108
+ # set the value of a particular audience_range
109
+ def audience_range_set(type, min=nil, max=nil)
110
+ a = audience_range(type)
111
+
112
+ # create a new audience_range record if we need to
113
+ if a.nil?
114
+ a = ONIX::AudienceRange.new
115
+ a.audience_range_qualifier = type
116
+ product.audience_ranges << a
117
+ end
118
+
119
+ unless min.nil?
120
+ a.audience_range_precisions << "03"
121
+ a.audience_range_values << min
122
+ end
123
+ unless max.nil?
124
+ a.audience_range_precisions << "04"
125
+ a.audience_range_values << max
126
+ end
127
+ a.audience_range_precisions = ["01"] if min.nil? || max.nil?
128
+ end
129
+
130
+ end
131
+ end
data/lib/onix/stock.rb ADDED
@@ -0,0 +1,15 @@
1
+ # coding: utf-8
2
+
3
+ module ONIX
4
+ class Stock
5
+ include ROXML
6
+ include ONIX::Common
7
+
8
+ xml_name "Stock"
9
+
10
+ # NOTE: these *should* be numeric fields according to the spec,
11
+ # but heaps of ONIX files in the wild use text
12
+ xml_accessor :on_hand, :from => "OnHand"
13
+ xml_accessor :on_order, :from => "OnOrder"
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ # coding: utf-8
2
+
3
+ module ONIX
4
+ class Subject
5
+ include ROXML
6
+ include ONIX::Common
7
+
8
+ xml_name "Subject"
9
+
10
+ xml_accessor :subject_scheme_id, :from => "SubjectSchemeIdentifier", :as => Fixnum, :to_xml => ONIX::Formatters.two_digit
11
+ xml_accessor :subject_scheme_name, :from => "SubjectSchemeName"
12
+ xml_accessor :subject_scheme_version, :from => "SubjectSchemeVersion"
13
+ xml_accessor :subject_code, :from => "SubjectCode"
14
+ xml_accessor :subject_heading_text, :from => "SubjectHeadingText"
15
+ end
16
+ end
@@ -0,0 +1,32 @@
1
+ # coding: utf-8
2
+
3
+ module ONIX
4
+ class SupplyDetail
5
+ include ROXML
6
+ include ONIX::Common
7
+
8
+ xml_name "SupplyDetail"
9
+
10
+ xml_accessor :supplier_ean_location_number, :from => "SupplierEANLocationNumber"
11
+ xml_accessor :supplier_san, :from => "SupplierSAN"
12
+ xml_accessor :supplier_name, :from => "SupplierName"
13
+ xml_accessor :telephone_number, :from => "TelephoneNumber"
14
+ xml_accessor :fax_number, :from => "FaxNumber"
15
+ xml_accessor :email_address, :from => "EmailAddress"
16
+ xml_accessor :websites, :from => "Website", :as => [ONIX::Website]
17
+ xml_accessor :supplier_role, :from => "SupplierRole", :as => Fixnum, :to_xml => ONIX::Formatters.two_digit
18
+ xml_accessor :supply_to_country, :from => "SupplyToCountry"
19
+ xml_accessor :supply_to_territory, :from => "SupplyToTerritory"
20
+ xml_accessor :availability_status_code, :from => "AvailabilityStatusCode", :as => Fixnum, :to_xml => ONIX::Formatters.two_digit
21
+ xml_accessor :product_availability, :from => "ProductAvailability", :as => Fixnum, :to_xml => ONIX::Formatters.two_digit
22
+ xml_accessor :stock, :from => "Stock", :as => [ONIX::Stock]
23
+ xml_accessor :pack_quantity, :from => "PackQuantity", :as => Fixnum
24
+ xml_accessor :prices, :from => "Price", :as => [ONIX::Price]
25
+
26
+ def initialize
27
+ self.websites = []
28
+ self.stock = []
29
+ self.prices = []
30
+ end
31
+ end
32
+ end
data/lib/onix/title.rb ADDED
@@ -0,0 +1,17 @@
1
+ # coding: utf-8
2
+
3
+ module ONIX
4
+ class Title
5
+ include ROXML
6
+ include ONIX::Common
7
+
8
+ xml_name "Title"
9
+
10
+ xml_accessor :title_type, :from => "TitleType", :as => Fixnum, :to_xml => ONIX::Formatters.two_digit
11
+ xml_accessor :title_text, :from => "TitleText"
12
+ xml_accessor :title_prefix, :from => "TitlePrefix"
13
+ xml_accessor :title_without_prefix, :from => "TitleWithoutPrefix"
14
+ xml_accessor :subtitle, :from => "Subtitle"
15
+
16
+ end
17
+ end
@@ -0,0 +1,14 @@
1
+ # coding: utf-8
2
+
3
+ module ONIX
4
+ class Website
5
+ include ROXML
6
+ include ONIX::Common
7
+
8
+ xml_name "Website"
9
+
10
+ xml_accessor :website_role, :from => "WebsiteRole", :as => Fixnum, :to_xml => ONIX::Formatters.two_digit
11
+ xml_accessor :website_description, :from => "WebsiteDescription"
12
+ xml_accessor :website_link, :from => "WebsiteLink"
13
+ end
14
+ end
@@ -0,0 +1,86 @@
1
+ # coding: utf-8
2
+
3
+ module ONIX
4
+ # The primary way to write a new ONIX file.
5
+ #
6
+ # Heres a quick example. The generated file will be nice and boring, as the
7
+ # header and product objects have no data in them, but you get the idea.
8
+ #
9
+ # File.open("output.xml","w") do |output|
10
+ # header = ONIX::Header.new
11
+ # ONIX::Writer.open(output, header) do |writer|
12
+ # writer << ONIX::Product.new
13
+ # writer << ONIX::Product.new
14
+ # end
15
+ # end
16
+ #
17
+ # If you prefer, you can build your products using the APAProduct shim layer.
18
+ #
19
+ # File.open("output.xml","w") do |output|
20
+ # header = ONIX::Header.new
21
+ # ONIX::Writer.open(output, header) do |writer|
22
+ # writer << ONIX::APAProduct.new
23
+ # writer << ONIX::APAProduct.new
24
+ # end
25
+ # end
26
+ #
27
+ class Writer
28
+
29
+ DOCTYPE = "http://www.editeur.org/onix/2.1/03/reference/onix-international.dtd"
30
+
31
+ # Default constructor.
32
+ def initialize(output, header)
33
+ raise ArgumentError, 'msg must be an ONIX::Header object' unless header.kind_of?(ONIX::Header)
34
+ @output = output
35
+ @header = header
36
+ @finished = false
37
+
38
+ start_document
39
+ end
40
+
41
+ # deprecated
42
+ def start_document
43
+ puts "ONIX::StreamWriter#start_document is no longer required"
44
+ end
45
+
46
+ def << (product)
47
+ unless product.kind_of?(ONIX::Product) || product.kind_of?(ONIX::SimpleProduct)
48
+ raise ArgumentError, 'product must be an ONIX::Product or ONIX::SimpleProduct'
49
+ end
50
+ raise "Can't add products to a finished writer" if finished?
51
+
52
+ @output.write(product.to_xml.to_s)
53
+ @output.write("\n")
54
+ end
55
+
56
+ def end_document
57
+ @output.write("</ONIXMessage>\n")
58
+ @finished = true
59
+ end
60
+
61
+ def finished?
62
+ @finished
63
+ end
64
+
65
+ def self.open(output, header)
66
+ if block_given?
67
+ writer = self.new(output, header)
68
+ yield writer
69
+ writer.end_document
70
+ else
71
+ self.new(output, header)
72
+ end
73
+ end
74
+
75
+ private
76
+
77
+ def start_document
78
+ @output.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
79
+ @output.write("<!DOCTYPE ONIXMessage SYSTEM \"#{DOCTYPE}\">\n")
80
+ @output.write("<ONIXMessage>\n")
81
+ @output.write(@header.to_xml.to_s)
82
+ @output.write("\n")
83
+ end
84
+
85
+ end
86
+ end