Python script to validate WIPO ST.92 Priority Document Data Packages (PDDP ZIP files) before REGISTRATION of priority documents in WIPO DAS REST API V2. It works with packages created by the generator (4.- Generating PDDP samples for testing) and with packages produced by any other system.

This is a helper tool for testing. It does not replace the validation performed by WIPO DAS and does not cover every rule of ST.92.

Get the validator here: PDDP_Validator.zip (version of 02.10.2026)

Contents of the package

validatorPddp/
├── validate_pddp.py                    # Validator script
├── requirements.txt                    # Python dependency (lxml)
├── README.md                           # Documentation
├── xsd/                                # Offline fallback copy of the ST.92 V2.0 schemas
│   ├── ST92PDDPIndex_V2_0.xsd
│   ├── ST96_Common_V9_0.xsd
│   ├── ST96_Design_V9_0.xsd
│   └── ST96_Trademark_V9_0.xsd
└── dtd/
    └── ST26SequenceListing_V1_3.dtd    # WIPO ST.26 DTD for sequence listings

By default the validator downloads the schemas directly from WIPO, so it always checks against the published versions:

Downloads are cached under .cache/ and reused on later runs. If a download fails, the validator falls back to the bundled xsd/ copy and reports that it did. Use --offline to force the bundled copy and never touch the network; those files are byte-identical to the published ones, so both modes validate against the same schema.

The ST.26 DTD is only distributed inside the ST.26 Annex II bundle and has no stable standalone URL, so it stays in dtd/.

Installation

The validator needs Python 3.10+ and the lxml library (XSD/DTD validation is not available in the Python standard library).

# Linux / macOS
cd validatorPddp
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt

# Windows (PowerShell)
cd validatorPddp
py -m venv .venv
.venv\Scripts\pip install -r requirements.txt

On Debian / Ubuntu / Raspberry Pi OS you can instead install the system package: sudo apt install python3-lxml.

Usage

# Validate all ZIP files in ../output (default)
.venv/bin/python validate_pddp.py

# Validate specific ZIP files and/or all ZIP files in a folder
.venv/bin/python validate_pddp.py Patent_NO_20210008_20210924.zip ./received/

# Also list every check that passed
.venv/bin/python validate_pddp.py -v ./output

# Report advisory findings as warnings instead of errors
.venv/bin/python validate_pddp.py --lenient ./output

# Use the bundled schemas, without any network access
.venv/bin/python validate_pddp.py --offline ./output

All options

OptionDefaultDescription
paths ...../outputZIP files and/or folders containing ZIP files
-v, --verboseoffAlso list the checks that passed
--schema URL|FILEthe WIPO URL aboveST.92 index schema to validate against
--offlineoffUse the bundled xsd/ copy, never touch the network
--refresh-schemaoffRe-download the schemas, ignoring the cache
--no-fallbackoffFail instead of falling back to the bundled schema
--timeout SECONDS30Schema download timeout
--st96-schema URLthe WIPO ST.96 zip aboveFlattened ST.96 release for supplementary artifacts
--st96-dir DIR-Use an already-extracted ST.96 schema folder
--no-st96offSkip ST.96 validation of supplementary artifacts
--lenientoffReport advisory findings as warnings instead of errors
--st26-dtd FILEdtd/ST26SequenceListing_V1_3.dtdST.26 sequence listing DTD

Strict by default: advisory findings are reported as errors, so nothing is silently accepted. Pass --lenient to keep them as warnings.

Exit code: 0 when no package has errors, 1 otherwise (can be used in scripts / CI).

Checks performed

GroupCheckResult if it fails
ArchiveZIP opens and every entry passes its CRCERROR
ArchiveNo encrypted entries and no duplicate entry namesERROR
ArchiveNo absolute paths, .. traversal, backslashes or control characters in entry namesERROR
ArchivePriorityDocumentIndex.xml present at the ZIP root, with exact casingERROR
IndexWell-formed XML, parsed with entity expansion and network access disabledERROR
IndexNo DOCTYPE and no XML entity referencesERROR
IndexRoot element is pde:PriorityDocumentIndexERROR
IndexValid against ST92PDDPIndex_V2_0.xsdERROR
IndexDocument categories match IPRightKindCategoryERROR
IndexMandatory documents present: priority document PDF (all types), certification page and representation (designs, trademarks)ERROR
IndexPatent package without a separate certification page (it must then be part of the priority document PDF)advisory
IndexSupplementary document category is one of the values ST.92 recommends for the IP right type. Mandatory categories are a closed enumeration enforced by the schema, but supplementary ones are declared as a union with xsd:token, so the schema accepts any value and a typo would otherwise pass unnoticedadvisory
IndexApplicationFilingDate and DocumentDate parse and are not in the futureERROR
IndexZIP name <Kind>_<Office>_<Number>_<YYYYMMDD>.zip matches the indexERROR / advisory
ReferencesEvery file listed in the index exists in the ZIPERROR
Referencescom:FileName contains no path componentERROR
ReferencesDocumentLocationURI is relative and does not escape the packageERROR
ReferencesMandatory documents live under MandatoryArtifacts/, supplementary under SupplementaryArtifacts/ERROR
ReferencesDocumentLocationURI is an external URL; file in the ZIP not listed in the index; one file referenced by several entriesadvisory
ContentNo empty filesERROR
ContentDeclared DocumentFileFormatCategory matches both the file extension and the actual bytesERROR
ContentFile content matches its extension (PDF, PNG, JPEG, WAV, MP3, STL, ZIP, TAR, XML)ERROR
ContentPDF structure: header, startxref, %%EOF, /RootERROR
ContentPNG structure: per-chunk CRCs, IHDR/IDAT/IEND present, non-zero dimensionsERROR
ContentWAV structure: RIFF size agrees with the file, fmt and data chunks present and in boundsERROR
ContentSTL structure: facet / loop / vertex counts agree (ASCII) or size matches the triangle count (binary)ERROR
ContentZipped artifacts open, are unencrypted and CRC-cleanERROR
ContentPageTotalQuantity matches the PDF page count; DocumentSizeQuantity matches the real byte sizeadvisory
ContentInternal XML is well-formedERROR
ContentSupplementary artifacts valid against the published ST.96 V9.0 schemasERROR
ContentST.26 sequence listings valid against the ST.26 DTDERROR
ContentST.26 cross-checks: fileName, SequenceTotalQuantity, sequenceIDNumber runs 1..n, INSDSeq_length matches the sequenceERROR
ContentST.26 characters within the Annex IV Basic Latin subsetadvisory
ContentST.25 sequence listings: mandatory numeric identifiers present, <160> matches the sequence count, <210> runs 1..n, <212> is DNA/RNA/PRT, ASCII onlyERROR
ContentST.25 used only on applications filed before 2022-07-01ERROR

Checks marked advisory are reported as errors by default and as warnings with --lenient.

Bibliographic and classification data are now validated against the published ST.96 V9.0 schemas, not just checked for well-formedness.

Note that these documents belong to the per-right ST.96 namespaces, not to Common: pat:BibliographicData and pat:PatentClassificationBag for patents, dgn:DesignApplication and com:DesignClassificationBag (Locarno) for designs, tmk:TrademarkApplication and tmk:GoodsServicesBag (Nice) for trademarks.

The trimmed ST96_Common_V9_0.xsd shipped inside the ST.92 Annex I bundle declares only 16 global elements, a subset built for the index schema. It is not a substitute for the full ST.96 Common namespace, which is why the supplementary artifacts are checked against the ST.96 release instead.

pde:*MandatoryDocumentCategory is declared with xsd:restriction, so only these values are valid and xmllint rejects anything else:

PatentIndustrial designTrademark
Certification pageCertification pageCertification page
Priority document PDFPriority document PDFPriority document PDF
Sequence listingIndustrial design representationTrademark representation

pde:*SupplementaryDocumentCategory is declared as a union of xsd:token and a base type, so the enumerated values are recommended rather than binding and an Office may legitimately use another token. The validator therefore reports an unrecognised supplementary category as advisory, to catch typos without blocking legitimate values:

PatentIndustrial designTrademark
AbstractBibliographic dataBibliographic data
Application bodyRegistration certificateRegistration certificate
Bibliographic dataIndustrial design representationMark representation
DescriptionClassification dataClassification data
ClaimsIntermediate documentsIntermediate documents
Drawings  
Classification data  
Preconversion document  
Sequence listing  

Note that com:DocumentName beside these elements is free text (xsd:string union) and carries no controlled vocabulary; the category element is the machine-readable one.

ST.92 paragraph 18 permits ST.26, ST.25 or ST.23, and footnote 2 makes ST.26 mandatory for patent applications filed on or after 1 July 2022. The validator reads pde:ApplicationFilingDate from the index and rejects an ST.25 listing on a later filing:

ERROR  ..._SequenceListing_ST25.txt: ST.25 sequence listing on an application
       filed 2023-03-15. ST.26 (XML) is mandatory for patent applications
       filed on or after 2022-07-01.

ST.25 listings are recognised by their numeric identifiers rather than by file name, so a listing named anything else is still checked. The expected DocumentFileFormatCategory is TEXT for ST.25 and XML for ST.26.

Example output

>>>> .venv/bin/python validate_pddp.py -v ./output/Patent_IB_PCT-IB2026-134592_20260103.zip
ST.92 schema: https://www.wipo.int/standards/XMLSchema/ST92/V2_0/ST92PDDPIndex_V2_0.xsd
ST.96 schema: https://www.wipo.int/standards/en/st96/v9-0/annex-iii/ST96XMLSchema_V9_0_Flattened.zip
Mode:         strict

[OK] Patent_IB_PCT-IB2026-134592_20260103.zip
    ok    ZIP integrity OK
    ok    11 ZIP entr(ies), all names safe and unique
    ok    PriorityDocumentIndex.xml valid against the ST.92 V2.0 schema
    ok    Document categories consistent with 'Patent'
    ok    Mandatory documents present: ['Certification page', 'Priority document PDF', 'Sequence listing']
    ok    ZIP file name consistent with index
    ok    All 7 referenced files resolved
    ok    MandatoryArtifacts/..._PriorityDocument.pdf: PDF OK (2,847 bytes, 3 page(s))
    ok    MandatoryArtifacts/..._SequenceListing_ST26.xml: valid against the ST.26 DTD
    ok    SupplementaryArtifacts/..._BibliographicData.xml: valid against ST.96 V9.0 (BibliographicData_V9_0.xsd)
    ok    SupplementaryArtifacts/..._ClassificationData.xml: valid against ST.96 V9.0 (Patent_V9_0.xsd)

1 package(s) checked: 1 passed, 0 failed.

Without -v only problems are listed:

>>>> .venv/bin/python validate_pddp.py ./received/
[FAIL] Patent_XX_1234567_20260101.zip
    ERROR MandatoryArtifacts/doc.pdf: declared format 'PNG' does not match extension '.pdf' (expected ['.png'])
    ERROR SupplementaryArtifacts/bib.xml ST.96: line 11: Element 'InventionTitle': This element is not expected. Expected is ( InventionTitleBag ).

1 package(s) checked: 0 passed, 1 failed.

Common errors

MessageCause / fix
SupplementaryDocumentBag': Missing child element(s)An empty <pde:SupplementaryDocumentBag> is not allowed. Remove the element if there are no supplementary documents.
'Text' is not a valid value of the union type ... DocumentFileFormatCategoryTypeFile format values are case sensitive: use TEXT, PDF, XML, …
No declaration for element INSDSeq_organismNot part of ST.26. The organism must be given as the organism qualifier of the source feature.
<PatentBibliographicData> is not a global elementThere is no such element in the ST.96 Common namespace. Bibliographic data belongs to the per-right namespaces: pat:BibliographicData, dgn:DesignApplication, tmk:TrademarkApplication.
declared format 'X' does not match extension '.y'DocumentFileFormatCategory disagrees with the file it points at. Fix whichever is wrong.
PageTotalQuantity N != M page(s) found in the PDFThe declared page count does not match the PDF. Advisory, so it only fails the run in strict mode.
mandatory document stored under SupplementaryArtifacts/Mandatory artifacts must sit under MandatoryArtifacts/ and supplementary ones under SupplementaryArtifacts/.
Path traversal in ZIP entryThe package contains an entry with .. or an absolute path. Rebuild it with relative paths only.
ST.25 sequence listing on an application filed ...The package pairs an ST.25 listing with a filing date on or after 1 July 2022. Supply the listing in ST.26 (XML) instead.
unrecognised DocumentFileFormatCategory 'TXT'ST.96 enumerates the plain-text category as TEXT, not TXT.
content is not a valid STL/PDF/... fileThe file does not contain what its extension says (e.g. an HTML page saved with a .stl extension).

Python 3.10+ and lxml.

Network access to www.wipo.int is used to fetch the schemas on first run. Behind a proxy or offline, run with --offline to use the bundled copies.