rbook 0.1 → 0.2

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.
@@ -0,0 +1,19 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + "/../")
2
+
3
+ require 'rbook/isbn'
4
+ require 'rbook/gbip/pos'
5
+
6
+ module RBook
7
+
8
+ # Ruby classes for searching the globalbooksinprint.com API. This is a
9
+ # commercial service and requires a registered account to access. More
10
+ # information on the service can be found at the website.
11
+ #
12
+ # = Basic Usage
13
+ # gbip = RBook::GBIP::POS.new("username", "password")
14
+ # puts gbip.find("0091835135").inspect
15
+ #
16
+ module GBIP
17
+
18
+ end
19
+ end
@@ -0,0 +1,40 @@
1
+ require 'socket'
2
+
3
+ module RBook
4
+
5
+ module GBIP
6
+
7
+ # Provides easy access to the globalbooksinprint.com search API.
8
+ # RBook::GBIP has basic usage examples.
9
+ class POS
10
+
11
+ attr_accessor :username, :password
12
+
13
+ POS_SERVER = "pos.bowker.com"
14
+ POS_PORT = 7052
15
+
16
+ # creates a new POS object ready to perform a search
17
+ def initialize(username, password)
18
+ @username = username
19
+ @password = password
20
+ end
21
+
22
+ # search for the specified ISBN on globalbooksinprint.com.
23
+ # Accepts both ISBN10 and ISBN13's.
24
+ def find(isbn)
25
+ isbn = RBook::ISBN::convert_to_isbn10(isbn)
26
+ return nil if isbn.nil?
27
+
28
+ request = "POS\t3\t2\t#{@username}\t#{@password}\t2\t\tbn=#{isbn}\t1|1|1|1|1|1|1|1|1|1\t10,0\t1\t\t"
29
+ gbip = TCPSocket.new(POS_SERVER, POS_PORT)
30
+ gbip.print request
31
+ response = gbip.gets(nil)
32
+ gbip.close
33
+ return response.split("\t")
34
+ end
35
+
36
+ end
37
+
38
+ end
39
+
40
+ end
@@ -7,6 +7,8 @@ require 'rbook/onix/product'
7
7
  require 'rbook/onix/sales_restriction'
8
8
  require 'rbook/onix/supply_detail'
9
9
  require 'rbook/onix/xchar'
10
+ require 'rbook/onix/stream_reader'
11
+ require 'rbook/onix/stream_writer'
10
12
  require 'rbook/isbn'
11
13
 
12
14
  module RBook
@@ -2,100 +2,105 @@ require 'rubygems'
2
2
  require 'rexml/document'
3
3
 
4
4
  module RBook
5
- module Onix
5
+ module Onix
6
6
 
7
- class Message
8
- attr_reader :products
9
- attr_accessor :from_company, :from_person, :from_email, :message_note, :sent_date, :to_person, :to_company
10
-
11
- VERSION = 0.1
7
+ class Message
8
+ attr_reader :products
9
+ attr_accessor :from_company, :from_person, :from_email, :message_note, :sent_date, :to_person, :to_company
12
10
 
13
- def initialize
14
- @ONIX_DTD_URL = "http://www.editeur.org/onix/2.1/reference/onix-international.dtd"
15
-
16
- @products = []
17
- end
11
+ VERSION = 0.1
12
+ ONIX_DTD_URL = "http://www.editeur.org/onix/2.1/reference/onix-international.dtd"
18
13
 
19
- # Attempts to create a message object using thge supplied xml document
20
- def Message.load_from_xmldoc(doc)
21
- raise ArgumentError, 'load_from_xmldoc expects a REXML document object' unless doc.class == REXML::Document
22
- if REXML::XPath.first(doc, '/ONIXMessage/').nil? ||
23
- REXML::XPath.first(doc, '/ONIXMessage/Header').nil? ||
24
- REXML::XPath.first(doc, '/ONIXMessage/Product').nil?
25
- raise LoadError, 'supplied REXML document object does not appear to be a valid ONIX file'
26
- end
27
-
28
- msg = Onix::Message.new
29
-
30
- tmpelement = REXML::XPath.first(doc, '/ONIXMessage/Header/FromCompany')
31
- msg.from_company = tmpelement.text if tmpelement != nil
32
-
33
- tmpelement = REXML::XPath.first(doc, '/ONIXMessage/Header/FromPerson')
34
- msg.from_person = tmpelement.text if tmpelement != nil
35
-
36
- tmpelement = REXML::XPath.first(doc, '/ONIXMessage/Header/FromEmail')
37
- msg.from_email = tmpelement.text if tmpelement != nil
38
-
39
- tmpelement = REXML::XPath.first(doc, '/ONIXMessage/Header/SentDate')
40
- tmpdate = Date.civil(tmpelement.text[0,4].to_i, tmpelement.text[4,2].to_i, tmpelement.text[6,2].to_i) if tmpelement != nil
41
- msg.sent_date = tmpdate if tmpdate != nil
42
-
43
- tmpelement = REXML::XPath.first(doc, '/ONIXMessage/Header/ToCompany')
44
- msg.to_company = tmpelement.text if tmpelement != nil
45
-
46
- tmpelement = REXML::XPath.first(doc, '/ONIXMessage/Header/ToPerson')
47
- msg.to_person = tmpelement.text if tmpelement != nil
48
-
49
- products = REXML::XPath.each(doc, '/ONIXMessage/Product') { |product|
50
- msg.add_product(Onix::Product.load_from_element(product))
51
- }
52
-
53
- return msg
54
- end
14
+ def initialize
15
+ @products = []
16
+ end
55
17
 
56
- # Adds a new product to this message
57
- def add_product(product)
58
- raise ArgumentError, 'Argument must be a Onix::Product' if product.class != Onix::Product
59
- @products << product
60
- end
18
+ # Attempts to create a message object using thge supplied xml document
19
+ def Message.load_from_xmldoc(doc)
20
+ raise ArgumentError, 'load_from_xmldoc expects a REXML document object' unless doc.class == REXML::Document
21
+ if REXML::XPath.first(doc, '/ONIXMessage/').nil? ||
22
+ REXML::XPath.first(doc, '/ONIXMessage/Header').nil? ||
23
+ REXML::XPath.first(doc, '/ONIXMessage/Product').nil?
24
+ raise LoadError, 'supplied REXML document object does not appear to be a valid ONIX file'
25
+ end
61
26
 
62
- # Returns an XML string representing this message
63
- def to_s
64
- doc = to_xml
65
- output = ''
66
- doc.write(output, 0)
67
- return output
68
- end
27
+ msg = Onix::Message.new
69
28
 
70
- # Returns an XML document representing this message
71
- def to_xml
72
- raise 'from_compnay must be set to create an onix message' if from_company == nil
73
- raise 'from_person must be set to create an onix message' if from_person == nil
74
- raise 'There must be at least 1 product to burn' if @products.size < 1
75
-
76
- doc = REXML::Document.new
77
- doc << REXML::XMLDecl.new
78
- doc << REXML::DocType.new('ONIXMessage', "SYSTEM \"#{@ONIX_DTD_URL}\"")
79
- msg = doc.add_element('ONIXMessage')
80
- header = msg.add_element('Header')
81
- header.add_element('FromCompany').text = from_company.to_xs
82
- header.add_element('FromPerson').text = from_person.to_xs
83
- header.add_element('FromEmail').text = from_email.to_xs unless from_email.nil?
84
- header.add_element('MessageNote').text = message_note.to_xs unless message_note.nil?
85
- header.add_element('ToCompany').text = to_company.to_xs unless to_company.nil?
86
- header.add_element('ToPerson').text = to_person.to_xs unless to_person.nil?
87
-
88
- now = Time.now
89
- header.add_element('SentDate').text = "%.4d%.2d%.2d" % [ now.year, now.month, now.day ]
29
+ tmpelement = REXML::XPath.first(doc, '/ONIXMessage/Header/FromCompany')
30
+ msg.from_company = tmpelement.text if tmpelement != nil
31
+
32
+ tmpelement = REXML::XPath.first(doc, '/ONIXMessage/Header/FromPerson')
33
+ msg.from_person = tmpelement.text if tmpelement != nil
34
+
35
+ tmpelement = REXML::XPath.first(doc, '/ONIXMessage/Header/FromEmail')
36
+ msg.from_email = tmpelement.text if tmpelement != nil
37
+
38
+ tmpelement = REXML::XPath.first(doc, '/ONIXMessage/Header/SentDate')
39
+ tmpdate = Date.civil(tmpelement.text[0,4].to_i, tmpelement.text[4,2].to_i, tmpelement.text[6,2].to_i) if tmpelement != nil
40
+ msg.sent_date = tmpdate if tmpdate != nil
41
+
42
+ tmpelement = REXML::XPath.first(doc, '/ONIXMessage/Header/ToCompany')
43
+ msg.to_company = tmpelement.text if tmpelement != nil
44
+
45
+ tmpelement = REXML::XPath.first(doc, '/ONIXMessage/Header/ToPerson')
46
+ msg.to_person = tmpelement.text if tmpelement != nil
47
+
48
+ products = REXML::XPath.each(doc, '/ONIXMessage/Product') { |product|
49
+ msg.add_product(Onix::Product.load_from_element(product))
50
+ }
51
+
52
+ return msg
53
+ end
54
+
55
+ # Adds a new product to this message
56
+ def add_product(product)
57
+ raise ArgumentError, 'Argument must be a Onix::Product' if product.class != Onix::Product
58
+ @products << product
59
+ end
60
+
61
+ # Returns an XML string representing this message
62
+ def to_s
63
+ doc = to_xml
64
+ output = ''
65
+ doc.write(output, 0)
66
+ return output
67
+ end
90
68
 
91
- @products.each do |product|
92
- prod = msg.add_element(product.to_element)
93
- end
69
+ def header
70
+ raise 'from_compnay must be set to create an onix message' if from_company == nil
71
+ raise 'from_person must be set to create an onix message' if from_person == nil
94
72
 
95
- return doc
96
- end
73
+ header = REXML::Element.new('Header')
74
+ header.add_element('FromCompany').text = from_company.to_xs
75
+ header.add_element('FromPerson').text = from_person.to_xs
76
+ header.add_element('FromEmail').text = from_email.to_xs unless from_email.nil?
77
+ header.add_element('MessageNote').text = message_note.to_xs unless message_note.nil?
78
+ header.add_element('ToCompany').text = to_company.to_xs unless to_company.nil?
79
+ header.add_element('ToPerson').text = to_person.to_xs unless to_person.nil?
97
80
 
98
- end
81
+ now = Time.now
82
+ header.add_element('SentDate').text = "%.4d%.2d%.2d" % [ now.year, now.month, now.day ]
83
+ return header
84
+ end
85
+
86
+ # Returns an XML document representing this message
87
+ def to_xml
88
+ raise 'There must be at least 1 product to burn' if @products.size < 1
99
89
 
100
- end
90
+ doc = REXML::Document.new
91
+ doc << REXML::XMLDecl.new
92
+ doc << REXML::DocType.new('ONIXMessage', "SYSTEM \"#{ONIX_DTD_URL}\"")
93
+ msg = doc.add_element('ONIXMessage')
94
+ msg.add_element(header)
95
+
96
+ @products.each do |product|
97
+ prod = msg.add_element(product.to_element)
98
+ end
99
+
100
+ return doc
101
+ end
102
+
103
+ end
104
+
105
+ end
101
106
  end
@@ -2,187 +2,188 @@ require 'rexml/document'
2
2
  require 'rubygems'
3
3
 
4
4
  module RBook
5
- module Onix
6
- class Product
7
-
8
- attr_accessor :record_reference, :notification_type, :product_identifier, :title, :subtitle, :pages, :publication_date, :price, :description, :form, :bicmainsubject, :publisher, :supplier, :website, :edition
9
- attr_reader :contributors, :sales_restrictions, :supply_details
10
-
11
- def initialize
12
- @contributors = []
13
- @supply_details = []
14
- @sales_restrictions = []
15
- end
16
-
17
- # Attempts to create a product object using the supplied xml element
18
- def Product.load_from_element(element)
19
- raise ArgumentError, 'load_from_element expects a REXML element object' unless element.class == REXML::Element
20
-
21
- if REXML::XPath.first(element, '//Product').nil?
22
- raise LoadError, 'supplied REXML document object does not appear contain a valid product fragment'
23
- end
24
-
25
- product = Product.new
26
-
27
- tmp = REXML::XPath.first(element, '//Product/RecordReference')
28
- product.record_reference = tmp.text if tmp != nil
29
-
30
- tmp = REXML::XPath.first(element, '//Product/NotificationType')
31
- product.notification_type = tmp.text if tmp != nil
32
-
33
- # TODO: load ProductIdentifier from the fragment
34
-
35
- tmp = REXML::XPath.first(element, '//Product/ProductForm')
36
- product.form = tmp.text if tmp != nil
37
-
38
- tmp = REXML::XPath.first(element, '//Product/NumberOfPages')
39
- product.pages = tmp.text if tmp != nil
40
-
41
- tmp = REXML::XPath.first(element, '//Product/BICMainSubject')
42
- product.bicmainsubject = tmp.text if tmp != nil
43
-
44
- tmp = REXML::XPath.first(element, '//Product/DistinctiveTitle')
45
- if !tmp.nil?
46
- product.title = tmp.text
47
- tmp = REXML::XPath.first(element, '//Product/Subtitle') if !tmp.nil?
48
- product.subtitle = tmp.text
49
- else
50
- tmp = REXML::XPath.first(element, '//Product/Title/TitleText')
51
- product.title = tmp.text unless tmp.nil?
52
- tmp = REXML::XPath.first(element, '//Product/Title/Subtitle')
53
- product.subtitle = tmp.text unless tmp.nil?
54
- end
55
-
56
- tmp = REXML::XPath.first(element, '//Product/EditionNumber')
57
- product.edition = tmp.text if tmp != nil
58
-
59
- tmp = REXML::XPath.first(element, '//Product/PublicationDate')
60
- tmpdate = Date.civil(tmp.text[0,4].to_i, tmp.text[4,2].to_i, tmp.text[6,2].to_i) if tmp != nil
61
- product.publication_date = tmpdate if tmpdate != nil
62
-
63
- tmp = REXML::XPath.first(element, '//Product/Publisher/PublisherName')
64
- product.publisher = tmp.text if tmp != nil
65
-
66
- REXML::XPath.each(element, '//Product/Contributor') { |contributor|
67
- product.add_contributor(Onix::Contributor.load_from_element(contributor))
68
- }
69
-
70
- REXML::XPath.each(element, '//Product/SupplyDetail') { |detail|
71
- product.add_supply_detail(Onix::SupplyDetail.load_from_element(detail))
72
- }
73
-
74
- return product
75
- end
76
-
77
- # Add a new contributor to this product
78
- def add_contributor(newAuthor)
79
- raise ArgumentError, 'Argument to add_contributor must be an ONIX::Contributor' if newAuthor.class != Contributor
80
- @contributors << newAuthor
81
- end
82
-
83
- # Add a new contributor to this product
84
- def add_sales_restriction(restriction)
85
- raise ArgumentError, 'Argument to add_sales_restriction must be an ONIX::SalesRestriction' if restriction.class != SalesRestriction
86
- @sales_restrictions << restriction
87
- end
88
-
89
- # Add a new contributor to this product
90
- def add_supply_detail(detail)
91
- raise ArgumentError, 'Argument to add_supply_detail must be an ONIX::SupplyDetail' if detail.class != SupplyDetail
92
- @supply_details << detail
93
- end
94
-
95
- # Return an xml element representing this contributor
96
- def to_element
97
- raise 'product_identifier must be set' if self.product_identifier.nil?
98
-
99
- product = REXML::Element.new('Product')
100
-
101
- if self.record_reference
102
- product.add_element('RecordReference').text = self.record_reference
103
- else
104
- product.add_element('RecordReference').text = self.product_identifier
105
- end
106
-
107
- product.add_element('NotificationType').text = '03'
108
-
109
- product_identifier = REXML::Element.new('ProductIdentifier')
110
- if ISBN::valid_isbn13?(self.product_identifier)
111
- product_identifier.add_element('ProductIDType').text = '03'
112
- elsif ISBN::valid_isbn10?(self.product_identifier)
113
- product_identifier.add_element('ProductIDType').text = '02'
114
- else
115
- product_identifier.add_element('ProductIDType').text = '01'
116
- end
117
- product_identifier.add_element('IDValue').text = self.product_identifier.to_xs
118
- product.add_element(product_identifier)
119
-
120
- if form != nil
121
- product.add_element('ProductForm').text = self.form.to_xs
122
- end
123
-
124
- product.add_element('NoSeries')
125
-
126
- title = REXML::Element.new('Title')
127
- title.add_element('TitleType').text = '01'
128
- title.add_element('TitleText').text = self.title.to_xs unless self.title.nil?
129
- title.add_element('Subtitle').text = self.subtitle.to_xs unless self.subtitle.nil?
130
- product.add_element(title)
131
-
132
- if website != nil
133
- product_website = REXML::Element.new('Website')
134
- product_website.add_element('WebsiteLink').text = self.website.to_xs
135
- product.add_element(product_website)
136
- end
137
-
138
- contributors.each do |contributor|
139
- product.add_element(contributor.to_element)
140
- end
141
-
142
- product.add_element('NoEdition')
143
-
144
- product.add_element('NumberOfPages').text = self.pages.to_s unless self.pages.nil?
145
-
146
- if bicmainsubject != nil
147
- product.add_element('BICMainSubject').text = self.bicmainsubject.to_xs
148
- end
5
+ module Onix
6
+ class Product
149
7
 
150
- if description != nil
151
- other_text = REXML::Element.new('OtherText')
152
- other_text.add_element('TextTypeCode').text = '01'
153
- other_text.add_element('Text').text = self.description.to_xs
154
- product.add_element(other_text)
155
- end
156
-
157
- if publisher != nil
158
- publisher = REXML::Element.new('Publisher')
159
- publisher.add_element('PublishingRole').text = '01'
160
- publisher.add_element('PublisherName').text = self.publisher.to_xs
161
- product.add_element(publisher)
162
- end
8
+ attr_accessor :record_reference, :notification_type, :product_identifier, :title, :subtitle, :pages, :publication_date, :price, :description, :form, :bicmainsubject, :publisher, :supplier, :website, :edition
9
+ attr_reader :contributors, :sales_restrictions, :supply_details
163
10
 
164
- supply_details.each do |detail|
165
- product.add_element(detail.to_element)
166
- end
167
-
168
- sales_restrictions.each do |restriction|
169
- product.add_element(restriction.to_element)
170
- end
171
-
172
- if publication_date != nil
173
- product.add_element('PublicationDate').text = "%.4d%.2d%.2d" % [ publication_date.year, publication_date.month, publication_date.day ]
11
+ def initialize
12
+ @contributors = []
13
+ @supply_details = []
14
+ @sales_restrictions = []
15
+ end
16
+
17
+ # Attempts to create a product object using the supplied xml element
18
+ def Product.load_from_element(element)
19
+ raise ArgumentError, 'load_from_element expects a REXML element object' unless element.class == REXML::Element
20
+
21
+ if REXML::XPath.first(element, '//Product').nil?
22
+ raise LoadError, 'supplied REXML document object does not appear contain a valid product fragment'
23
+ end
24
+
25
+ product = Product.new
26
+
27
+ tmp = REXML::XPath.first(element, '//Product/RecordReference')
28
+ product.record_reference = tmp.text if tmp != nil
29
+
30
+ tmp = REXML::XPath.first(element, '//Product/NotificationType')
31
+ product.notification_type = tmp.text if tmp != nil
32
+
33
+ tmp = REXML::XPath.first(element, '//Product/ProductIdentifier/IDValue')
34
+ product.product_identifier = tmp.text if tmp != nil
35
+
36
+ tmp = REXML::XPath.first(element, '//Product/ProductForm')
37
+ product.form = tmp.text if tmp != nil
38
+
39
+ tmp = REXML::XPath.first(element, '//Product/NumberOfPages')
40
+ product.pages = tmp.text if tmp != nil
41
+
42
+ tmp = REXML::XPath.first(element, '//Product/BICMainSubject')
43
+ product.bicmainsubject = tmp.text if tmp != nil
44
+
45
+ tmp = REXML::XPath.first(element, '//Product/DistinctiveTitle')
46
+ if !tmp.nil?
47
+ product.title = tmp.text
48
+ tmp = REXML::XPath.first(element, '//Product/Subtitle') if !tmp.nil?
49
+ product.subtitle = tmp.text
50
+ else
51
+ tmp = REXML::XPath.first(element, '//Product/Title/TitleText')
52
+ product.title = tmp.text unless tmp.nil?
53
+ tmp = REXML::XPath.first(element, '//Product/Title/Subtitle')
54
+ product.subtitle = tmp.text unless tmp.nil?
55
+ end
56
+
57
+ tmp = REXML::XPath.first(element, '//Product/EditionNumber')
58
+ product.edition = tmp.text if tmp != nil
59
+
60
+ tmp = REXML::XPath.first(element, '//Product/PublicationDate')
61
+ tmpdate = Date.civil(tmp.text[0,4].to_i, tmp.text[4,2].to_i, tmp.text[6,2].to_i) if tmp != nil
62
+ product.publication_date = tmpdate if tmpdate != nil
63
+
64
+ tmp = REXML::XPath.first(element, '//Product/Publisher/PublisherName')
65
+ product.publisher = tmp.text if tmp != nil
66
+
67
+ REXML::XPath.each(element, '//Product/Contributor') { |contributor|
68
+ product.add_contributor(Onix::Contributor.load_from_element(contributor))
69
+ }
70
+
71
+ REXML::XPath.each(element, '//Product/SupplyDetail') { |detail|
72
+ product.add_supply_detail(Onix::SupplyDetail.load_from_element(detail))
73
+ }
74
+
75
+ return product
76
+ end
77
+
78
+ # Add a new contributor to this product
79
+ def add_contributor(newAuthor)
80
+ raise ArgumentError, 'Argument to add_contributor must be an ONIX::Contributor' if newAuthor.class != Contributor
81
+ @contributors << newAuthor
82
+ end
83
+
84
+ # Add a new contributor to this product
85
+ def add_sales_restriction(restriction)
86
+ raise ArgumentError, 'Argument to add_sales_restriction must be an ONIX::SalesRestriction' if restriction.class != SalesRestriction
87
+ @sales_restrictions << restriction
88
+ end
89
+
90
+ # Add a new contributor to this product
91
+ def add_supply_detail(detail)
92
+ raise ArgumentError, 'Argument to add_supply_detail must be an ONIX::SupplyDetail' if detail.class != SupplyDetail
93
+ @supply_details << detail
94
+ end
95
+
96
+ # Return an xml element representing this contributor
97
+ def to_element
98
+ raise 'product_identifier must be set' if self.product_identifier.nil?
99
+
100
+ product = REXML::Element.new('Product')
101
+
102
+ if self.record_reference
103
+ product.add_element('RecordReference').text = self.record_reference
104
+ else
105
+ product.add_element('RecordReference').text = self.product_identifier
106
+ end
107
+
108
+ product.add_element('NotificationType').text = '03'
109
+
110
+ product_identifier = REXML::Element.new('ProductIdentifier')
111
+ if ISBN::valid_isbn13?(self.product_identifier)
112
+ product_identifier.add_element('ProductIDType').text = '03'
113
+ elsif ISBN::valid_isbn10?(self.product_identifier)
114
+ product_identifier.add_element('ProductIDType').text = '02'
115
+ else
116
+ product_identifier.add_element('ProductIDType').text = '01'
117
+ end
118
+ product_identifier.add_element('IDValue').text = self.product_identifier.to_xs
119
+ product.add_element(product_identifier)
120
+
121
+ if form != nil
122
+ product.add_element('ProductForm').text = self.form.to_xs
123
+ end
124
+
125
+ product.add_element('NoSeries')
126
+
127
+ title = REXML::Element.new('Title')
128
+ title.add_element('TitleType').text = '01'
129
+ title.add_element('TitleText').text = self.title.to_xs unless self.title.nil?
130
+ title.add_element('Subtitle').text = self.subtitle.to_xs unless self.subtitle.nil?
131
+ product.add_element(title)
132
+
133
+ if website != nil
134
+ product_website = REXML::Element.new('Website')
135
+ product_website.add_element('WebsiteLink').text = self.website.to_xs
136
+ product.add_element(product_website)
137
+ end
138
+
139
+ contributors.each do |contributor|
140
+ product.add_element(contributor.to_element)
141
+ end
142
+
143
+ product.add_element('NoEdition')
144
+
145
+ product.add_element('NumberOfPages').text = self.pages.to_s unless self.pages.nil?
146
+
147
+ if bicmainsubject != nil
148
+ product.add_element('BICMainSubject').text = self.bicmainsubject.to_xs
149
+ end
150
+
151
+ if description != nil
152
+ other_text = REXML::Element.new('OtherText')
153
+ other_text.add_element('TextTypeCode').text = '01'
154
+ other_text.add_element('Text').text = self.description.to_xs
155
+ product.add_element(other_text)
156
+ end
157
+
158
+ if publisher != nil
159
+ publisher = REXML::Element.new('Publisher')
160
+ publisher.add_element('PublishingRole').text = '01'
161
+ publisher.add_element('PublisherName').text = self.publisher.to_xs
162
+ product.add_element(publisher)
163
+ end
164
+
165
+ supply_details.each do |detail|
166
+ product.add_element(detail.to_element)
167
+ end
168
+
169
+ sales_restrictions.each do |restriction|
170
+ product.add_element(restriction.to_element)
171
+ end
172
+
173
+ if publication_date != nil
174
+ product.add_element('PublicationDate').text = "%.4d%.2d%.2d" % [ publication_date.year, publication_date.month, publication_date.day ]
175
+ end
176
+
177
+ return product
178
+ end
179
+
180
+ # return an XML string representing this contributor
181
+ def to_s
182
+ output = ''
183
+ to_element.write(output, 0)
184
+ return output
185
+ end
174
186
  end
175
187
 
176
- return product
177
188
  end
178
-
179
- # return an XML string representing this contributor
180
- def to_s
181
- output = ''
182
- to_element.write(output, 0)
183
- return output
184
- end
185
- end
186
-
187
- end
188
189
  end