define.xml for RWE Submissions
define.xml is the machine-readable XML metadata file that the FDA requires alongside every SDTM and ADaM submission; it documents each variable's name, label, type, controlled terminology, derivation algorithm, and origin, making the submission self-describing and reviewer-reproducible without access to the sponsor's analysis code.
On this page
define.xml is the machine-readable metadata file that the FDA requires alongside every SDTM and ADaM submission. While SDTM holds the data values, define.xml holds the meaning of those values — every variable's label, type, length, controlled terminology, origin (raw vs derived), and, for derived variables, the algorithm that produces them. A reviewer who opens define.xml alongside the data files can navigate the submission without ever seeing the sponsor's analysis code. For RWE this is the audit floor for every code translation and every derivation.
define.xml (v2.x)
is the CDISC XML metadata format that accompanies every SDTM and ADaM dataset in an FDA submission. It is, in the FDA's words in the Study Data Technical Conformance Guide, arguably the most important part of the electronic dataset submission for review: where SDTM and ADaM hold the data values, define.xml holds their meaning — every variable's name, label, data type, length, significant digits, controlled-terminology codelist binding, origin (CRF, Derived, Assigned, Predecessor), and, for derived variables, the computational algorithm (ComputationalMethod) or comment that reproduces it. Built on the ODM-XML backbone, it lets a reviewer navigate the entire submission without ever seeing sponsor analysis code.
Why it matters for RWE
For trial data, much of define.xml is mechanical. For real-world data, define.xml is where the epistemology of the package lives: which vendor supplied each field, what the linkage algorithm was, how the index date was derived, which imputation rule filled partial dates, why an AE's origin is "Derived" from problem-list logic. A reviewer evaluating whether an external-control arm is trustworthy reads the ADaM define.xml ComputationalMethods before reading a single table. Under-documented RWE packages fail here first — the data may be fine, but if the reviewer cannot reconstruct the derivations, the evidence is unverifiable.
Core components
- MetaDataVersion: the locked metadata block — its def:DefineVersion, the standards (SDTMIG/ADaMIG versions) and CT versions it references, and its effective date. An unpinned MetaDataVersion is incomplete.
- ItemGroupDef / ItemDef: one ItemGroupDef per dataset; ItemDefs describe every variable including type, length, origin, and Comment/Method bindings. KeySequence declares dataset sort keys.
- CodeList / ExternalCodeList: CT bindings — internal codelists with CodedValues, or external terminologies (MedDRA, WHODrug) referenced by dictionary name/version.
- ValueListDef (Value Level Metadata): per-parameter variable definitions for BDS datasets — essential wherever parameters differ structurally (ADLB analytes, ADTTE endpoints).
- def:Origin / def:Comment / MethodDef: origin classification and human-readable derivation algorithms. "Derived" origins must bind a computational method; "Assigned" is reserved for sponsor-supplied values with no source — most RWE-derived values are Derived, not Assigned.
- ARM extension (optional): AnalysisResultsMetadata linking TLFs to the analysis variables and methods behind them.
Common pitfalls
- Auto-generated-only metadata. Tools produce the skeleton; origin assignments and derivation algorithms require judgment. Auto-generated define.xml fails technical review on exactly the RWD-specific variables that matter most.
- Wrong origin types. Marking derived-from-source values as 'Assigned' where 'Derived' with a method was meant.
- CodeList mismatches. Every value of a codelist-bound variable must appear in the codelist's CodedValues (or be a justified extension of an extensible list) — the conformance validator enforces this mechanically.
- Custom domains without coverage. RWE-only custom domains (--TORG-prefixed linkage tables, cost domains) need the same ItemDef discipline; otherwise the submission contains undocumented data.
Pros, cons, and trade-offs
- vs a data dictionary spreadsheet: spreadsheets drift; define.xml is validated against the actual XPT contents by Pinnacle 21, so metadata and data cannot silently diverge.
- vs minimal compliance-level metadata: richer Value Level Metadata and ARM raise quality and effort together; skip only where the standard genuinely does not apply.
- Trade-off: narrative goes elsewhere — define.xml documents structure and derivations, not study rationale (that belongs in the ADRG/SDRG and SAP).
When NOT to use
Not a place for study-level argumentation or for masking proprietary source detail beyond what reviewers need; and never submit datasets whose define.xml references a different metadata snapshot than the data itself.
Decision diagram
flowchart LR S[SDTM XPT files] --> D[Define.xml v2.1<br/>metadata for SDTM] A[ADaM XPT files] --> E[Define.xml v2.1<br/>metadata for ADaM] D --> V[Pinnacle 21 / FDA reviewer tooling] E --> V V --> F[FDA submission package<br/>XPT + define.xml + ADRG/SDRG]
Worked example
Scenario
We need to define the ADaM ADTTE dataset in define.xml v2.1. The dataset has 7 variables: USUBJID (raw, from SDTM), PARAMCD and PARAM (controlled values), PARAMTYP (controlled value, 'DERIVED'), AVAL (derived from ADSL.ADT and ADSL.STARTDT), CNSR (derived from ADSL.END_REASON), and SRCSEQ (raw, referencing the SDTM source record). For each derived variable we need an Origin.type of 'Derived' and an Algorithm with a Description.
Dataset
define.xml v2.1 ItemGroupDef and ItemDef for ADTTE.
| variable | type | origin | algorithm_or_note |
|---|---|---|---|
| USUBJID - text(10) - Raw - From SDTM DM.USUBJID | |||
| PARAMCD - text(8) - Assigned - Controlled terminology codelist PARAMCD | |||
| PARAM - text(40) - Assigned - Controlled terminology codelist PARAM | |||
| PARAMTYP - text(8) - Assigned - CDISC CT codelist PARAMTYP; value DERIVED for analysis rows | |||
| AVAL - integer(8) - Derived - AVAL = ADSL.ADT - ADSL.STARTDT (days) | where ADSL.ADT is event or censor date and ADSL.STARTDT is the protocol-defined time zero. | ||
| CNSR - integer(1) - Derived - CNSR = 1 if ADSL.END_REASON in (DISENROLL | DEATH | END_OF_STUDY); else 0. | |
| SRCSEQ - integer(8) - Raw - From SDTM source record; the trace-back pointer for traceability. |
Steps
Result
define.xml v2.1 with one ItemGroupDef (ADTTE), seven ItemDefs (USUBJID, PARAMCD, PARAM, PARAMTYP, AVAL, CNSR, SRCSEQ), three CodeLists (PARAMCD, PARAM, PARAMTYP), and two Algorithms (AVAL and CNSR). The MetaDataVersion pins Define-XML v2.1.8, SDTMIG v3.4, ADaMIG v1.3, CDISC CT 2024-09-26. A reviewer can navigate the submission without seeing analysis code.
Trade-offs
Runnable example
Minimal Python skeleton for define.xml v2.1 with a derived ItemDef carrying an Algorithm element. For full submissions use pyodm or odmlib.
# Minimal define.xml v2.1 fragment showing the ODM root, MetaDataVersion, and one
# ItemGroupDef with a derived ItemDef carrying an Algorithm element. Build with a
# CDISC ODM library (pyodm, odmlib) for full submissions; this skeleton is for
# illustration of the structure.
import xml.etree.ElementTree as ET
NS = {"odm": "http://www.cdisc.org/ns/odm/v1.3.2",
"def": "http://www.cdisc.org/ns/def/v2.1"}
odm = ET.Element("{%s}ODM" % NS["odm"], {
"ODMVersion": "1.3.2",
"FileType": "Snapshot",
"Granularity": "Metadata",
})
mdv = ET.SubElement(odm, "{%s}Study" % NS["odm"])
mv = ET.SubElement(mdv, "{%s}MetaDataVersion" % NS["def"], {
"OID": "MDV.RWED.001",
"Name": "RWED ADaM MetaData",
"DefineVersion": "2.1.8",
"SdtmigVersion": "3.4",
"AdamigVersion": "1.3",
"CdiscCtVersion": "2024-09-26",
})
igd = ET.SubElement(mv, "{%s}ItemGroupDef" % NS["def"], {
"OID": "IG.ADTTE",
"Name": "ADTTE",
"Structure": "One record per parameter per subject",
"Purpose": "Time-to-event analysis dataset",
})
# USUBJID — raw, from SDTM
ET.SubElement(igd, "{%s}ItemRef" % NS["def"], {"ItemOID": "IT.USUBJID", "Mandatory": "Yes"})
# AVAL — derived from ADSL.STARTDT and ADSL.ADT
aval = ET.SubElement(mv, "{%s}ItemDef" % NS["def"], {
"OID": "IT.AVAL",
"Name": "AVAL",
"DataType": "integer",
"Length": "8",
})
ET.SubElement(aval, "{%s}Origin" % NS["def"], {"Type": "Derived"})
algo = ET.SubElement(aval, "{%s}Algorithm" % NS["def"], {"OID": "AL.AVAL"})
ET.SubElement(algo, "{%s}Description" % NS["def"]).text = (
"AVAL = ADSL.ADT - ADSL.STARTDT (days), where ADSL.ADT is event or censor date and "
"ADSL.STARTDT is the protocol-defined time zero (treatment initiation). Re-derivable from "
"ADaM ADSL."
)
ET.ElementTree(odm).write("define.xml", xml_declaration=True, encoding="UTF-8")
R version using odmlib; emits a minimal ODM tree with the locked standards versions.
library(odmlib)
# Build the ODM root and MetaDataVersion with the locked standards versions.
odm <- ODMTree$new()
odm$SetFileType("Snapshot")
mdv <- odm$AddMetaDataVersion(
oid = "MDV.RWED.001",
name = "RWED ADaM MetaData",
define_version = "2.1.8",
sdtmig_version = "3.4",
adamig_version = "1.3",
cdisc_ct_version = "2024-09-26"
)
mdv$AddItemGroup(
oid = "IG.ADTTE", name = "ADTTE",
structure = "One record per parameter per subject",
purpose = "Time-to-event analysis dataset"
)
mdv$AddItem(oid = "IT.AVAL", name = "AVAL", data_type = "integer", length = 8,
origin_type = "Derived")
mdv$AddAlgorithm(oid = "AL.AVAL", description = "AVAL = ADSL.ADT - ADSL.STARTDT (days).")
odm$WriteXML("define.xml")
SAS XMLV2 skeleton; for production submissions use the SAS Clinical Standards Toolkit or an ODM library.
/* SAS macro stub — building define.xml from SAS requires an XML engine (XMLV2)
or a CDISC ODM library. The skeleton below emits the ODM root and a derived
ItemDef using XMLV2. For full submissions use the SAS Clinical Standards Toolkit. */
filename out "define.xml";
data _null_;
file out;
put '<?xml version="1.0" encoding="UTF-8"?>';
put '<ODM xmlns="http://www.cdisc.org/ns/odm/v1.3.2" xmlns:def="http://www.cdisc.org/ns/def/v2.1"';
put ' ODMVersion="1.3.2" FileType="Snapshot" Granularity="Metadata">';
put ' <Study OID="STUDY.RWED.001">';
put ' <GlobalVariables><StudyName>RWED ADaM MetaData</StudyName></GlobalVariables>';
put ' <MetaDataVersion OID="MDV.RWED.001" Name="RWED ADaM MetaData"';
put ' DefineVersion="2.1.8" SdtmigVersion="3.4" AdamigVersion="1.3"';
put ' CdiscCtVersion="2024-09-26"/>';
put ' </Study>';
put '</ODM>';
run;
Citations
- [1]CDISC. Define-XML. CDISC standards.
- [2]CDISC. Define-XML v2.1. CDISC standards.
- [3]CDISC. SDTM Metadata Submission Guidelines v2.0. CDISC foundational standard.