Skip to content

Restore required elements and ordering on vastInLine_type and vastWrapper_type - #59

Open
aleksUIX wants to merge 2 commits into
InteractiveAdvertisingBureau:masterfrom
aleksUIX:fix/vast-4-4-inline-wrapper-content-model
Open

aleksUIX wants to merge 2 commits into
InteractiveAdvertisingBureau:masterfrom
aleksUIX:fix/vast-4-4-inline-wrapper-content-model

Conversation

@aleksUIX

@aleksUIX aleksUIX commented Aug 9, 2026 •

Copy link
Copy Markdown

vastInLine_type and vastWrapper_type use <xs:choice minOccurs="0" maxOccurs="unbounded">. That compositor drops the cardinality of everything inside it: the children still declare minOccurs="1", but within a repeating optional choice that governs a single selection rather than the content model. Reported in #58.

Against the schema as it stands, all three of these validate:

<Ad id="a"><Wrapper/></Ad>                 <!-- no AdSystem, VASTAdTagURI or Impression -->
<Ad id="a"><InLine/></Ad>                  <!-- no AdSystem, AdTitle, Impression or Creatives -->
<InLine><AdSystem>A</AdSystem><AdSystem>B</AdSystem>...   <!-- AdSystem repeated -->

All three were rejected in 2.0 through 4.2. This changes both types to xs:sequence with the cardinality these elements have always had. No elements are added or removed.

On the ordering. I kept the 4.2 element order rather than the order the xs:choice happened to list them in, and that is not cosmetic. I tested the alternative: using 4.4's current listed order breaks all six VAST 4.1 and 4.2 files in VAST_Samples that validate against 4.4 today. The 4.2 order breaks none of them.

Regression testing. Ran the 33 4.1 and 4.2 samples with the version attribute rewritten to 4.4, so the fixed-value constraint does not mask the content model. Six pass before and after this change, zero newly broken. VAST 4.0 samples were excluded deliberately, since they predate AdServingId and would fail on a requirement that has held since 4.1 rather than on anything introduced here. Also confirmed the three cases above are now rejected and that ordinary inlines and wrappers still validate.

Separate, not addressed here. BlockedAdCategories on Wrapper and Expires on InLine exist in 4.2 but are not declared anywhere in vast_4.4.xsd, and neither is marked deprecated in the 4.3 text. A 4.4 wrapper carrying BlockedAdCategories is rejected today. Re-adding them needs type definitions, so I left them out of this change.

If the group would rather keep order independence than restore cardinality, I am happy to close this. As covered in #58, XSD 1.0 cannot give both: xs:all caps every particle at maxOccurs="1", and Impression has been 1..n since 2.0.

vastInLine_type and vastWrapper_type use
<xs:choice minOccurs="0" maxOccurs="unbounded">, which drops the
cardinality of every child it contains. The elements still declare
minOccurs="1", but inside a repeating optional choice that governs a
single selection rather than the content model.

The result is that an empty <Wrapper/> and an empty <InLine/> validate,
singular elements such as AdSystem repeat, and element order is
unconstrained. All three were rejected in 2.0 through 4.2.

Change both to xs:sequence with the cardinality these elements have
always had. No elements are added or removed. The 4.2 element order is
kept because it is what the IAB VAST 4.1 and 4.2 sample files emit.

Refs InteractiveAdvertisingBureau#58
@aleksUIX
aleksUIX force-pushed the fix/vast-4-4-inline-wrapper-content-model branch from 0acd8d7 to 1a7d442 Compare August 9, 2026 06:46
@aleksUIX aleksUIX changed the title Restore InLine and Wrapper content model in vast_4.4.xsd (fixes #58) Restore required elements and ordering on vastInLine_type and vastWrapper_type Aug 9, 2026
Empty InLine, empty Wrapper, and repeated AdSystem must fail against this
tree and still pass origin/master vast_4.4.xsd, which is the InteractiveAdvertisingBureau#58 bug.
@aleksUIX

aleksUIX commented Sep 4, 2026

Copy link
Copy Markdown
Author

Pushed a follow-up commit with xmllint fixtures so the three #58 cases are checked in-tree: empty <InLine/>, empty <Wrapper/>, and repeated <AdSystem>. The same three documents still validate against origin/master vast_4.4.xsd.

Run: ./tests/schema/run.sh (needs libxml2 xmllint).

This is the blocker AdCP cited when they deferred VAST 4.4 from the 3.2 enum: adcontextprotocol/adcp#7230 closed in favor of adcontextprotocol/adcp#7247, which points at #58.

@jstastny

Copy link
Copy Markdown

We generate VAST NonLinear overlays for CTV and ran this branch (dd8d381) against our output and against the 4.4 examples IAB has published. +1 on restoring the sequence. One thing will likely come up in review, so flagging it early:

Every InLine example in the 4.4 prose fails against this branch. That's the overlay example in VAST4.x/4.4.md §3.12 and all ten VAST examples in Ad-Format-Guidelines-for-Digital-Video-CTV/Signaling-Implementation-Guidelines.md. Nothing is wrong with the schema here. The examples use an order the 4.1/4.2 XSD never allowed:

  • AdTitle before Impression (the XSD order is Impression, then AdServingId, then AdTitle)
  • AdServingId missing (required since 4.1)
  • Extensions after Creatives (the XSD puts it after Error, before Impression)

Three of the guideline examples also aren't well-formed XML: one truncated block, one stray </Extension>, and a template with NonLinear directly under Creative.

Against current master they all pass, because the xs:choice accepts anything. So the examples look fine until this fix lands, and at that point they all look broken.

I've opened PRs that bring the examples in line with the order this PR restores. No content changes, only ordering, the missing AdServingId, and the well-formedness fixes:

With those applied, all 11 examples validate against this branch (xmllint, libxml2; the template filled with numeric width/height). They still validate against current master too, so the example PRs are safe to merge in either order relative to this one.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants