vast 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Chris Dinn
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,45 @@
1
+ VAST
2
+ =====
3
+
4
+ A library for parsing Digital Video Ad Serving Template (VAST) documents, as outlined by the Interactive Advertising Bureau at
5
+ [http://www.iab.net/iab_products_and_industry_services/508676/digitalvideo/vast]. This library strives to be as true to the
6
+ standard as possible, while presenting a Ruby-friendly interface.
7
+
8
+ VAST outlines a standard document format for communication between digital video players and ad servers, including support for
9
+ multiple forms of creative and tracking support that conforms to the latest IAB standards.
10
+
11
+ Installation
12
+ ------------
13
+
14
+ VAST is available as a RubyGem.
15
+
16
+ gem install vast
17
+
18
+ Usage
19
+ -----
20
+
21
+ Parse a VAST document and access it's contents easily. See the documentation for the individual classes for an overview of
22
+ what information available for each class.
23
+
24
+ document = VAST::Document.parse(File.read("vast_document.xml"))
25
+
26
+ Problems/Bugs/Requests
27
+ -----------------------------
28
+
29
+ Please, file an issue.
30
+
31
+ Note on Patches/Pull Requests
32
+ -----------------------------
33
+
34
+ * Fork the project.
35
+ * Make your feature addition or bug fix.
36
+ * Add tests for it. This is important so I don't break it in a
37
+ future version unintentionally.
38
+ * Commit, do not mess with rakefile, version, or history.
39
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
40
+ * Send me a pull request. Bonus points for topic branches.
41
+
42
+ Copyright
43
+ -----------------------------
44
+
45
+ © 2010 Chris Dinn. See [LICENSE](http://github.com/chrisdinn/vast/blob/master/LICENSE) for details.
@@ -0,0 +1,43 @@
1
+ = VAST
2
+
3
+ A library for parsing Digital Video Ad Serving Template (VAST) documents, as outlined by the Interactive Advertising Bureau at
4
+ http://www.iab.net/iab_products_and_industry_services/508676/digitalvideo/vast. This library strives to be as true to the
5
+ standard as possible, while presenting a Ruby-friendly interface.
6
+
7
+ VAST outlines a standard document format for communication between digital video players and ad servers, including support for
8
+ multiple forms of creative and tracking support that conforms to the latest IAB standards.
9
+
10
+ == Installation
11
+
12
+ VAST is available as a RubyGem.
13
+
14
+ gem install vast
15
+
16
+ == Usage
17
+
18
+ Parse a VAST document and access it's contents easily. See the documentation for the individual classes for an overview of
19
+ what information available for each class.
20
+
21
+ document = VAST::Document.parse(File.read("vast_document.xml"))
22
+
23
+ == Documentation
24
+
25
+ Read the rdoc at http://rdoc.info/projects/chrisdinn/vast
26
+
27
+ == Problems/Bugs/Requests
28
+
29
+ Please, file an issue.
30
+
31
+ == Note on Patches/Pull Requests
32
+
33
+ * Fork the project.
34
+ * Make your feature addition or bug fix.
35
+ * Add tests for it. This is important so I don't break it in a
36
+ future version unintentionally.
37
+ * Commit, do not mess with rakefile, version, or history.
38
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
39
+ * Send me a pull request. Bonus points for topic branches.
40
+
41
+ == Copyright
42
+
43
+ © 2010 Chris Dinn. See LICENSE for details.
@@ -0,0 +1,22 @@
1
+ require 'vast/document'
2
+ require 'vast/ad'
3
+ require 'vast/inline_ad'
4
+ require 'vast/creative'
5
+ require 'vast/linear_creative'
6
+ require 'vast/mediafile'
7
+
8
+ # This module wraps VAST documents, as outlined by the IAB at http://www.iab.net/media/file/VAST-2_0-FINAL.pdf
9
+ module VAST
10
+ VAST_VERSION = 2.0
11
+ VAST_SCHEMA_XSD_FILE = File.expand_path(File.join(File.dirname(__FILE__), 'vast_2.0.1.xsd'))
12
+
13
+ # Raised when parsing a VAST document that does not conform to the VAST spec XSD
14
+ class InvalidDocumentError < StandardError; end
15
+
16
+ # Raised when parsing a VAST ad node that is not complete
17
+ class InvalidAdError < StandardError; end
18
+
19
+ # Raised when parsing a VAST creative node that is not complete
20
+ class InvalidCreativeError < StandardError; end
21
+
22
+ end
@@ -0,0 +1,78 @@
1
+ module VAST
2
+ class Ad
3
+ attr_reader :source_node
4
+
5
+ def initialize(node)
6
+ @source_node = node
7
+ end
8
+
9
+ # Create proper ad type
10
+ def self.create(node)
11
+ if node.at('InLine')
12
+ InlineAd.new(node)
13
+ elsif node.at('Wrapper')
14
+ WrapperAd.new(node)
15
+ else
16
+ raise InvalidAdError
17
+ end
18
+ end
19
+
20
+ # Ad id, if indicated
21
+ def id
22
+ @source_node[:id]
23
+ end
24
+
25
+ # Name of source ad server
26
+ def ad_system
27
+ ad_system_node = @source_node.at("AdSystem")
28
+ if ad_system_node
29
+ ad_system_node.content
30
+ else
31
+ raise InvalidAdError, "missing AdSystem node in Ad"
32
+ end
33
+ end
34
+
35
+ # URI to request if ad does not play due to error
36
+ def error_url
37
+ error_url_node = @source_node.at("Error")
38
+ URI.parse(error_url_node.content) if error_url_node
39
+ end
40
+
41
+ # Returns an array containing all linear creatives
42
+ def linear_creatives
43
+ @source_node.xpath('.//Creative/Linear').to_a.collect do |node|
44
+ LinearCreative.new(node)
45
+ end
46
+ end
47
+
48
+ # Returns an array containing all non linear creatives
49
+ def non_linear_creatives
50
+ @source_node.xpath('.//Creative/NonLinearAds/NonLinear').to_a.collect do |node|
51
+ NonLinearCreative.new(node)
52
+ end
53
+ end
54
+
55
+ # Returns an array containing all companion creatives
56
+ def companion_creatives
57
+ @source_node.xpath('.//Creative/CompanionAds/Companion').to_a.collect do |node|
58
+ CompanionCreative.new(node)
59
+ end
60
+ end
61
+
62
+ # Each Ad should contain at least one impression.
63
+ def impression
64
+ URI.parse(@source_node.at('Impression').content)
65
+ end
66
+
67
+ # Array of all impressions available for this ad, excluding those specific
68
+ # to a particular creative.
69
+ def impressions
70
+ @source_node.xpath('.//Impression').to_a.collect do |node|
71
+ URI.parse(node)
72
+ end
73
+ end
74
+
75
+ end
76
+
77
+ class WrapperAd < Ad; end
78
+ end
@@ -0,0 +1,59 @@
1
+ module VAST
2
+ class Creative
3
+ attr_reader :source_node
4
+
5
+ def initialize(node)
6
+ @source_node = node
7
+ end
8
+
9
+ def ad
10
+ Ad.create @source_node.ancestors('Ad').first
11
+ end
12
+
13
+ def id
14
+ creative_node[:id]
15
+ end
16
+
17
+ def ad_id
18
+ creative_node[:AdID]
19
+ end
20
+
21
+ # The preferred order in which multiple Creatives should be displayed
22
+ def sequence
23
+ creative_node[:sequence]
24
+ end
25
+
26
+ # Data to be passed into the video ad.
27
+ def ad_parameters
28
+ @source_node.at('AdParameters').content
29
+ end
30
+
31
+ def tracking_urls
32
+ tracking_urls = {}
33
+ @source_node.xpath('.//Tracking').to_a.collect do |node|
34
+ underscored_name = underscore(node[:event])
35
+ tracking_urls[underscored_name.to_sym] = URI.parse(node.content)
36
+ end
37
+ tracking_urls
38
+ end
39
+
40
+ protected
41
+
42
+ def underscore(camel_cased_word)
43
+ camel_cased_word.to_s.gsub(/::/, '/').
44
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
45
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
46
+ tr("-", "_").
47
+ downcase
48
+ end
49
+
50
+ private
51
+
52
+ def creative_node
53
+ @source_node.ancestors('Creative').first
54
+ end
55
+ end
56
+
57
+ class NonLinearCreative < Creative; end
58
+ class CompanionCreative < Creative; end
59
+ end
@@ -0,0 +1,40 @@
1
+ module VAST
2
+ class Document < Nokogiri::XML::Document
3
+
4
+ # Parse a VAST XML document
5
+ def self.parse(*args)
6
+ super(*args)
7
+ end
8
+
9
+ # Same as parse, but raises InvalidDocumentError if document is not valid
10
+ def self.parse!(*args)
11
+ document = parse(*args)
12
+ raise InvalidDocumentError unless document.valid?
13
+ document
14
+ end
15
+
16
+ # Checks whether document conforms to the VAST XML Schema Definitions, accessible at
17
+ # http://www.iab.net/iab_products_and_industry_services/508676/digitalvideo/vast
18
+ def valid?
19
+ xsd = Nokogiri::XML::Schema(File.read(VAST_SCHEMA_XSD_FILE))
20
+ xsd.valid?(self)
21
+ end
22
+
23
+ # All ads in the document
24
+ def ads
25
+ self.root.xpath('.//Ad').to_a.collect do |node|
26
+ Ad.create(node)
27
+ end
28
+ end
29
+
30
+ # All inline ads
31
+ def inline_ads
32
+ ads.select{ |ad| ad.kind_of?(VAST::InlineAd) }
33
+ end
34
+
35
+ # All wrapper ads
36
+ def wrapper_ads
37
+ ads.select{ |ad| ad.kind_of?(VAST::WrapperAd) }
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,15 @@
1
+ module VAST
2
+ class InlineAd < Ad
3
+
4
+ # URI of request to survey vendor
5
+ def survey_url
6
+ URI.parse @source_node.at('Survey').content
7
+ end
8
+
9
+ # Common name of ad
10
+ def ad_title
11
+ @source_node.at('AdTitle').content
12
+ end
13
+ end
14
+ end
15
+
@@ -0,0 +1,39 @@
1
+ module VAST
2
+ class LinearCreative < Creative
3
+
4
+ # Duration of creative
5
+ def duration
6
+ @source_node.at('Duration').content
7
+ end
8
+
9
+ # URI to open as destination page when user clicks on the video
10
+ def click_through_url
11
+ URI.parse @source_node.at('ClickThrough').content
12
+ end
13
+
14
+ # An array of URIs to request for tracking purposes when user clicks on the video
15
+ def click_tracking_urls
16
+ @source_node.xpath('.//ClickTracking').to_a.collect do |node|
17
+ URI.parse node.content
18
+ end
19
+ end
20
+
21
+ # A hash of URIs to request on custom events such as hotspotted video. This library
22
+ # required custom click urls to identify themselves with an `id` attribute, which is
23
+ # used as the key for this hash
24
+ def custom_click_urls
25
+ custom_click_urls = {}
26
+ @source_node.xpath('.//CustomClick').to_a.collect do |node|
27
+ key = underscore(node[:id]).to_sym
28
+ custom_click_urls[key] = URI.parse(node.content)
29
+ end
30
+ custom_click_urls
31
+ end
32
+
33
+ def mediafiles
34
+ @source_node.xpath('.//MediaFile').to_a.collect do |node|
35
+ Mediafile.new(node)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,54 @@
1
+ module VAST
2
+ class Mediafile
3
+ attr_reader :source_node
4
+
5
+ def initialize(node)
6
+ @source_node = node
7
+ end
8
+
9
+ # Location of linear file
10
+ def url
11
+ URI.parse @source_node.content
12
+ end
13
+
14
+ def id
15
+ @source_node[:id]
16
+ end
17
+
18
+ # Method of delivery of ad, either "streaming" or "progressive"
19
+ def delivery
20
+ @source_node[:delivery]
21
+ end
22
+
23
+ # MIME type. Popular MIME types include, but are not limited to “video/x-ms-wmv” for
24
+ # Windows Media, and “video/x-flv” for Flash Video.
25
+ def type
26
+ @source_node[:type]
27
+ end
28
+
29
+ # Bitrate of encoded video in Kbps
30
+ def bitrate
31
+ @source_node[:bitrate].to_i
32
+ end
33
+
34
+ # Pixel dimensions of video width
35
+ def width
36
+ @source_node[:width].to_i
37
+ end
38
+
39
+ # Pixel dimensions of video height
40
+ def height
41
+ @source_node[:height].to_i
42
+ end
43
+
44
+ # Whether it is acceptable to scale the image.
45
+ def scalable?
46
+ @source_node[:scalable]=="true"
47
+ end
48
+
49
+ # Whether the ad must have its aspect ratio maintained when scaled
50
+ def maintain_aspect_ratio?
51
+ @source_node[:maintainAspectRatio]=="true"
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,643 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
3
+ attributeFormDefault="unqualified">
4
+ <xs:element name="VAST">
5
+ <xs:annotation>
6
+ <xs:documentation>IAB VAST, Video Ad Serving Template, video xml ad response, Version 2.0.1, xml schema prepared by Tremor Media</xs:documentation>
7
+ </xs:annotation>
8
+ <xs:complexType>
9
+ <xs:sequence>
10
+ <xs:element name="Ad" maxOccurs="unbounded" minOccurs="0">
11
+ <xs:annotation>
12
+ <xs:documentation>Top-level element, wraps each ad in the response</xs:documentation>
13
+ </xs:annotation>
14
+ <xs:complexType>
15
+ <xs:choice maxOccurs="1" minOccurs="1">
16
+ <xs:element name="InLine" maxOccurs="1" minOccurs="0">
17
+ <xs:annotation>
18
+ <xs:documentation>Second-level element surrounding complete ad data for a single ad</xs:documentation>
19
+ </xs:annotation>
20
+ <xs:complexType>
21
+ <xs:sequence>
22
+ <xs:element name="AdSystem" maxOccurs="1" minOccurs="1"
23
+ type="AdSystem_type">
24
+ <xs:annotation>
25
+ <xs:documentation>Indicates source ad server</xs:documentation>
26
+ </xs:annotation>
27
+ </xs:element>
28
+ <xs:element name="AdTitle" type="xs:string" maxOccurs="1"
29
+ minOccurs="1">
30
+ <xs:annotation>
31
+ <xs:documentation>Common name of ad</xs:documentation>
32
+ </xs:annotation>
33
+ </xs:element>
34
+ <xs:element name="Description" type="xs:string"
35
+ minOccurs="0" maxOccurs="1">
36
+ <xs:annotation>
37
+ <xs:documentation>Longer description of ad</xs:documentation>
38
+ </xs:annotation>
39
+ </xs:element>
40
+ <xs:element name="Survey" type="xs:anyURI" minOccurs="0"
41
+ maxOccurs="1">
42
+ <xs:annotation>
43
+ <xs:documentation>URL of request to survey vendor</xs:documentation>
44
+ </xs:annotation>
45
+ </xs:element>
46
+ <xs:element name="Error" type="xs:anyURI" minOccurs="0"
47
+ maxOccurs="1">
48
+ <xs:annotation>
49
+ <xs:documentation>URL to request if ad does not play due to error</xs:documentation>
50
+ </xs:annotation>
51
+ </xs:element>
52
+ <xs:element name="Impression" type="Impression_type"
53
+ maxOccurs="unbounded" minOccurs="1">
54
+ <xs:annotation>
55
+ <xs:documentation>URL to track impression</xs:documentation>
56
+ </xs:annotation>
57
+ </xs:element>
58
+ <xs:element maxOccurs="1" minOccurs="1" name="Creatives">
59
+ <xs:annotation>
60
+ <xs:documentation>Any number of companions in any desired pixel dimensions.</xs:documentation>
61
+ </xs:annotation>
62
+ <xs:complexType>
63
+ <xs:sequence>
64
+ <xs:element name="Creative" maxOccurs="unbounded">
65
+ <xs:annotation>
66
+ <xs:documentation>Wraps each creative element within an InLine or Wrapper Ad</xs:documentation>
67
+ </xs:annotation>
68
+ <xs:complexType>
69
+ <xs:choice>
70
+ <xs:element name="Linear" minOccurs="0"
71
+ maxOccurs="1">
72
+ <xs:complexType>
73
+ <xs:sequence>
74
+ <xs:element name="Duration" type="xs:time"
75
+ maxOccurs="1" minOccurs="1">
76
+ <xs:annotation>
77
+ <xs:documentation>Duration in standard time format, hh:mm:ss</xs:documentation>
78
+ </xs:annotation>
79
+ </xs:element>
80
+ <xs:element name="TrackingEvents" minOccurs="0"
81
+ type="TrackingEvents_type" maxOccurs="1"> </xs:element>
82
+ <xs:element name="AdParameters" type="xs:string"
83
+ minOccurs="0" maxOccurs="1">
84
+ <xs:annotation>
85
+ <xs:documentation>Data to be passed into the video ad</xs:documentation>
86
+ </xs:annotation>
87
+ </xs:element>
88
+ <xs:element name="VideoClicks" minOccurs="0"
89
+ type="VideoClicks_type" maxOccurs="1"> </xs:element>
90
+ <xs:element name="MediaFiles" minOccurs="0"
91
+ maxOccurs="1">
92
+ <xs:complexType>
93
+ <xs:sequence>
94
+ <xs:element name="MediaFile" minOccurs="1"
95
+ maxOccurs="unbounded">
96
+ <xs:annotation>
97
+ <xs:documentation>Location of linear file</xs:documentation>
98
+ </xs:annotation>
99
+ <xs:complexType>
100
+ <xs:simpleContent>
101
+ <xs:extension base="xs:anyURI">
102
+ <xs:attribute name="id" type="xs:string"
103
+ use="optional">
104
+ <xs:annotation>
105
+ <xs:documentation>Optional identifier</xs:documentation>
106
+ </xs:annotation>
107
+ </xs:attribute>
108
+ <xs:attribute name="delivery" use="required">
109
+ <xs:annotation>
110
+ <xs:documentation>Method of delivery of ad</xs:documentation>
111
+ </xs:annotation>
112
+ <xs:simpleType>
113
+ <xs:restriction base="xs:NMTOKEN">
114
+ <xs:enumeration value="streaming"/>
115
+ <xs:enumeration value="progressive"/>
116
+ </xs:restriction>
117
+ </xs:simpleType>
118
+ </xs:attribute>
119
+ <xs:attribute name="type" use="required"
120
+ type="xs:string">
121
+ <xs:annotation>
122
+ <xs:documentation>MIME type. Popular MIME types include, but are not limited to “video/x-ms-wmv” for Windows Media, and “video/x-flv” for Flash Video. Image ads or interactive ads can be included in the MediaFiles section with appropriate Mime types</xs:documentation>
123
+ </xs:annotation>
124
+ </xs:attribute>
125
+ <xs:attribute name="bitrate" type="xs:integer"
126
+ use="optional">
127
+ <xs:annotation>
128
+ <xs:documentation>Bitrate of encoded video in Kbps</xs:documentation>
129
+ </xs:annotation>
130
+ </xs:attribute>
131
+ <xs:attribute name="width" type="xs:integer"
132
+ use="required">
133
+ <xs:annotation>
134
+ <xs:documentation>Pixel dimensions of video</xs:documentation>
135
+ </xs:annotation>
136
+ </xs:attribute>
137
+ <xs:attribute name="height" type="xs:integer"
138
+ use="required">
139
+ <xs:annotation>
140
+ <xs:documentation>Pixel dimensions of video</xs:documentation>
141
+ </xs:annotation>
142
+ </xs:attribute>
143
+ <xs:attribute name="scalable" type="xs:boolean"
144
+ use="optional">
145
+ <xs:annotation>
146
+ <xs:documentation>Whether it is acceptable to scale the image.</xs:documentation>
147
+ </xs:annotation>
148
+ </xs:attribute>
149
+ <xs:attribute name="maintainAspectRatio"
150
+ type="xs:boolean" use="optional">
151
+ <xs:annotation>
152
+ <xs:documentation>Whether the ad must have its aspect ratio maintained when scales</xs:documentation>
153
+ </xs:annotation>
154
+ </xs:attribute>
155
+ <xs:attribute name="apiFramework" type="xs:string"
156
+ use="optional">
157
+ <xs:annotation>
158
+ <xs:documentation>The apiFramework defines the method to use for communication if the MediaFile is interactive. Suggested values for this element are “VPAID”, “FlashVars” (for Flash/Flex), “initParams” (for Silverlight) and “GetVariables” (variables placed in key/value pairs on the asset request).</xs:documentation>
159
+ </xs:annotation>
160
+ </xs:attribute>
161
+ </xs:extension>
162
+ </xs:simpleContent>
163
+ </xs:complexType>
164
+ </xs:element>
165
+ </xs:sequence>
166
+ </xs:complexType>
167
+ </xs:element>
168
+ </xs:sequence>
169
+ </xs:complexType>
170
+ </xs:element>
171
+ <xs:element name="CompanionAds" minOccurs="0"
172
+ maxOccurs="1">
173
+ <xs:complexType>
174
+ <xs:sequence>
175
+ <xs:element name="Companion" minOccurs="0"
176
+ maxOccurs="unbounded" type="Companion_type">
177
+ <xs:annotation>
178
+ <xs:documentation>Any number of companions in any desired pixel dimensions.</xs:documentation>
179
+ </xs:annotation>
180
+ </xs:element>
181
+ </xs:sequence>
182
+ </xs:complexType>
183
+ </xs:element>
184
+ <xs:element name="NonLinearAds" minOccurs="0"
185
+ maxOccurs="1">
186
+ <xs:complexType>
187
+ <xs:sequence>
188
+ <xs:element name="TrackingEvents" minOccurs="0"
189
+ type="TrackingEvents_type" maxOccurs="1"> </xs:element>
190
+ <xs:element name="NonLinear" minOccurs="1"
191
+ maxOccurs="unbounded" type="NonLinear_type">
192
+ <xs:annotation>
193
+ <xs:documentation>Any number of companions in any desired pixel dimensions.</xs:documentation>
194
+ </xs:annotation>
195
+ </xs:element>
196
+ </xs:sequence>
197
+ </xs:complexType>
198
+ </xs:element>
199
+ </xs:choice>
200
+ <xs:attribute name="id" type="xs:string"
201
+ use="optional"/>
202
+ <xs:attribute name="sequence" type="xs:integer"
203
+ use="optional">
204
+ <xs:annotation>
205
+ <xs:documentation>The preferred order in which multiple Creatives should be displayed</xs:documentation>
206
+ </xs:annotation>
207
+ </xs:attribute>
208
+ <xs:attribute name="AdID" type="xs:string"
209
+ use="optional">
210
+ <xs:annotation>
211
+ <xs:documentation>Ad-ID for the creative (formerly ISCI)</xs:documentation>
212
+ </xs:annotation>
213
+ </xs:attribute>
214
+ </xs:complexType>
215
+ </xs:element>
216
+ </xs:sequence>
217
+ </xs:complexType>
218
+ </xs:element>
219
+ <xs:element name="Extensions" minOccurs="0" maxOccurs="1">
220
+ <xs:complexType>
221
+ <xs:sequence>
222
+ <xs:element name="Extension" type="xs:anyType"
223
+ minOccurs="0" maxOccurs="unbounded">
224
+ <xs:annotation>
225
+ <xs:documentation>Any valid XML may be included in the Extensions node</xs:documentation>
226
+ </xs:annotation>
227
+ </xs:element>
228
+ </xs:sequence>
229
+ </xs:complexType>
230
+ </xs:element>
231
+ </xs:sequence>
232
+ </xs:complexType>
233
+ </xs:element>
234
+ <xs:element name="Wrapper" maxOccurs="1" minOccurs="0">
235
+ <xs:annotation>
236
+ <xs:documentation>Second-level element surrounding wrapper ad pointing to Secondary ad server.</xs:documentation>
237
+ </xs:annotation>
238
+ <xs:complexType>
239
+ <xs:sequence>
240
+ <xs:element name="AdSystem" type="AdSystem_type"
241
+ maxOccurs="1" minOccurs="1">
242
+ <xs:annotation>
243
+ <xs:documentation>Indicates source ad server</xs:documentation>
244
+ </xs:annotation>
245
+ </xs:element>
246
+ <xs:element name="VASTAdTagURI" type="xs:anyURI"
247
+ maxOccurs="1" minOccurs="1">
248
+ <xs:annotation>
249
+ <xs:documentation>URL of ad tag of downstream Secondary Ad Server</xs:documentation>
250
+ </xs:annotation>
251
+ </xs:element>
252
+ <xs:element name="Error" type="xs:anyURI" minOccurs="0"
253
+ maxOccurs="1">
254
+ <xs:annotation>
255
+ <xs:documentation>URL to request if ad does not play due to error</xs:documentation>
256
+ </xs:annotation>
257
+ </xs:element>
258
+ <xs:element name="Impression" type="xs:anyURI"
259
+ maxOccurs="unbounded" minOccurs="1">
260
+ <xs:annotation>
261
+ <xs:documentation>URL to request to track an impression</xs:documentation>
262
+ </xs:annotation>
263
+ </xs:element>
264
+ <xs:element name="Creatives">
265
+ <xs:complexType>
266
+ <xs:sequence>
267
+ <xs:element name="Creative" maxOccurs="unbounded"
268
+ minOccurs="0">
269
+ <xs:complexType>
270
+ <xs:choice>
271
+ <xs:element name="Linear" minOccurs="0"
272
+ maxOccurs="1">
273
+ <xs:complexType>
274
+ <xs:sequence>
275
+ <xs:element name="TrackingEvents" minOccurs="0"
276
+ type="TrackingEvents_type" maxOccurs="1"> </xs:element>
277
+ <xs:element name="VideoClicks" minOccurs="0"
278
+ maxOccurs="1">
279
+ <xs:complexType>
280
+ <xs:sequence>
281
+ <xs:element name="ClickTracking" minOccurs="0"
282
+ maxOccurs="unbounded">
283
+ <xs:annotation>
284
+ <xs:documentation>URL to request for tracking purposes when user clicks on the video</xs:documentation>
285
+ </xs:annotation>
286
+ <xs:complexType>
287
+ <xs:simpleContent>
288
+ <xs:extension base="xs:anyURI">
289
+ <xs:attribute name="id" type="xs:string"
290
+ use="optional"/>
291
+ </xs:extension>
292
+ </xs:simpleContent>
293
+ </xs:complexType>
294
+ </xs:element>
295
+ </xs:sequence>
296
+ </xs:complexType>
297
+ </xs:element>
298
+ </xs:sequence>
299
+ </xs:complexType>
300
+ </xs:element>
301
+ <xs:element name="CompanionAds" minOccurs="0"
302
+ maxOccurs="1">
303
+ <xs:complexType>
304
+ <xs:sequence>
305
+ <xs:element name="Companion" minOccurs="0"
306
+ maxOccurs="unbounded" type="Companion_type">
307
+ <xs:annotation>
308
+ <xs:documentation>Definition of Companion ad, if served separately</xs:documentation>
309
+ </xs:annotation>
310
+ </xs:element>
311
+ </xs:sequence>
312
+ </xs:complexType>
313
+ </xs:element>
314
+ <xs:element name="NonLinearAds" minOccurs="0"
315
+ maxOccurs="1">
316
+ <xs:complexType>
317
+ <xs:sequence>
318
+ <xs:element name="TrackingEvents" minOccurs="0"
319
+ type="TrackingEvents_type" maxOccurs="1"> </xs:element>
320
+ <xs:element name="NonLinear" minOccurs="0"
321
+ maxOccurs="unbounded" type="NonLinear_type">
322
+ <xs:annotation>
323
+ <xs:documentation>Any number of companions in any desired pixel dimensions.</xs:documentation>
324
+ </xs:annotation>
325
+ </xs:element>
326
+ </xs:sequence>
327
+ </xs:complexType>
328
+ </xs:element>
329
+ </xs:choice>
330
+ <xs:attribute name="id" type="xs:string"
331
+ use="optional"/>
332
+ <xs:attribute name="sequence" type="xs:integer"
333
+ use="optional">
334
+ <xs:annotation>
335
+ <xs:documentation>The preferred order in which multiple Creatives should be displayed</xs:documentation>
336
+ </xs:annotation>
337
+ </xs:attribute>
338
+ <xs:attribute name="AdID" type="xs:string"
339
+ use="optional">
340
+ <xs:annotation>
341
+ <xs:documentation>Ad-ID for the creative (formerly ISCI)</xs:documentation>
342
+ </xs:annotation>
343
+ </xs:attribute>
344
+ </xs:complexType>
345
+ </xs:element>
346
+ </xs:sequence>
347
+ </xs:complexType>
348
+ </xs:element>
349
+ <xs:element name="Extensions" minOccurs="0" maxOccurs="1">
350
+ <xs:complexType>
351
+ <xs:sequence>
352
+ <xs:element name="Extension" type="xs:anyType"
353
+ minOccurs="0" maxOccurs="unbounded">
354
+ <xs:annotation>
355
+ <xs:documentation>Any valid XML may be included in the Extensions node</xs:documentation>
356
+ </xs:annotation>
357
+ </xs:element>
358
+ </xs:sequence>
359
+ </xs:complexType>
360
+ </xs:element>
361
+ </xs:sequence>
362
+ </xs:complexType>
363
+ </xs:element>
364
+ </xs:choice>
365
+ <xs:attribute name="id" type="xs:string" use="required"/>
366
+ </xs:complexType>
367
+ </xs:element>
368
+ </xs:sequence>
369
+ <xs:attribute name="version" type="xs:string" use="required">
370
+ <xs:annotation>
371
+ <xs:documentation>Current version is 2.0. The 2.0.1 version corrects an error in the Wrapper section related the Linear node's TrackingEvents and VideoCLicks elements.</xs:documentation>
372
+ </xs:annotation>
373
+ </xs:attribute>
374
+ </xs:complexType>
375
+ </xs:element>
376
+ <xs:complexType name="TrackingEvents_type">
377
+ <xs:sequence>
378
+ <xs:element name="Tracking" minOccurs="0" maxOccurs="unbounded">
379
+ <xs:annotation>
380
+ <xs:documentation>The name of the event to track for the Linear element. The creativeView should always be requested when present.</xs:documentation>
381
+ </xs:annotation>
382
+ <xs:complexType>
383
+ <xs:simpleContent>
384
+ <xs:extension base="xs:anyURI">
385
+ <xs:attribute name="event" use="required">
386
+ <xs:annotation>
387
+ <xs:documentation>The name of the event to track. For nonlinear ads these events should be recorded on the video within the ad.</xs:documentation>
388
+ </xs:annotation>
389
+ <xs:simpleType>
390
+ <xs:restriction base="xs:NMTOKEN">
391
+ <xs:enumeration value="creativeView"/>
392
+ <xs:enumeration value="start"/>
393
+ <xs:enumeration value="midpoint"/>
394
+ <xs:enumeration value="firstQuartile"/>
395
+ <xs:enumeration value="thirdQuartile"/>
396
+ <xs:enumeration value="complete"/>
397
+ <xs:enumeration value="mute"/>
398
+ <xs:enumeration value="unmute"/>
399
+ <xs:enumeration value="pause"/>
400
+ <xs:enumeration value="rewind"/>
401
+ <xs:enumeration value="resume"/>
402
+ <xs:enumeration value="fullscreen"/>
403
+ <xs:enumeration value="expand"/>
404
+ <xs:enumeration value="collapse"/>
405
+ <xs:enumeration value="acceptInvitation"/>
406
+ <xs:enumeration value="close"/>
407
+ </xs:restriction>
408
+ </xs:simpleType>
409
+ </xs:attribute>
410
+ </xs:extension>
411
+ </xs:simpleContent>
412
+ </xs:complexType>
413
+ </xs:element>
414
+ </xs:sequence>
415
+ </xs:complexType>
416
+ <xs:complexType name="VideoClicks_type">
417
+ <xs:sequence>
418
+ <xs:element name="ClickThrough" minOccurs="0" maxOccurs="1">
419
+ <xs:annotation>
420
+ <xs:documentation>URL to open as destination page when user clicks on the video</xs:documentation>
421
+ </xs:annotation>
422
+ <xs:complexType>
423
+ <xs:simpleContent>
424
+ <xs:extension base="xs:anyURI">
425
+ <xs:attribute name="id" type="xs:string" use="optional"/>
426
+ </xs:extension>
427
+ </xs:simpleContent>
428
+ </xs:complexType>
429
+ </xs:element>
430
+ <xs:element name="ClickTracking" minOccurs="0" maxOccurs="unbounded">
431
+ <xs:annotation>
432
+ <xs:documentation>URL to request for tracking purposes when user clicks on the video</xs:documentation>
433
+ </xs:annotation>
434
+ <xs:complexType>
435
+ <xs:simpleContent>
436
+ <xs:extension base="xs:anyURI">
437
+ <xs:attribute name="id" type="xs:string" use="optional"/>
438
+ </xs:extension>
439
+ </xs:simpleContent>
440
+ </xs:complexType>
441
+ </xs:element>
442
+ <xs:element name="CustomClick" minOccurs="0" maxOccurs="unbounded">
443
+ <xs:annotation>
444
+ <xs:documentation>URLs to request on custom events such as hotspotted video</xs:documentation>
445
+ </xs:annotation>
446
+ <xs:complexType>
447
+ <xs:simpleContent>
448
+ <xs:extension base="xs:anyURI">
449
+ <xs:attribute name="id" type="xs:string" use="optional"/>
450
+ </xs:extension>
451
+ </xs:simpleContent>
452
+ </xs:complexType>
453
+ </xs:element>
454
+ </xs:sequence>
455
+ </xs:complexType>
456
+ <xs:complexType name="Companion_type">
457
+ <xs:sequence>
458
+ <xs:choice>
459
+ <xs:element name="StaticResource" minOccurs="0" maxOccurs="1">
460
+ <xs:annotation>
461
+ <xs:documentation>URL to a static file, such as an image or SWF file</xs:documentation>
462
+ </xs:annotation>
463
+ <xs:complexType>
464
+ <xs:simpleContent>
465
+ <xs:extension base="xs:anyURI">
466
+ <xs:attribute name="creativeType" type="xs:string" use="required">
467
+ <xs:annotation>
468
+ <xs:documentation>Mime type of static resource</xs:documentation>
469
+ </xs:annotation>
470
+ </xs:attribute>
471
+ </xs:extension>
472
+ </xs:simpleContent>
473
+ </xs:complexType>
474
+ </xs:element>
475
+ <xs:element name="IFrameResource" type="xs:anyURI" minOccurs="0" maxOccurs="1">
476
+ <xs:annotation>
477
+ <xs:documentation>URL source for an IFrame to display the companion element</xs:documentation>
478
+ </xs:annotation>
479
+ </xs:element>
480
+ <xs:element name="HTMLResource" type="xs:string" minOccurs="0" maxOccurs="1">
481
+ <xs:annotation>
482
+ <xs:documentation>HTML to display the companion element</xs:documentation>
483
+ </xs:annotation>
484
+ </xs:element>
485
+ </xs:choice>
486
+ <xs:element maxOccurs="1" minOccurs="0" name="TrackingEvents" type="TrackingEvents_type">
487
+ <xs:annotation>
488
+ <xs:documentation>The creativeView should always be requested when present. For Companions creativeView is the only supported event.</xs:documentation>
489
+ </xs:annotation>
490
+ </xs:element>
491
+ <xs:element name="CompanionClickThrough" type="xs:anyURI" minOccurs="0" maxOccurs="1">
492
+ <xs:annotation>
493
+ <xs:documentation>URL to open as destination page when user clicks on the the companion banner ad.</xs:documentation>
494
+ </xs:annotation>
495
+ </xs:element>
496
+ <xs:element name="AltText" type="xs:string" minOccurs="0" maxOccurs="1">
497
+ <xs:annotation>
498
+ <xs:documentation>Alt text to be displayed when companion is rendered in HTML environment.</xs:documentation>
499
+ </xs:annotation>
500
+ </xs:element>
501
+ <xs:element name="AdParameters" type="xs:string" minOccurs="0" maxOccurs="1">
502
+ <xs:annotation>
503
+ <xs:documentation>Data to be passed into the companion ads. The apiFramework defines the method to use for communication (e.g. “FlashVar”)</xs:documentation>
504
+ </xs:annotation>
505
+ </xs:element>
506
+ </xs:sequence>
507
+ <xs:attribute name="id" type="xs:string" use="optional">
508
+ <xs:annotation>
509
+ <xs:documentation>Optional identifier</xs:documentation>
510
+ </xs:annotation>
511
+ </xs:attribute>
512
+ <xs:attribute name="width" type="xs:integer" use="required">
513
+ <xs:annotation>
514
+ <xs:documentation>Pixel dimensions of companion</xs:documentation>
515
+ </xs:annotation>
516
+ </xs:attribute>
517
+ <xs:attribute name="height" type="xs:integer" use="required">
518
+ <xs:annotation>
519
+ <xs:documentation>Pixel dimensions of companion</xs:documentation>
520
+ </xs:annotation>
521
+ </xs:attribute>
522
+ <xs:attribute name="expandedWidth" type="xs:integer" use="optional">
523
+ <xs:annotation>
524
+ <xs:documentation>Pixel dimensions of expanding companion ad when in expanded state</xs:documentation>
525
+ </xs:annotation>
526
+ </xs:attribute>
527
+ <xs:attribute name="expandedHeight" type="xs:integer" use="optional">
528
+ <xs:annotation>
529
+ <xs:documentation>Pixel dimensions of expanding companion ad when in expanded state</xs:documentation>
530
+ </xs:annotation>
531
+ </xs:attribute>
532
+ <xs:attribute name="apiFramework" type="xs:string" use="optional">
533
+ <xs:annotation>
534
+ <xs:documentation>The apiFramework defines the method to use for communication with the companion</xs:documentation>
535
+ </xs:annotation>
536
+ </xs:attribute>
537
+ </xs:complexType>
538
+ <xs:complexType name="NonLinear_type">
539
+ <xs:sequence>
540
+ <xs:choice>
541
+ <xs:element name="StaticResource" minOccurs="0" maxOccurs="1">
542
+ <xs:annotation>
543
+ <xs:documentation>URL to a static file, such as an image or SWF file</xs:documentation>
544
+ </xs:annotation>
545
+ <xs:complexType>
546
+ <xs:simpleContent>
547
+ <xs:extension base="xs:anyURI">
548
+ <xs:attribute name="creativeType" type="xs:string" use="required">
549
+ <xs:annotation>
550
+ <xs:documentation>Mime type of static resource</xs:documentation>
551
+ </xs:annotation>
552
+ </xs:attribute>
553
+ </xs:extension>
554
+ </xs:simpleContent>
555
+ </xs:complexType>
556
+ </xs:element>
557
+ <xs:element name="IFrameResource" type="xs:anyURI" minOccurs="0" maxOccurs="1">
558
+ <xs:annotation>
559
+ <xs:documentation>URL source for an IFrame to display the companion element</xs:documentation>
560
+ </xs:annotation>
561
+ </xs:element>
562
+ <xs:element name="HTMLResource" type="xs:string" minOccurs="0" maxOccurs="1">
563
+ <xs:annotation>
564
+ <xs:documentation>HTML to display the companion element</xs:documentation>
565
+ </xs:annotation>
566
+ </xs:element>
567
+ </xs:choice>
568
+ <xs:element name="NonLinearClickThrough" type="xs:anyURI" minOccurs="0" maxOccurs="1">
569
+ <xs:annotation>
570
+ <xs:documentation>URL to open as destination page when user clicks on the the non-linear ad unit.</xs:documentation>
571
+ </xs:annotation>
572
+ </xs:element>
573
+ <xs:element name="AdParameters" type="xs:string" minOccurs="0" maxOccurs="1">
574
+ <xs:annotation>
575
+ <xs:documentation>Data to be passed into the video ad. </xs:documentation>
576
+ </xs:annotation>
577
+ </xs:element>
578
+ </xs:sequence>
579
+ <xs:attribute name="id" type="xs:string" use="optional">
580
+ <xs:annotation>
581
+ <xs:documentation>Optional identifier</xs:documentation>
582
+ </xs:annotation>
583
+ </xs:attribute>
584
+ <xs:attribute name="width" type="xs:integer" use="required">
585
+ <xs:annotation>
586
+ <xs:documentation>Pixel dimensions of companion</xs:documentation>
587
+ </xs:annotation>
588
+ </xs:attribute>
589
+ <xs:attribute name="height" type="xs:integer" use="required">
590
+ <xs:annotation>
591
+ <xs:documentation>Pixel dimensions of companion</xs:documentation>
592
+ </xs:annotation>
593
+ </xs:attribute>
594
+ <xs:attribute name="expandedWidth" type="xs:integer" use="optional">
595
+ <xs:annotation>
596
+ <xs:documentation>Pixel dimensions of expanding nonlinear ad when in expanded state</xs:documentation>
597
+ </xs:annotation>
598
+ </xs:attribute>
599
+ <xs:attribute name="expandedHeight" type="xs:integer" use="optional">
600
+ <xs:annotation>
601
+ <xs:documentation>Pixel dimensions of expanding nonlinear ad when in expanded state</xs:documentation>
602
+ </xs:annotation>
603
+ </xs:attribute>
604
+ <xs:attribute name="scalable" type="xs:boolean" use="optional">
605
+ <xs:annotation>
606
+ <xs:documentation>Whether it is acceptable to scale the image.</xs:documentation>
607
+ </xs:annotation>
608
+ </xs:attribute>
609
+ <xs:attribute name="maintainAspectRatio" type="xs:boolean" use="optional">
610
+ <xs:annotation>
611
+ <xs:documentation>Whether the ad must have its aspect ratio maintained when scales</xs:documentation>
612
+ </xs:annotation>
613
+ </xs:attribute>
614
+ <xs:attribute name="minSuggestedDuration" type="xs:time" use="optional">
615
+ <xs:annotation>
616
+ <xs:documentation>Suggested duration to display non-linear ad, typically for animation to complete. Expressed in standard time format hh:mm:ss</xs:documentation>
617
+ </xs:annotation>
618
+ </xs:attribute>
619
+ <xs:attribute name="apiFramework" type="xs:string" use="optional">
620
+ <xs:annotation>
621
+ <xs:documentation>The apiFramework defines the method to use for communication with the nonlinear element</xs:documentation>
622
+ </xs:annotation>
623
+ </xs:attribute>
624
+ </xs:complexType>
625
+ <xs:complexType name="AdSystem_type">
626
+ <xs:simpleContent>
627
+ <xs:extension base="xs:string">
628
+ <xs:attribute name="version" type="xs:string" use="optional">
629
+ <xs:annotation>
630
+ <xs:documentation>Internal version used by ad system</xs:documentation>
631
+ </xs:annotation>
632
+ </xs:attribute>
633
+ </xs:extension>
634
+ </xs:simpleContent>
635
+ </xs:complexType>
636
+ <xs:complexType name="Impression_type">
637
+ <xs:simpleContent>
638
+ <xs:extension base="xs:anyURI">
639
+ <xs:attribute name="id" type="xs:string" use="optional"/>
640
+ </xs:extension>
641
+ </xs:simpleContent>
642
+ </xs:complexType>
643
+ </xs:schema>