odmlib

Create, load, validate, and convert CDISC ODM, Define-XML, Dataset-JSON, and ARM documents in Python.

29|11|Updated Jan 3, 2021
One-click install
npx skills add https://github.com/swhume/odmlib --skill odmlib-swhume
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: odmlib
Source: https://github.com/swhume/odmlib/tree/main/.claude/skills/odmlib
Command: npx skills add https://github.com/swhume/odmlib --skill odmlib-swhume

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill requires odmlib, and includes references (resource) components.

What problem does it solve? Hand-writing CDISC ODM-family XML or JSON is error-prone: wrong element order, missing namespace declarations, dangling OID references, and silent data loss on serialization. This Skill teaches the correct odmlib patterns so generated study metadata, Define-XML, Dataset-JSON, and ARM documents validate against the standard instead of failing schema checks or regulatory loads. ## Core Features & Use Cases - Model-driven document handling: Load, modify, and create ODM 1.3.2/2.0, Define-XML 2.1, Dataset-JSON 1.1, and ARM 1.0 documents as typed Python objects via the open_odm/open_define facades, explicit loaders, or the ODMBuilder fluent API. - Layered validation: Run element-order, OID integrity, Cerberus conformance, and bundled XSD schema validation with collect_errors=True to enumerate every defect in one pass, plus permissive mode for repairing non-conformant files. - Serialization and conversion guidance: Avoid the ET.tostring(to_xml()) data-loss trap with to_xml_string()/to_element(), and convert between Define-XML and tabular Dataset-JSON via DefineFlattener. - Use Case: A clinical programmer needs to generate a Define-XML 2.1 file for an SDTM submission. The Skill guides building the document with define_2_1 model classes (single Study/MetaDataVersion objects), validating OID references, and schema-checking against the bundled Define-XML 2.1 XSD. ## Quick Start Ask the AI to load your define.xml with odmlib, list its datasets and variables, fix any dangling OID references, and validate the result against the bundled Define-XML 2.1 schema.

Frequently Asked Questions about odmlib

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I create a Define-XML 2.1 file in Python?

Use the odmlib define_2_1 model classes to build the document as objects, assigning Study and MetaDataVersion as single objects rather than lists. Then call validate() with an OID checker and write_xml() to serialize, optionally schema-checking with the bundled Define-XML 2.1 XSD.

How do I validate an ODM or Define-XML document in Python?

Call validate(collect_errors=True, oid_checker=create_oid_checker(...), conformance_checker=MetadataSchema()) on the loaded odmlib object to enumerate element-order, OID integrity, and conformance errors in one pass. For full schema validation, use ODMSchemaValidator with the bundled ODM, Define-XML, or ARM XSDs.

Why does my ODM file lose all Study data after serialization?

Calling ET.tostring(obj.to_xml()) produces markup with no namespace declarations, so ODM re-parses into no namespace and every Study is silently dropped while FileOID still reads back. Use to_xml_string() or write_xml() instead, which attach the required xmlns declarations.

What is the difference between ODM and Define-XML models in odmlib?

In odm_1_3_2 and odm_2_0, Study and MetaDataVersion are lists accessed as odm.Study[0].MetaDataVersion[0]. In define_2_1 and arm_1_0 they are single objects accessed as define.Study.MetaDataVersion, and indexing them raises an error.

Can odmlib load a non-conformant or broken ODM file?

Yes, wrap the load in permissive mode via open_odm(path, permissive=True) or the permissive() context manager to relax required-attribute, value-set, type, and format checks. Permissive mode is intended for inspection and repair; fix the issues, return to strict mode, and validate before writing output.

How do I convert Define-XML to Dataset-JSON?

Load the Define-XML document with the define_2_1 loader, then call DefineFlattener(odm).flatten_all() to get named DatasetJSON datasets for study, datasets, variables, codelists, and more. Write each with write_ndjson(), since NDJSON is the Dataset-JSON v1.1 wire format.