sitemap_generator 4.1.1 → 4.2.0
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/Gemfile +1 -1
- data/Gemfile.lock +3 -3
- data/README.md +6 -0
- data/VERSION +1 -1
- data/lib/sitemap_generator.rb +9 -1
- data/lib/sitemap_generator/builder/sitemap_file.rb +6 -6
- data/lib/sitemap_generator/builder/sitemap_url.rb +38 -29
- data/lib/sitemap_generator/link_set.rb +7 -5
- data/lib/sitemap_generator/sitemap_location.rb +1 -1
- data/lib/sitemap_generator/utilities.rb +11 -0
- data/spec/sitemap_generator/geo_sitemap_spec.rb +2 -2
- data/spec/sitemap_generator/link_set_spec.rb +25 -7
- data/spec/sitemap_generator/mobile_sitemap_spec.rb +2 -2
- data/spec/sitemap_generator/news_sitemap_spec.rb +2 -2
- data/spec/sitemap_generator/pagemap_sitemap_spec.rb +27 -20
- data/spec/sitemap_generator/sitemap_location_spec.rb +31 -0
- data/spec/sitemap_generator/utilities_spec.rb +10 -0
- data/spec/sitemap_generator/video_sitemap_spec.rb +11 -3
- data/spec/support/schemas/sitemap-video.xsd +245 -11
- data/spec/support/xml_macros.rb +17 -5
- metadata +4 -4
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ./
|
3
3
|
specs:
|
4
|
-
sitemap_generator (4.
|
4
|
+
sitemap_generator (4.2)
|
5
5
|
builder
|
6
6
|
|
7
7
|
GEM
|
@@ -12,7 +12,7 @@ GEM
|
|
12
12
|
metaclass (0.0.1)
|
13
13
|
mocha (0.10.0)
|
14
14
|
metaclass (~> 0.0.1)
|
15
|
-
nokogiri (1.5.
|
15
|
+
nokogiri (1.5.10)
|
16
16
|
rake (10.0.4)
|
17
17
|
rspec (2.8.0)
|
18
18
|
rspec-core (~> 2.8.0)
|
@@ -29,7 +29,7 @@ PLATFORMS
|
|
29
29
|
DEPENDENCIES
|
30
30
|
builder
|
31
31
|
mocha
|
32
|
-
nokogiri
|
32
|
+
nokogiri (= 1.5.10)
|
33
33
|
rake
|
34
34
|
rspec
|
35
35
|
sitemap_generator!
|
data/README.md
CHANGED
@@ -105,6 +105,7 @@ That's it! Welcome to the future!
|
|
105
105
|
|
106
106
|
## Changelog
|
107
107
|
|
108
|
+
* v4.2: Update Google ping URL. Quote the ping URL in the output. Support Video `video:price` element ([#117][https://github.com/kjvarga/sitemap_generator/issues/117]). Support symbols as well as strings for most arguments to `add()` ([#113][https://github.com/kjvarga/sitemap_generator/issues/113]). Ensure that `public_path` and `sitemaps_path` end with a slash (`/`) ([#113][https://github.com/kjvarga/sitemap_generator/issues/118]).
|
108
109
|
* v4.1.1: Support setting the S3 region. Fixed bug where incorrect URL was being used in the ping to search engines - only affected sites with a single sitemap file and no index file. Output the URL being pinged in the verbose output. Test in Rails 4.
|
109
110
|
* v4.1.0: [PageMap sitemap][using_pagemaps] support. Tested with Rails 4 pre-release.
|
110
111
|
* v4.0.1: Add a post install message regarding the naming convention change.
|
@@ -912,6 +913,10 @@ end
|
|
912
913
|
* `:gallery_title` - Title attribute of the gallery location element
|
913
914
|
* `:uploader`
|
914
915
|
* `:uploader_info` - Info attribute of uploader element
|
916
|
+
* `:price` - Only one price supported at this time
|
917
|
+
* `:price_currency` - Required. In [ISO_4217][iso_4217] format.
|
918
|
+
* `:price_type` - Optional. `rent` or `own`
|
919
|
+
* `:price_resolution` - Optional. `HD` or `SD`
|
915
920
|
|
916
921
|
### Geo Sitemaps
|
917
922
|
|
@@ -1078,3 +1083,4 @@ Copyright (c) 2009 Karl Varga released under the MIT license
|
|
1078
1083
|
[ehoch]:https://github.com/ehoch
|
1079
1084
|
[alternate_links]:http://support.google.com/webmasters/bin/answer.py?hl=en&answer=2620865
|
1080
1085
|
[using_pagemaps]:https://developers.google.com/custom-search/docs/structured_data#pagemaps
|
1086
|
+
[iso_4217]:http://en.wikipedia.org/wiki/ISO_4217
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
4.
|
1
|
+
4.2.0
|
data/lib/sitemap_generator.rb
CHANGED
@@ -26,7 +26,15 @@ module SitemapGenerator
|
|
26
26
|
MAX_SITEMAP_IMAGES = 1_000 # max images per url
|
27
27
|
MAX_SITEMAP_NEWS = 1_000 # max news sitemap per index_file
|
28
28
|
MAX_SITEMAP_FILESIZE = SitemapGenerator::Numeric.new(10).megabytes # bytes
|
29
|
-
|
29
|
+
SCHEMAS = {
|
30
|
+
'geo' => 'http://www.google.com/geo/schemas/sitemap/1.0',
|
31
|
+
'image' => 'http://www.google.com/schemas/sitemap-image/1.1',
|
32
|
+
'mobile' => 'http://www.google.com/schemas/sitemap-mobile/1.0',
|
33
|
+
'news' => 'http://www.google.com/schemas/sitemap-news/0.9',
|
34
|
+
'pagemap' => 'http://www.google.com/schemas/sitemap-pagemap/1.0',
|
35
|
+
'video' => 'http://www.google.com/schemas/sitemap-video/1.1'
|
36
|
+
}
|
37
|
+
|
30
38
|
# Lazy-initialize the LinkSet instance
|
31
39
|
Sitemap = (Class.new do
|
32
40
|
def method_missing(*args, &block)
|
@@ -28,15 +28,15 @@ module SitemapGenerator
|
|
28
28
|
<?xml version="1.0" encoding="UTF-8"?>
|
29
29
|
<urlset
|
30
30
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
31
|
-
xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"
|
32
31
|
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
|
33
32
|
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"
|
34
33
|
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
|
35
|
-
xmlns:
|
36
|
-
xmlns:
|
37
|
-
xmlns:
|
38
|
-
xmlns:
|
39
|
-
xmlns:
|
34
|
+
xmlns:image="#{SitemapGenerator::SCHEMAS['image']}"
|
35
|
+
xmlns:video="#{SitemapGenerator::SCHEMAS['video']}"
|
36
|
+
xmlns:geo="#{SitemapGenerator::SCHEMAS['geo']}"
|
37
|
+
xmlns:news="#{SitemapGenerator::SCHEMAS['news']}"
|
38
|
+
xmlns:mobile="#{SitemapGenerator::SCHEMAS['mobile']}"
|
39
|
+
xmlns:pagemap="#{SitemapGenerator::SCHEMAS['pagemap']}"
|
40
40
|
xmlns:xhtml="http://www.w3.org/1999/xhtml"
|
41
41
|
>
|
42
42
|
HTML
|
@@ -72,72 +72,73 @@ module SitemapGenerator
|
|
72
72
|
builder.url do
|
73
73
|
builder.loc self[:loc]
|
74
74
|
builder.lastmod w3c_date(self[:lastmod]) if self[:lastmod]
|
75
|
-
builder.changefreq self[:changefreq]
|
75
|
+
builder.changefreq self[:changefreq].to_s if self[:changefreq]
|
76
76
|
builder.priority format_float(self[:priority]) if self[:priority]
|
77
77
|
|
78
78
|
unless SitemapGenerator::Utilities.blank?(self[:news])
|
79
79
|
news_data = self[:news]
|
80
80
|
builder.news:news do
|
81
81
|
builder.news:publication do
|
82
|
-
builder.news :name, news_data[:publication_name] if news_data[:publication_name]
|
83
|
-
builder.news :language, news_data[:publication_language] if news_data[:publication_language]
|
82
|
+
builder.news :name, news_data[:publication_name].to_s if news_data[:publication_name]
|
83
|
+
builder.news :language, news_data[:publication_language].to_s if news_data[:publication_language]
|
84
84
|
end
|
85
85
|
|
86
|
-
builder.news :access, news_data[:access] if news_data[:access]
|
87
|
-
builder.news :genres, news_data[:genres] if news_data[:genres]
|
86
|
+
builder.news :access, news_data[:access].to_s if news_data[:access]
|
87
|
+
builder.news :genres, news_data[:genres].to_s if news_data[:genres]
|
88
88
|
builder.news :publication_date, w3c_date(news_data[:publication_date]) if news_data[:publication_date]
|
89
|
-
builder.news :title, news_data[:title] if news_data[:title]
|
90
|
-
builder.news :keywords, news_data[:keywords] if news_data[:keywords]
|
91
|
-
builder.news :stock_tickers, news_data[:stock_tickers] if news_data[:stock_tickers]
|
89
|
+
builder.news :title, news_data[:title].to_s if news_data[:title]
|
90
|
+
builder.news :keywords, news_data[:keywords].to_s if news_data[:keywords]
|
91
|
+
builder.news :stock_tickers, news_data[:stock_tickers].to_s if news_data[:stock_tickers]
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
95
95
|
self[:images].each do |image|
|
96
96
|
builder.image:image do
|
97
97
|
builder.image :loc, image[:loc]
|
98
|
-
builder.image :caption, image[:caption] if image[:caption]
|
99
|
-
builder.image :geo_location, image[:geo_location] if image[:geo_location]
|
100
|
-
builder.image :title, image[:title] if image[:title]
|
101
|
-
builder.image :license, image[:license] if image[:license]
|
98
|
+
builder.image :caption, image[:caption].to_s if image[:caption]
|
99
|
+
builder.image :geo_location, image[:geo_location].to_s if image[:geo_location]
|
100
|
+
builder.image :title, image[:title].to_s if image[:title]
|
101
|
+
builder.image :license, image[:license].to_s if image[:license]
|
102
102
|
end
|
103
103
|
end
|
104
104
|
|
105
105
|
self[:videos].each do |video|
|
106
106
|
builder.video :video do
|
107
|
-
builder.video :thumbnail_loc, video[:thumbnail_loc]
|
108
|
-
builder.video :title, video[:title]
|
109
|
-
builder.video :description, video[:description]
|
110
|
-
builder.video :content_loc, video[:content_loc] if video[:content_loc]
|
107
|
+
builder.video :thumbnail_loc, video[:thumbnail_loc].to_s
|
108
|
+
builder.video :title, video[:title].to_s
|
109
|
+
builder.video :description, video[:description].to_s
|
110
|
+
builder.video :content_loc, video[:content_loc].to_s if video[:content_loc]
|
111
111
|
if video[:player_loc]
|
112
112
|
loc_attributes = { :allow_embed => yes_or_no_with_default(video[:allow_embed], true) }
|
113
|
-
loc_attributes[:autoplay] = video[:autoplay] if SitemapGenerator::Utilities.present?(video[:autoplay])
|
114
|
-
builder.video :player_loc, video[:player_loc], loc_attributes
|
113
|
+
loc_attributes[:autoplay] = video[:autoplay].to_s if SitemapGenerator::Utilities.present?(video[:autoplay])
|
114
|
+
builder.video :player_loc, video[:player_loc].to_s, loc_attributes
|
115
115
|
end
|
116
|
-
builder.video :duration, video[:duration] if video[:duration]
|
116
|
+
builder.video :duration, video[:duration].to_s if video[:duration]
|
117
117
|
builder.video :expiration_date, w3c_date(video[:expiration_date]) if video[:expiration_date]
|
118
118
|
builder.video :rating, format_float(video[:rating]) if video[:rating]
|
119
|
-
builder.video :view_count, video[:view_count] if video[:view_count]
|
119
|
+
builder.video :view_count, video[:view_count].to_s if video[:view_count]
|
120
120
|
builder.video :publication_date, w3c_date(video[:publication_date]) if video[:publication_date]
|
121
|
-
video[:tags].each {|tag| builder.video :tag, tag } if video[:tags]
|
122
|
-
builder.video :tag, video[:tag] if video[:tag]
|
123
|
-
builder.video :category, video[:category] if video[:category]
|
121
|
+
video[:tags].each {|tag| builder.video :tag, tag.to_s } if video[:tags]
|
122
|
+
builder.video :tag, video[:tag].to_s if video[:tag]
|
123
|
+
builder.video :category, video[:category].to_s if video[:category]
|
124
124
|
builder.video :family_friendly, yes_or_no_with_default(video[:family_friendly], true) if video.has_key?(:family_friendly)
|
125
|
-
builder.video :gallery_loc, video[:gallery_loc], :title => video[:gallery_title] if video[:gallery_loc]
|
125
|
+
builder.video :gallery_loc, video[:gallery_loc].to_s, :title => video[:gallery_title].to_s if video[:gallery_loc]
|
126
|
+
builder.video :price, video[:price].to_s, prepare_video_price_attribs(video) if SitemapGenerator::Utilities.present?(video[:price])
|
126
127
|
if video[:uploader]
|
127
|
-
builder.video :uploader, video[:uploader], video[:uploader_info] ? { :info => video[:uploader_info] } : {}
|
128
|
+
builder.video :uploader, video[:uploader].to_s, video[:uploader_info] ? { :info => video[:uploader_info].to_s } : {}
|
128
129
|
end
|
129
130
|
end
|
130
131
|
end
|
131
132
|
|
132
133
|
self[:alternates].each do |alternate|
|
133
134
|
rel = alternate[:nofollow] ? 'alternate nofollow' : 'alternate'
|
134
|
-
builder.xhtml :link, :rel => rel, :hreflang => alternate[:lang], :href => alternate[:href]
|
135
|
+
builder.xhtml :link, :rel => rel, :hreflang => alternate[:lang].to_s, :href => alternate[:href].to_s
|
135
136
|
end
|
136
137
|
|
137
138
|
unless SitemapGenerator::Utilities.blank?(self[:geo])
|
138
139
|
geo = self[:geo]
|
139
140
|
builder.geo :geo do
|
140
|
-
builder.geo :format, geo[:format] if geo[:format]
|
141
|
+
builder.geo :format, geo[:format].to_s if geo[:format]
|
141
142
|
end
|
142
143
|
end
|
143
144
|
|
@@ -148,9 +149,9 @@ module SitemapGenerator
|
|
148
149
|
unless SitemapGenerator::Utilities.blank?(self[:pagemap])
|
149
150
|
builder.pagemap :PageMap do
|
150
151
|
SitemapGenerator::Utilities.as_array(self[:pagemap][:dataobjects]).each do |dataobject|
|
151
|
-
builder.pagemap :DataObject, :type => dataobject[:type], :id => dataobject[:id] do
|
152
|
+
builder.pagemap :DataObject, :type => dataobject[:type].to_s, :id => dataobject[:id].to_s do
|
152
153
|
SitemapGenerator::Utilities.as_array(dataobject[:attributes]).each do |attribute|
|
153
|
-
builder.pagemap :Attribute, attribute[:value], :name => attribute[:name]
|
154
|
+
builder.pagemap :Attribute, attribute[:value].to_s, :name => attribute[:name].to_s
|
154
155
|
end
|
155
156
|
end
|
156
157
|
end
|
@@ -166,6 +167,14 @@ module SitemapGenerator
|
|
166
167
|
|
167
168
|
protected
|
168
169
|
|
170
|
+
def prepare_video_price_attribs(video)
|
171
|
+
attribs = {}
|
172
|
+
attribs[:currency] = video[:price_currency].to_s # required
|
173
|
+
attribs[:type] = video[:price_type] if SitemapGenerator::Utilities.present?(video[:price_type])
|
174
|
+
attribs[:resolution] = video[:price_resolution] if SitemapGenerator::Utilities.present?(video[:price_resolution])
|
175
|
+
attribs
|
176
|
+
end
|
177
|
+
|
169
178
|
def prepare_news(news)
|
170
179
|
SitemapGenerator::Utilities.assert_valid_keys(news, :publication_name, :publication_language, :publication_date, :genres, :access, :title, :keywords, :stock_tickers) unless news.empty?
|
171
180
|
news
|
@@ -34,7 +34,7 @@ module SitemapGenerator
|
|
34
34
|
set_options(opts)
|
35
35
|
if verbose
|
36
36
|
start_time = Time.now
|
37
|
-
puts "In #{sitemap_index.location.public_path}"
|
37
|
+
puts "In '#{sitemap_index.location.public_path}':"
|
38
38
|
end
|
39
39
|
interpreter.eval(:yield_sitemap => yield_sitemap?, &block)
|
40
40
|
finalize!
|
@@ -123,7 +123,7 @@ module SitemapGenerator
|
|
123
123
|
:include_index => false,
|
124
124
|
:filename => :sitemap,
|
125
125
|
:search_engines => {
|
126
|
-
:google => "http://www.google.com/webmasters/
|
126
|
+
:google => "http://www.google.com/webmasters/tools/ping?sitemap=%s",
|
127
127
|
:bing => "http://www.bing.com/webmaster/ping.aspx?siteMap=%s",
|
128
128
|
:sitemap_writer => "http://www.sitemapwriter.com/notify.php?crawler=all&url=%s"
|
129
129
|
},
|
@@ -285,7 +285,7 @@ module SitemapGenerator
|
|
285
285
|
index_url = CGI.escape(unescaped_url)
|
286
286
|
|
287
287
|
output("\n")
|
288
|
-
output("Pinging with URL #{unescaped_url}:")
|
288
|
+
output("Pinging with URL '#{unescaped_url}':")
|
289
289
|
search_engines.merge(engines).each do |engine, link|
|
290
290
|
link = link % index_url
|
291
291
|
name = Utilities.titleize(engine.to_s)
|
@@ -506,8 +506,10 @@ module SitemapGenerator
|
|
506
506
|
#
|
507
507
|
# Set to nil to use the current directory.
|
508
508
|
def public_path=(value)
|
509
|
-
@public_path = Pathname.new(value
|
510
|
-
|
509
|
+
@public_path = Pathname.new(SitemapGenerator::Utilities.append_slash(value))
|
510
|
+
if @public_path.relative?
|
511
|
+
@public_path = SitemapGenerator.app.root + @public_path
|
512
|
+
end
|
511
513
|
update_location_info(:public_path, @public_path)
|
512
514
|
@public_path
|
513
515
|
end
|
@@ -151,5 +151,16 @@ module SitemapGenerator
|
|
151
151
|
def falsy?(value)
|
152
152
|
['0', 0, 'f', 'false', false].include?(value)
|
153
153
|
end
|
154
|
+
|
155
|
+
# Append a slash to `path` if it does not already end in a slash.
|
156
|
+
# Returns a string. Expects a string or Pathname object.
|
157
|
+
def append_slash(path)
|
158
|
+
strpath = path.to_s
|
159
|
+
if strpath[-1] != nil && strpath[-1].chr != '/'
|
160
|
+
strpath + '/'
|
161
|
+
else
|
162
|
+
strpath
|
163
|
+
end
|
164
|
+
end
|
154
165
|
end
|
155
166
|
end
|
@@ -14,7 +14,7 @@ describe "SitemapGenerator" do
|
|
14
14
|
).to_xml
|
15
15
|
|
16
16
|
# Check that the options were parsed correctly
|
17
|
-
doc = Nokogiri::XML.parse("<root xmlns:geo='
|
17
|
+
doc = Nokogiri::XML.parse("<root xmlns:geo='#{SitemapGenerator::SCHEMAS['geo']}'>#{geo_xml_fragment}</root>")
|
18
18
|
url = doc.at_xpath("//url")
|
19
19
|
url.should_not be_nil
|
20
20
|
url.at_xpath("loc").text.should == loc
|
@@ -25,6 +25,6 @@ describe "SitemapGenerator" do
|
|
25
25
|
|
26
26
|
# Google's documentation and published schema don't match some valid elements may
|
27
27
|
# not validate.
|
28
|
-
xml_fragment_should_validate_against_schema(geo, '
|
28
|
+
xml_fragment_should_validate_against_schema(geo, 'sitemap-geo', 'xmlns:geo' => SitemapGenerator::SCHEMAS['geo'])
|
29
29
|
end
|
30
30
|
end
|
@@ -72,15 +72,26 @@ describe SitemapGenerator::LinkSet do
|
|
72
72
|
|
73
73
|
describe "sitemaps public_path" do
|
74
74
|
it "should default to public/" do
|
75
|
-
|
76
|
-
ls.
|
77
|
-
ls.
|
75
|
+
path = SitemapGenerator.app.root + 'public/'
|
76
|
+
ls.public_path.should == path
|
77
|
+
ls.sitemap.location.public_path.should == path
|
78
|
+
ls.sitemap_index.location.public_path.should == path
|
78
79
|
end
|
79
80
|
|
80
81
|
it "should change when the public_path is changed" do
|
82
|
+
path = SitemapGenerator.app.root + 'tmp/'
|
83
|
+
ls.public_path = 'tmp/'
|
84
|
+
ls.public_path.should == path
|
85
|
+
ls.sitemap.location.public_path.should == path
|
86
|
+
ls.sitemap_index.location.public_path.should == path
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should append a slash to the path" do
|
90
|
+
path = SitemapGenerator.app.root + 'tmp/'
|
81
91
|
ls.public_path = 'tmp'
|
82
|
-
ls.
|
83
|
-
ls.
|
92
|
+
ls.public_path.should == path
|
93
|
+
ls.sitemap.location.public_path.should == path
|
94
|
+
ls.sitemap_index.location.public_path.should == path
|
84
95
|
end
|
85
96
|
end
|
86
97
|
|
@@ -98,6 +109,13 @@ describe SitemapGenerator::LinkSet do
|
|
98
109
|
ls.sitemap.location.url.should == 'http://one.com/sitemaps/sitemap.xml.gz'
|
99
110
|
ls.sitemap_index.location.url.should == 'http://one.com/sitemaps/sitemap.xml.gz'
|
100
111
|
end
|
112
|
+
|
113
|
+
it "should append a slash to the path" do
|
114
|
+
ls.default_host = 'http://one.com'
|
115
|
+
ls.sitemaps_path = 'sitemaps'
|
116
|
+
ls.sitemap.location.url.should == 'http://one.com/sitemaps/sitemap.xml.gz'
|
117
|
+
ls.sitemap_index.location.url.should == 'http://one.com/sitemaps/sitemap.xml.gz'
|
118
|
+
end
|
101
119
|
end
|
102
120
|
|
103
121
|
describe "sitemap_index_url" do
|
@@ -317,7 +335,7 @@ describe SitemapGenerator::LinkSet do
|
|
317
335
|
path = 'new/path'
|
318
336
|
group = ls.group(:sitemaps_path => path)
|
319
337
|
group.sitemaps_path.should == path
|
320
|
-
group.sitemap.location.sitemaps_path.to_s.should == path
|
338
|
+
group.sitemap.location.sitemaps_path.to_s.should == 'new/path/'
|
321
339
|
end
|
322
340
|
end
|
323
341
|
|
@@ -489,7 +507,7 @@ describe SitemapGenerator::LinkSet do
|
|
489
507
|
path = 'new/path'
|
490
508
|
ls.create(:sitemaps_path => path)
|
491
509
|
ls.sitemaps_path.should == path
|
492
|
-
ls.sitemap.location.sitemaps_path.to_s.should == path
|
510
|
+
ls.sitemap.location.sitemaps_path.to_s.should == 'new/path/'
|
493
511
|
end
|
494
512
|
|
495
513
|
it "should set the default_host" do
|
@@ -12,7 +12,7 @@ describe "SitemapGenerator" do
|
|
12
12
|
).to_xml
|
13
13
|
|
14
14
|
# Check that the options were parsed correctly
|
15
|
-
doc = Nokogiri::XML.parse("<root xmlns:mobile='
|
15
|
+
doc = Nokogiri::XML.parse("<root xmlns:mobile='#{SitemapGenerator::SCHEMAS['mobile']}'>#{mobile_xml_fragment}</root>")
|
16
16
|
url = doc.at_xpath("//url")
|
17
17
|
url.should_not be_nil
|
18
18
|
url.at_xpath("loc").text.should == loc
|
@@ -22,6 +22,6 @@ describe "SitemapGenerator" do
|
|
22
22
|
|
23
23
|
# Google's documentation and published schema don't match some valid elements may
|
24
24
|
# not validate.
|
25
|
-
xml_fragment_should_validate_against_schema(mobile, '
|
25
|
+
xml_fragment_should_validate_against_schema(mobile, 'sitemap-mobile', 'xmlns:mobile' => SitemapGenerator::SCHEMAS['mobile'])
|
26
26
|
end
|
27
27
|
end
|
@@ -20,7 +20,7 @@ describe "SitemapGenerator" do
|
|
20
20
|
}
|
21
21
|
}).to_xml
|
22
22
|
|
23
|
-
doc = Nokogiri::XML.parse("<root xmlns:news='
|
23
|
+
doc = Nokogiri::XML.parse("<root xmlns:news='#{SitemapGenerator::SCHEMAS['news']}'>#{news_xml_fragment}</root>")
|
24
24
|
|
25
25
|
url = doc.at_xpath("//url")
|
26
26
|
loc = url.at_xpath("loc")
|
@@ -37,6 +37,6 @@ describe "SitemapGenerator" do
|
|
37
37
|
news.at_xpath("//news:name").text.should == "Example"
|
38
38
|
news.at_xpath("//news:language").text.should == "en"
|
39
39
|
|
40
|
-
xml_fragment_should_validate_against_schema(news, '
|
40
|
+
xml_fragment_should_validate_against_schema(news, 'sitemap-news', 'xmlns:news' => SitemapGenerator::SCHEMAS['news'])
|
41
41
|
end
|
42
42
|
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe "SitemapGenerator" do
|
4
|
-
|
4
|
+
let(:schema) { SitemapGenerator::SCHEMAS['pagemap'] }
|
5
|
+
|
5
6
|
it "should add the pagemap sitemap element" do
|
6
7
|
pagemap_xml_fragment = SitemapGenerator::Builder::SitemapUrl.new('my_page.html', {
|
7
8
|
:host => 'http://www.example.com',
|
@@ -9,42 +10,48 @@ describe "SitemapGenerator" do
|
|
9
10
|
:pagemap => {
|
10
11
|
:dataobjects => [
|
11
12
|
{
|
12
|
-
type
|
13
|
-
id
|
14
|
-
attributes
|
15
|
-
{name
|
16
|
-
{name
|
13
|
+
:type => 'document',
|
14
|
+
:id => 'hibachi',
|
15
|
+
:attributes => [
|
16
|
+
{:name => 'name', :value => 'Dragon'},
|
17
|
+
{:name => 'review', :value => 3.5},
|
17
18
|
]
|
18
19
|
},
|
19
20
|
{
|
20
|
-
type
|
21
|
-
attributes
|
22
|
-
{name
|
23
|
-
{name
|
21
|
+
:type => 'stats',
|
22
|
+
:attributes => [
|
23
|
+
{:name => 'installs', :value => 2000},
|
24
|
+
{:name => 'comments', :value => 200},
|
24
25
|
]
|
25
26
|
}
|
26
27
|
]
|
27
28
|
}
|
28
29
|
}).to_xml
|
29
30
|
|
31
|
+
# Nokogiri is a fickle beast. We have to add the namespace and define
|
32
|
+
# the prefix in order for XPath queries to work. And then we have to
|
33
|
+
# reingest because otherwise Nokogiri doesn't use it.
|
30
34
|
doc = Nokogiri::XML.parse(pagemap_xml_fragment)
|
31
|
-
|
35
|
+
doc.root.add_namespace_definition('pagemap', schema)
|
36
|
+
doc = Nokogiri::XML.parse(doc.to_xml)
|
37
|
+
|
32
38
|
url = doc.at_xpath("//url")
|
33
39
|
loc = url.at_xpath("loc")
|
34
40
|
loc.text.should == 'http://www.example.com/my_page.html'
|
35
|
-
|
36
|
-
pagemap =
|
37
|
-
pagemap.
|
38
|
-
pagemap.at_xpath('//DataObject')
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
41
|
+
|
42
|
+
pagemap = doc.at_xpath('//pagemap:PageMap', 'pagemap' => schema)
|
43
|
+
pagemap.element_children.count.should == 2
|
44
|
+
dataobject = pagemap.at_xpath('//pagemap:DataObject')
|
45
|
+
dataobject.attributes['type'].value.should == 'document'
|
46
|
+
dataobject.attributes['id'].value.should == 'hibachi'
|
47
|
+
dataobject.element_children.count.should == 2
|
48
|
+
first_attribute = dataobject.element_children.first
|
49
|
+
second_attribute = dataobject.element_children.last
|
43
50
|
first_attribute.text.should == 'Dragon'
|
44
51
|
first_attribute.attributes['name'].value.should == 'name'
|
45
52
|
second_attribute.text.should == '3.5'
|
46
53
|
second_attribute.attributes['name'].value.should == 'review'
|
47
54
|
|
48
|
-
xml_fragment_should_validate_against_schema(pagemap, '
|
55
|
+
xml_fragment_should_validate_against_schema(pagemap, 'sitemap-pagemap', 'xmlns:pagemap' => schema)
|
49
56
|
end
|
50
57
|
end
|
@@ -112,6 +112,37 @@ describe SitemapGenerator::SitemapLocation do
|
|
112
112
|
location.filesize
|
113
113
|
end
|
114
114
|
end
|
115
|
+
|
116
|
+
describe "public_path" do
|
117
|
+
it "should append a trailing slash" do
|
118
|
+
location = SitemapGenerator::SitemapLocation.new(:public_path => 'public/google')
|
119
|
+
location.public_path.to_s.should == 'public/google/'
|
120
|
+
location[:public_path] = 'new/path'
|
121
|
+
location.public_path.to_s.should == 'new/path/'
|
122
|
+
location[:public_path] = 'already/slashed/'
|
123
|
+
location.public_path.to_s.should == 'already/slashed/'
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe "sitemaps_path" do
|
128
|
+
it "should append a trailing slash" do
|
129
|
+
location = SitemapGenerator::SitemapLocation.new(:sitemaps_path => 'public/google')
|
130
|
+
location.sitemaps_path.to_s.should == 'public/google/'
|
131
|
+
location[:sitemaps_path] = 'new/path'
|
132
|
+
location.sitemaps_path.to_s.should == 'new/path/'
|
133
|
+
location[:sitemaps_path] = 'already/slashed/'
|
134
|
+
location.sitemaps_path.to_s.should == 'already/slashed/'
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe "url" do
|
139
|
+
it "should handle paths not ending in slash" do
|
140
|
+
location = SitemapGenerator::SitemapLocation.new(
|
141
|
+
:public_path => 'public/google', :filename => 'xxx',
|
142
|
+
:host => default_host, :sitemaps_path => 'sub/dir')
|
143
|
+
location.url.should == default_host + '/sub/dir/xxx'
|
144
|
+
end
|
145
|
+
end
|
115
146
|
end
|
116
147
|
|
117
148
|
describe SitemapGenerator::SitemapIndexLocation do
|
@@ -66,4 +66,14 @@ describe SitemapGenerator::Utilities do
|
|
66
66
|
SitemapGenerator::Utilities.as_array({}).should == [{}]
|
67
67
|
end
|
68
68
|
end
|
69
|
+
|
70
|
+
describe "append_slash" do
|
71
|
+
SitemapGenerator::Utilities.append_slash('').should == ''
|
72
|
+
SitemapGenerator::Utilities.append_slash(nil).should == ''
|
73
|
+
SitemapGenerator::Utilities.append_slash(Pathname.new('')).should == ''
|
74
|
+
SitemapGenerator::Utilities.append_slash('tmp').should == 'tmp/'
|
75
|
+
SitemapGenerator::Utilities.append_slash(Pathname.new('tmp')).should == 'tmp/'
|
76
|
+
SitemapGenerator::Utilities.append_slash('tmp/').should == 'tmp/'
|
77
|
+
SitemapGenerator::Utilities.append_slash(Pathname.new('tmp/')).should == 'tmp/'
|
78
|
+
end
|
69
79
|
end
|
@@ -28,7 +28,11 @@ describe "SitemapGenerator" do
|
|
28
28
|
:family_friendly => true,
|
29
29
|
:view_count => 123,
|
30
30
|
:duration => 456,
|
31
|
-
:rating => 0.499999999
|
31
|
+
:rating => 0.499999999,
|
32
|
+
:price => 123.45,
|
33
|
+
:price_currency => 'CAD',
|
34
|
+
:price_resolution => 'HD',
|
35
|
+
:price_type => 'rent'
|
32
36
|
}
|
33
37
|
end
|
34
38
|
|
@@ -42,7 +46,7 @@ describe "SitemapGenerator" do
|
|
42
46
|
|
43
47
|
# Return a Nokogiri document from the XML. The root of the document is the <URL> element.
|
44
48
|
def video_doc(xml)
|
45
|
-
Nokogiri::XML.parse("<root xmlns:video='
|
49
|
+
Nokogiri::XML.parse("<root xmlns:video='#{SitemapGenerator::SCHEMAS['video']}'>#{xml}</root>")
|
46
50
|
end
|
47
51
|
|
48
52
|
# Validate the contents of the video element
|
@@ -65,7 +69,11 @@ describe "SitemapGenerator" do
|
|
65
69
|
video_doc.at_xpath("video:player_loc").attribute('autoplay').text.should == video_options[:autoplay]
|
66
70
|
video_doc.at_xpath("video:uploader").text.should == video_options[:uploader]
|
67
71
|
video_doc.at_xpath("video:uploader").attribute("info").text.should == video_options[:uploader_info]
|
68
|
-
|
72
|
+
video_doc.at_xpath("video:price").text.should == video_options[:price].to_s
|
73
|
+
video_doc.at_xpath("video:price").attribute("resolution").text.should == video_options[:price_resolution].to_s
|
74
|
+
video_doc.at_xpath("video:price").attribute("type").text.should == video_options[:price_type].to_s
|
75
|
+
video_doc.at_xpath("video:price").attribute("currency").text.should == video_options[:price_currency].to_s
|
76
|
+
xml_fragment_should_validate_against_schema(video_doc, 'sitemap-video', 'xmlns:video' => SitemapGenerator::SCHEMAS['video'])
|
69
77
|
end
|
70
78
|
|
71
79
|
it "should add a valid video sitemap element" do
|
@@ -50,9 +50,19 @@
|
|
50
50
|
</xsd:restriction>
|
51
51
|
</xsd:simpleType>
|
52
52
|
|
53
|
-
<xsd:simpleType name="
|
54
|
-
<xsd:
|
55
|
-
<xsd:
|
53
|
+
<xsd:simpleType name="tPlatformList">
|
54
|
+
<xsd:annotation>
|
55
|
+
<xsd:documentation>
|
56
|
+
Space-separated platform names.
|
57
|
+
|
58
|
+
Platform names:
|
59
|
+
web - desktop and laptop browsers.
|
60
|
+
mobile - mobile devices such as phones and tablets.
|
61
|
+
tv - tv platforms such as GoogleTV.
|
62
|
+
</xsd:documentation>
|
63
|
+
</xsd:annotation>
|
64
|
+
<xsd:restriction base="xsd:string">
|
65
|
+
<xsd:pattern value="((web|mobile|tv)( (web|mobile|tv))*)?"/>
|
56
66
|
</xsd:restriction>
|
57
67
|
</xsd:simpleType>
|
58
68
|
|
@@ -63,11 +73,12 @@
|
|
63
73
|
<xsd:annotation>
|
64
74
|
<xsd:documentation>
|
65
75
|
A URL pointing to the URL for the video thumbnail image file. We can
|
66
|
-
accept most image sizes/types but recommend your
|
67
|
-
120x90 pixels in .jpg, .png, or. gif formats.
|
76
|
+
accept most image sizes/types but recommend your thumbnails are at
|
77
|
+
least 120x90 pixels in .jpg, .png, or. gif formats.
|
68
78
|
</xsd:documentation>
|
69
79
|
</xsd:annotation>
|
70
80
|
</xsd:element>
|
81
|
+
|
71
82
|
<xsd:element name="title">
|
72
83
|
<xsd:annotation>
|
73
84
|
<xsd:documentation>
|
@@ -80,6 +91,7 @@
|
|
80
91
|
</xsd:restriction>
|
81
92
|
</xsd:simpleType>
|
82
93
|
</xsd:element>
|
94
|
+
|
83
95
|
<xsd:element name="description">
|
84
96
|
<xsd:annotation>
|
85
97
|
<xsd:documentation>
|
@@ -92,6 +104,7 @@
|
|
92
104
|
</xsd:restriction>
|
93
105
|
</xsd:simpleType>
|
94
106
|
</xsd:element>
|
107
|
+
|
95
108
|
<xsd:element name="content_loc" minOccurs="0" type="xsd:anyURI">
|
96
109
|
<xsd:annotation>
|
97
110
|
<xsd:documentation>
|
@@ -107,6 +120,7 @@
|
|
107
120
|
</xsd:documentation>
|
108
121
|
</xsd:annotation>
|
109
122
|
</xsd:element>
|
123
|
+
|
110
124
|
<xsd:element name="player_loc" minOccurs="0">
|
111
125
|
<xsd:annotation>
|
112
126
|
<xsd:documentation>
|
@@ -148,6 +162,7 @@
|
|
148
162
|
</xsd:simpleContent>
|
149
163
|
</xsd:complexType>
|
150
164
|
</xsd:element>
|
165
|
+
|
151
166
|
<xsd:element name="duration" minOccurs="0">
|
152
167
|
<xsd:annotation>
|
153
168
|
<xsd:documentation>
|
@@ -160,6 +175,7 @@
|
|
160
175
|
</xsd:restriction>
|
161
176
|
</xsd:simpleType>
|
162
177
|
</xsd:element>
|
178
|
+
|
163
179
|
<xsd:element name="expiration_date" minOccurs="0">
|
164
180
|
<xsd:annotation>
|
165
181
|
<xsd:documentation>
|
@@ -181,6 +197,7 @@
|
|
181
197
|
</xsd:union>
|
182
198
|
</xsd:simpleType>
|
183
199
|
</xsd:element>
|
200
|
+
|
184
201
|
<xsd:element name="rating" minOccurs="0">
|
185
202
|
<xsd:annotation>
|
186
203
|
<xsd:documentation>
|
@@ -194,6 +211,7 @@
|
|
194
211
|
</xsd:restriction>
|
195
212
|
</xsd:simpleType>
|
196
213
|
</xsd:element>
|
214
|
+
|
197
215
|
<xsd:element name="content_segment_loc"
|
198
216
|
minOccurs="0"
|
199
217
|
maxOccurs="unbounded">
|
@@ -231,6 +249,7 @@
|
|
231
249
|
</xsd:simpleContent>
|
232
250
|
</xsd:complexType>
|
233
251
|
</xsd:element>
|
252
|
+
|
234
253
|
<xsd:element name="view_count"
|
235
254
|
minOccurs="0"
|
236
255
|
type="xsd:nonNegativeInteger">
|
@@ -240,6 +259,7 @@
|
|
240
259
|
</xsd:documentation>
|
241
260
|
</xsd:annotation>
|
242
261
|
</xsd:element>
|
262
|
+
|
243
263
|
<xsd:element name="publication_date" minOccurs="0">
|
244
264
|
<xsd:annotation>
|
245
265
|
<xsd:documentation>
|
@@ -260,6 +280,7 @@
|
|
260
280
|
</xsd:union>
|
261
281
|
</xsd:simpleType>
|
262
282
|
</xsd:element>
|
283
|
+
|
263
284
|
<xsd:element name="tag" type="xsd:string" minOccurs="0" maxOccurs="32">
|
264
285
|
<xsd:annotation>
|
265
286
|
<xsd:documentation>
|
@@ -273,10 +294,11 @@
|
|
273
294
|
</xsd:documentation>
|
274
295
|
</xsd:annotation>
|
275
296
|
</xsd:element>
|
297
|
+
|
276
298
|
<xsd:element name="category" minOccurs="0">
|
277
299
|
<xsd:annotation>
|
278
300
|
<xsd:documentation>
|
279
|
-
The video's category
|
301
|
+
The video's category - for example, cooking. In general, categories
|
280
302
|
are broad groupings of content by subject. For example, a site about
|
281
303
|
cooking could have categories for Broiling, Baking, and Grilling.
|
282
304
|
</xsd:documentation>
|
@@ -287,6 +309,7 @@
|
|
287
309
|
</xsd:restriction>
|
288
310
|
</xsd:simpleType>
|
289
311
|
</xsd:element>
|
312
|
+
|
290
313
|
<xsd:element name="family_friendly" minOccurs="0" type="tYesNo">
|
291
314
|
<xsd:annotation>
|
292
315
|
<xsd:documentation>
|
@@ -295,6 +318,7 @@
|
|
295
318
|
</xsd:documentation>
|
296
319
|
</xsd:annotation>
|
297
320
|
</xsd:element>
|
321
|
+
|
298
322
|
<xsd:element name="restriction" minOccurs="0">
|
299
323
|
<xsd:annotation>
|
300
324
|
<xsd:documentation>
|
@@ -324,6 +348,7 @@
|
|
324
348
|
</xsd:simpleContent>
|
325
349
|
</xsd:complexType>
|
326
350
|
</xsd:element>
|
351
|
+
|
327
352
|
<xsd:element name="gallery_loc" minOccurs="0">
|
328
353
|
<xsd:annotation>
|
329
354
|
<xsd:documentation>
|
@@ -345,21 +370,27 @@
|
|
345
370
|
</xsd:simpleContent>
|
346
371
|
</xsd:complexType>
|
347
372
|
</xsd:element>
|
373
|
+
|
348
374
|
<xsd:element name="price" minOccurs="0" maxOccurs="unbounded">
|
349
375
|
<xsd:annotation>
|
350
376
|
<xsd:documentation>
|
351
377
|
The price to download or view the video. More than one
|
352
378
|
<video:price> element can be listed (for example, in order to
|
353
|
-
specify various currencies).
|
379
|
+
specify various currencies). The price value must either be a
|
380
|
+
non-negative decimal or be empty. If a price value is specified, the
|
381
|
+
currency attribute is required. If no price value is specified, the
|
382
|
+
type attribute must be valid and present. The resolution attribute
|
383
|
+
is optional.
|
354
384
|
</xsd:documentation>
|
355
385
|
</xsd:annotation>
|
356
386
|
<xsd:complexType>
|
357
387
|
<xsd:simpleContent>
|
358
|
-
<xsd:extension base="
|
359
|
-
<xsd:attribute name="currency"
|
388
|
+
<xsd:extension base="xsd:string">
|
389
|
+
<xsd:attribute name="currency">
|
360
390
|
<xsd:annotation>
|
361
391
|
<xsd:documentation>
|
362
|
-
The currency in ISO 4217 format.
|
392
|
+
The currency in ISO 4217 format. This attribute is required
|
393
|
+
if a value is given for price.
|
363
394
|
</xsd:documentation>
|
364
395
|
</xsd:annotation>
|
365
396
|
<xsd:simpleType>
|
@@ -368,10 +399,42 @@
|
|
368
399
|
</xsd:restriction>
|
369
400
|
</xsd:simpleType>
|
370
401
|
</xsd:attribute>
|
402
|
+
<xsd:attribute name="type">
|
403
|
+
<xsd:annotation>
|
404
|
+
<xsd:documentation>
|
405
|
+
The type (purchase or rent) of price. This value is required
|
406
|
+
if there is no value given for price.
|
407
|
+
</xsd:documentation>
|
408
|
+
</xsd:annotation>
|
409
|
+
<xsd:simpleType>
|
410
|
+
<xsd:restriction base="xsd:string">
|
411
|
+
<xsd:enumeration value="purchase"/>
|
412
|
+
<xsd:enumeration value="PURCHASE"/>
|
413
|
+
<xsd:enumeration value="rent"/>
|
414
|
+
<xsd:enumeration value="RENT"/>
|
415
|
+
</xsd:restriction>
|
416
|
+
</xsd:simpleType>
|
417
|
+
</xsd:attribute>
|
418
|
+
<xsd:attribute name="resolution">
|
419
|
+
<xsd:annotation>
|
420
|
+
<xsd:documentation>
|
421
|
+
The resolution of the video at this price (SD or HD).
|
422
|
+
</xsd:documentation>
|
423
|
+
</xsd:annotation>
|
424
|
+
<xsd:simpleType>
|
425
|
+
<xsd:restriction base="xsd:string">
|
426
|
+
<xsd:enumeration value="sd"/>
|
427
|
+
<xsd:enumeration value="SD"/>
|
428
|
+
<xsd:enumeration value="hd"/>
|
429
|
+
<xsd:enumeration value="HD"/>
|
430
|
+
</xsd:restriction>
|
431
|
+
</xsd:simpleType>
|
432
|
+
</xsd:attribute>
|
371
433
|
</xsd:extension>
|
372
434
|
</xsd:simpleContent>
|
373
435
|
</xsd:complexType>
|
374
436
|
</xsd:element>
|
437
|
+
|
375
438
|
<xsd:element name="requires_subscription" minOccurs="0" type="tYesNo">
|
376
439
|
<xsd:annotation>
|
377
440
|
<xsd:documentation>
|
@@ -380,6 +443,7 @@
|
|
380
443
|
</xsd:documentation>
|
381
444
|
</xsd:annotation>
|
382
445
|
</xsd:element>
|
446
|
+
|
383
447
|
<xsd:element name="uploader" minOccurs="0">
|
384
448
|
<xsd:annotation>
|
385
449
|
<xsd:documentation>
|
@@ -402,8 +466,178 @@
|
|
402
466
|
</xsd:simpleContent>
|
403
467
|
</xsd:complexType>
|
404
468
|
</xsd:element>
|
469
|
+
|
470
|
+
<xsd:element name="tvshow" minOccurs="0">
|
471
|
+
<xsd:annotation>
|
472
|
+
<xsd:documentation>
|
473
|
+
Encloses all information about a single TV video.
|
474
|
+
</xsd:documentation>
|
475
|
+
</xsd:annotation>
|
476
|
+
<xsd:complexType>
|
477
|
+
<xsd:sequence>
|
478
|
+
<xsd:element name="show_title" type="xsd:string">
|
479
|
+
<xsd:annotation>
|
480
|
+
<xsd:documentation>
|
481
|
+
The title of the TV show. This should be the same for all
|
482
|
+
episodes from the same series.
|
483
|
+
</xsd:documentation>
|
484
|
+
</xsd:annotation>
|
485
|
+
</xsd:element>
|
486
|
+
<xsd:element name="video_type">
|
487
|
+
<xsd:annotation>
|
488
|
+
<xsd:documentation>
|
489
|
+
Describes the relationship of the video to the specified
|
490
|
+
TV show/episode.
|
491
|
+
</xsd:documentation>
|
492
|
+
</xsd:annotation>
|
493
|
+
<xsd:simpleType>
|
494
|
+
<xsd:restriction base="xsd:string">
|
495
|
+
<!-- Complete episode -->
|
496
|
+
<xsd:enumeration value="full"/>
|
497
|
+
<!-- Episode promo -->
|
498
|
+
<xsd:enumeration value="preview"/>
|
499
|
+
<!-- Episode clip -->
|
500
|
+
<xsd:enumeration value="clip"/>
|
501
|
+
<!-- Interview -->
|
502
|
+
<xsd:enumeration value="interview"/>
|
503
|
+
<!-- News related to the content -->
|
504
|
+
<xsd:enumeration value="news"/>
|
505
|
+
<!-- If none of the above options accurately describe
|
506
|
+
the relationship -->
|
507
|
+
<xsd:enumeration value="other"/>
|
508
|
+
</xsd:restriction>
|
509
|
+
</xsd:simpleType>
|
510
|
+
</xsd:element>
|
511
|
+
<xsd:element name="episode_title" type="xsd:string" minOccurs="0">
|
512
|
+
<xsd:annotation>
|
513
|
+
<xsd:documentation>
|
514
|
+
The title of the episode—for example, "Flesh and Bone" is the
|
515
|
+
title of the Season 1, Episode 8 episode of Battlestar
|
516
|
+
Galactica. This tag is not necessary if the video is not
|
517
|
+
related to a specific episode (for example, if it's a trailer
|
518
|
+
for an entire series or season).
|
519
|
+
</xsd:documentation>
|
520
|
+
</xsd:annotation>
|
521
|
+
</xsd:element>
|
522
|
+
<xsd:element name="season_number" minOccurs="0">
|
523
|
+
<xsd:annotation>
|
524
|
+
<xsd:documentation>
|
525
|
+
Only for shows with a per-season schedule.
|
526
|
+
</xsd:documentation>
|
527
|
+
</xsd:annotation>
|
528
|
+
<xsd:simpleType>
|
529
|
+
<xsd:restriction base="xsd:integer">
|
530
|
+
<xsd:minInclusive value="1"/>
|
531
|
+
</xsd:restriction>
|
532
|
+
</xsd:simpleType>
|
533
|
+
</xsd:element>
|
534
|
+
<xsd:element name="episode_number" minOccurs="0">
|
535
|
+
<xsd:annotation>
|
536
|
+
<xsd:documentation>
|
537
|
+
The episode number in number format. For TV shoes with a
|
538
|
+
per-season schedule, the first episode of each series should
|
539
|
+
be numbered 1.
|
540
|
+
</xsd:documentation>
|
541
|
+
</xsd:annotation>
|
542
|
+
<xsd:simpleType>
|
543
|
+
<xsd:restriction base="xsd:integer">
|
544
|
+
<xsd:minInclusive value="1"/>
|
545
|
+
</xsd:restriction>
|
546
|
+
</xsd:simpleType>
|
547
|
+
</xsd:element>
|
548
|
+
<xsd:element name="premier_date" minOccurs="0">
|
549
|
+
<xsd:annotation>
|
550
|
+
<xsd:documentation>
|
551
|
+
The date the content of the video was first broadcast, in
|
552
|
+
W3C format (for example, 2010-11-05.)
|
553
|
+
</xsd:documentation>
|
554
|
+
</xsd:annotation>
|
555
|
+
<xsd:simpleType>
|
556
|
+
<xsd:union>
|
557
|
+
<xsd:simpleType>
|
558
|
+
<xsd:restriction base="xsd:date"/>
|
559
|
+
</xsd:simpleType>
|
560
|
+
<xsd:simpleType>
|
561
|
+
<xsd:restriction base="xsd:dateTime"/>
|
562
|
+
</xsd:simpleType>
|
563
|
+
</xsd:union>
|
564
|
+
</xsd:simpleType>
|
565
|
+
</xsd:element>
|
566
|
+
</xsd:sequence>
|
567
|
+
</xsd:complexType>
|
568
|
+
</xsd:element>
|
569
|
+
|
570
|
+
<xsd:element name="platform" minOccurs="0">
|
571
|
+
<xsd:annotation>
|
572
|
+
<xsd:documentation>
|
573
|
+
A list of platforms where the video may or may not be played.
|
574
|
+
If there is no <video:platform> tag, it is assumed that
|
575
|
+
the video can be played on all platforms.
|
576
|
+
</xsd:documentation>
|
577
|
+
</xsd:annotation>
|
578
|
+
<xsd:complexType>
|
579
|
+
<xsd:simpleContent>
|
580
|
+
<xsd:extension base="tPlatformList">
|
581
|
+
<xsd:attribute name="relationship" use="required">
|
582
|
+
<xsd:annotation>
|
583
|
+
<xsd:documentation>
|
584
|
+
Attribute "relationship" specifies whether the video is
|
585
|
+
restricted or permitted for the specified platforms.
|
586
|
+
</xsd:documentation>
|
587
|
+
</xsd:annotation>
|
588
|
+
<xsd:simpleType>
|
589
|
+
<xsd:restriction base="xsd:string">
|
590
|
+
<xsd:enumeration value="allow"/>
|
591
|
+
<xsd:enumeration value="deny"/>
|
592
|
+
</xsd:restriction>
|
593
|
+
</xsd:simpleType>
|
594
|
+
</xsd:attribute>
|
595
|
+
</xsd:extension>
|
596
|
+
</xsd:simpleContent>
|
597
|
+
</xsd:complexType>
|
598
|
+
</xsd:element>
|
599
|
+
|
600
|
+
<xsd:element name="live" minOccurs="0" type="tYesNo">
|
601
|
+
<xsd:annotation>
|
602
|
+
<xsd:documentation>
|
603
|
+
Whether the video is a live internet broadcast.
|
604
|
+
</xsd:documentation>
|
605
|
+
</xsd:annotation>
|
606
|
+
</xsd:element>
|
607
|
+
|
608
|
+
<xsd:element name="id" minOccurs="0" maxOccurs="unbounded">
|
609
|
+
<xsd:annotation>
|
610
|
+
<xsd:documentation>
|
611
|
+
An unambiguous identifier for the video within a given
|
612
|
+
identification context.
|
613
|
+
</xsd:documentation>
|
614
|
+
</xsd:annotation>
|
615
|
+
<xsd:complexType>
|
616
|
+
<xsd:simpleContent>
|
617
|
+
<xsd:extension base="xsd:string">
|
618
|
+
<xsd:attribute name="type" use="required">
|
619
|
+
<xsd:annotation>
|
620
|
+
<xsd:documentation>
|
621
|
+
The identification context.
|
622
|
+
</xsd:documentation>
|
623
|
+
</xsd:annotation>
|
624
|
+
<xsd:simpleType>
|
625
|
+
<xsd:restriction base="xsd:string">
|
626
|
+
<xsd:enumeration value="tms:series"/>
|
627
|
+
<xsd:enumeration value="tms:program"/>
|
628
|
+
<xsd:enumeration value="rovi:series"/>
|
629
|
+
<xsd:enumeration value="rovi:program"/>
|
630
|
+
<xsd:enumeration value="freebase"/>
|
631
|
+
<xsd:enumeration value="url"/>
|
632
|
+
</xsd:restriction>
|
633
|
+
</xsd:simpleType>
|
634
|
+
</xsd:attribute>
|
635
|
+
</xsd:extension>
|
636
|
+
</xsd:simpleContent>
|
637
|
+
</xsd:complexType>
|
638
|
+
</xsd:element>
|
405
639
|
</xsd:sequence>
|
406
640
|
</xsd:complexType>
|
407
641
|
</xsd:element>
|
408
642
|
|
409
|
-
</xsd:schema>
|
643
|
+
</xsd:schema>
|
data/spec/support/xml_macros.rb
CHANGED
@@ -8,6 +8,10 @@ module XmlMacros
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
+
# Validate XML against a local schema file.
|
12
|
+
#
|
13
|
+
# `schema_name` gives the name of the schema file to validate against. The schema
|
14
|
+
# file is looked for in `spec/support/schemas/<schema_name>.xsd`.
|
11
15
|
def xml_data_should_validate_against_schema(xml, schema_name)
|
12
16
|
xml = xml.is_a?(String) ? xml : xml.to_s
|
13
17
|
doc = Nokogiri::XML(xml)
|
@@ -26,15 +30,23 @@ module XmlMacros
|
|
26
30
|
#
|
27
31
|
# Element 'video': No matching global declaration available for the validation root.
|
28
32
|
#
|
29
|
-
# <tt>
|
30
|
-
# <tt>
|
33
|
+
# <tt>xml</tt> The XML fragment
|
34
|
+
# <tt>schema_name</tt> the name of the schema file to validate against. The schema
|
35
|
+
# file is looked for in `spec/support/schemas/<schema_name>.xsd`.
|
36
|
+
# <tt>xmlns</tt> A hash with only one key which gives the XML namespace and associated
|
37
|
+
# URI. Sometimes one needs to specify a prefix to the namespace, in which case this would
|
38
|
+
# look like: 'xmlns:video' => 'http://www.google.com/schemas/sitemap-video/1.1'
|
31
39
|
#
|
32
40
|
# Example:
|
33
|
-
#
|
34
|
-
|
41
|
+
# xml_fragment_should_validate_against_schema('<video/>', 'sitemap-video', 'xmlns:video' => 'http://www.google.com/schemas/sitemap-video/1.1')
|
42
|
+
#
|
43
|
+
# This validates the given XML using the spec/support/schemas/sitemap-video.xsd`
|
44
|
+
# schema. The XML namespace `xmlns:video='http://www.google.com/schemas/sitemap-video/1.1'` is automatically
|
45
|
+
# added to the root element for you.
|
46
|
+
def xml_fragment_should_validate_against_schema(xml, schema_name, xmlns={})
|
35
47
|
xml = xml.is_a?(String) ? xml : xml.to_s
|
36
48
|
doc = Nokogiri::XML(xml)
|
37
|
-
doc.root[
|
49
|
+
doc.root.send(:[]=, *xmlns.first)
|
38
50
|
xml_data_should_validate_against_schema(doc, schema_name)
|
39
51
|
end
|
40
52
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sitemap_generator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.2.0
|
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: 2013-
|
12
|
+
date: 2013-08-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: mocha
|
@@ -183,7 +183,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
183
183
|
version: '0'
|
184
184
|
segments:
|
185
185
|
- 0
|
186
|
-
hash:
|
186
|
+
hash: 629438297049129393
|
187
187
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
188
188
|
none: false
|
189
189
|
requirements:
|
@@ -192,7 +192,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
192
192
|
version: '0'
|
193
193
|
segments:
|
194
194
|
- 0
|
195
|
-
hash:
|
195
|
+
hash: 629438297049129393
|
196
196
|
requirements: []
|
197
197
|
rubyforge_project:
|
198
198
|
rubygems_version: 1.8.25
|