Skip to content

Commit f97dada

Browse files
milanmajchrakclaude
andcommitted
Satisfy the CCMM requirements the XSD cannot enforce
Every record already validated against dataset/schema.xsd, which is why none of this showed up as invalid. The CCMM specification states requirements the XSD has no way to express - they live in en/dsv.ttl as scope notes and cardinality - and a conformance check reads those, not the XSD. All 89 scope notes and 92 cardinality statements were extracted and checked against the output of all 2628 live LINDAT records. The one the specification calls mandatory: - FRASCATI FORD. Dataset.hasSubject: "At least one subject must be a value from FRASCATI FORD vocabulary. For that subject use reference codelist .../SubjectCategory/ as the Subject scheme." No record carried one. The field is read off dc.type: a tool or service is computer science (10201), a newsreel clip is History (60101) - on this corpus every dc.type "clip" is a segment of a digitised 1943 newsreel held as a historical source, not a language resource - and everything else is Linguistics (60203), which is what the repository collects. Codes and both prefLabels come from the live register, and FORD_DEFAULT_CODE is the single value another deployment changes. 1161 History, 1136 Linguistics, 331 Computer sciences. Statements the output was making that the source does not support: - access_url pointed at the bitstream. accessUrl: "The resource at the access URL contains information about how to get the Dataset. It shall be the web page (not a document file)", and the schema's own Czech documentation says to use it "in all cases except a downloadable file URL". It is now the item's landing page; download_url keeps the file. - identifier/value carried the resolved URL. CCMM types value as skos:notation - the identifier WITHIN its scheme - and keeps the resolvable form in iri, the split its own samples use. One emitter now serves every source, so scheme, notation and IRI cannot disagree between branches. - The dataset had no iri of its own, so the published record had no resolvable identity. - license is 1..1 and was serialised as <license/> on 584 records. A void mandatory element tells a harvester nothing; those records now carry rightsstatements.org UND, which is the standard statement for rights not stated. - Language labels were DSpace's own strings, not the register's, and glued words together ("UpperSorbian", "AncientGreek (to 1453)") on 537 elements; their positional pairing could also slip once duplicate codes were removed. The scope note asks for the register's "label and/or its 3-letter code" and CCMM's own dataset-mini sample writes primary_language with an iri and no label, so the IRI alone is published. - media_type published IANA IRIs for six types RFC 6838 reserves as unregistered (application/ x-gzip and friends); those IRIs 404. They are suppressed, and the mandatory EU format element carries the file type - which is the scope note's own "otherwise Format MAY be used" branch. - format carried the IANA media type where Format.label asks for a label from the EU file-type codelist. format is now the EU concept, media_type stays IANA. All 9125 distributions map to a real EU concept; every code was verified by content, because that register answers 200 for any path. Values that were not what they claimed to be: - 203 byte-identical sibling elements across 161 records, because DSpace stores one value under several language wrappers and two sources can carry the same value. Deduplication now happens where each block is assembled, so it also catches the cross-source repeats. - "Germany||United States" was published as one place name; it is two. - 20 alternate titles said nothing about how they differ from the title. - dc.relation.uri was listed as a qualifier but had no term, so those related resources came out untyped; the register has Other for exactly that. - An iri only had to start with a URL, so "http://a/ Book and enhanced publication" was published as an identifier. The whole value now has to be one URI. - A packed contact field put an affiliation in the email slot. - A second dc.title never became an alternate title. The predicate was doc:field[@name='value'][position() > 1], but position() counts within each parent and every XOAI language wrapper holds exactly one field, so it was always 1. Two titles only worked when both sat in the SAME wrapper, which XOAI does not do for values differing in language. Latent on this corpus - no record has two dc.title - but wrong, and the new fixture exercises it. Measured after the change over all 2628 records: 2628 valid, every counter zero, 95 tests and 187 assertions green, 67 of 68 stylesheet mutants killed, 23 portability inputs clean. The surviving mutant edits a FormatDate branch its callers make unreachable by pre-filtering. Not changed, and why: eight records carry U+FFFD in title and description text. That is in the source data - eight records in, eight records out - so guessing the intended character would be inventing content. It belongs in the repository's metadata. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 23aca5e commit f97dada

4 files changed

Lines changed: 805 additions & 80 deletions

File tree

0 commit comments

Comments
 (0)