FDA SDTM validation rules April 2017
missing DM dataset - Demographics (DM) dataset must be included in every submission
DM
(: Rule FDAC001 - missing DM dataset :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace request="http://exist-db.org/xquery/request";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the location of the DM dataset :)
let $dmdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/def:leaf/@xlink:href
let $dmdatasetlocation := concat($base,$dmdatasetname)
(: we now have the location of the dataset, check whether it is available there :)
where (not(doc-available($dmdatasetlocation)))
return <error rule="FDAC001" rulelastupdate="2015-02-09" dataset="DM">Document {data($dmdatasetname)} could not be found in collection {data($base)}</error>
Missing TS dataset - Trial Summary (TS) dataset must be included in every submission
TS
(: Rule FDAC002 - Missing TS dataset :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace request="http://exist-db.org/xquery/request";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the location of the TS dataset :)
let $tsdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: we now have the location of the dataset, check whether it is available there :)
where (not(doc-available($tsdatasetlocation)))
return <error rule="FDAC002" rulelastupdate="2015-02-09" dataset="TS">Document {data($tsdatasetname)} could not be found in collection {data($base)}</error>
Missing DS dataset - Disposition (DS) dataset should be included in every submission
DS
(: Rule FDAC003 - Missing DS dataset :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace request="http://exist-db.org/xquery/request";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the location of the DS dataset :)
let $dsdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DS']/def:leaf/@xlink:href
let $dsdatasetlocation := concat($base,$dsdatasetname)
(: we now have the location of the dataset, check whether it is available there :)
where (not(doc-available($dsdatasetlocation)))
return <warning rule="FDAC003" dataset="DS" rulelastupdate="2015-02-09">Document {data($dsdatasetname)} could not be found in collection {data($base)}</warning>
Missing EX dataset - Exposure (EX) dataset should be included in every submission
EX
(: Rule FDAC004 - Missing EX dataset :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace request="http://exist-db.org/xquery/request";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the location of the EX dataset :)
let $exdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='EX']/def:leaf/@xlink:href
let $exdatasetlocation := concat($base,$exdatasetname)
(: we now have the location of the dataset, check whether it is available there :)
where (not(doc-available($exdatasetlocation)))
return <warning rule="FDAC004" dataset="EX" rulelastupdate="2015-02-09">Document {data($exdatasetname)} could not be found in collection {data($base)}</warning>
Missing AE dataset - Adverse Events (AE) dataset should be included in every submission
AE
(: Rule FDAC005 - Missing AE dataset :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace request="http://exist-db.org/xquery/request";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the location of the AE dataset :)
let $aedatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='AE']/def:leaf/@xlink:href
let $aedatasetlocation := concat($base,$aedatasetname)
(: we now have the location of the dataset, check whether it is available there :)
where (not(doc-available($aedatasetlocation)))
return <warning rule="FDAC005" dataset="AE" rulelastupdate="2015-02-09">Document {data($aedatasetname)} could not be found in collection {data($base)}</warning>
Missing LB dataset - Lab Test Results (LB) dataset should be included in every submission
LB
(: Rule FDAC006 - Missing LB dataset :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace request="http://exist-db.org/xquery/request";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the location of the LB dataset :)
let $lbdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='LB']/def:leaf/@xlink:href
let $lbdatasetlocation := concat($base,$lbdatasetname)
(: we now have the location of the dataset, check whether it is available there :)
where (not(doc-available($lbdatasetlocation)))
return <error rule="FDAC006" dataset="LB" rulelastupdate="2015-02-09">Document {data($lbdatasetname)} could not be found in collection {data($base)}</error>
Missing VS dataset - Vital Signs (VS) dataset should be included in every submission
VS
(: Rule FDAC007 - Missing VS dataset :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace request="http://exist-db.org/xquery/request";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the location of the VS dataset :)
let $vsdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='VS']/def:leaf/@xlink:href
let $vsdatasetlocation := concat($base,$vsdatasetname)
(: we now have the location of the dataset, check whether it is available there :)
where (not(doc-available($vsdatasetlocation)))
return <warning rule="FDAC007" dataset="VS" rulelastupdate="2015-02-09">Document {data($vsdatasetname)} could not be found in collection {data($base)}</warning>
Missing SE dataset - Subject Elements (SE) dataset should be included in every submission
SE
(: Rule FDAC008 - Missing SE dataset :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace request="http://exist-db.org/xquery/request";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the location of the SE dataset :)
let $sedatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='SE']/def:leaf/@xlink:href
let $sedatasetlocation := concat($base,$sedatasetname)
(: we now have the location of the dataset, check whether it is available there :)
where (not(doc-available($sedatasetlocation)))
return <warning rule="FDAC008" dataset="SE" rulelastupdate="2015-02-09">Document {data($sedatasetname)} could not be found in collection {data($base)}</warning>
Missing TA dataset - Trial Arms (TA) dataset should be included in every submission
TA
(: Rule FDAC009 - Missing TA dataset :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace request="http://exist-db.org/xquery/request";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the location of the TA dataset :)
let $tadatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TA']/def:leaf/@xlink:href
let $tadatasetlocation := concat($base,$tadatasetname)
(: we now have the location of the dataset, check whether it is available there :)
where (not(doc-available($tadatasetlocation)))
return <warning rule="FDAC009" dataset="TA" rulelastupdate="2015-02-09">Document {data($tadatasetname)} could not be found in collection {data($base)}</warning>
Missing TE dataset - Trial Elements (TE) dataset should be included in every submission
TE
(: Rule FDAC010 - Missing TE dataset :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace request="http://exist-db.org/xquery/request";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the location of the TE dataset :)
let $tedatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TE']/def:leaf/@xlink:href
let $tedatasetlocation := concat($base,$tedatasetname)
(: we now have the location of the dataset, check whether it is available there :)
where (not(doc-available($tedatasetlocation)))
return <warning rule="FDAC010" dataset="TE" rulelastupdate="2015-02-09">Document {data($tedatasetname)} could not be found in collection {data($base)}</warning>
Missing MB dataset, when MS dataset is present
MB
MS
(: ##### Not well tested yet ###### :)
(: Rule FDAC012 - Missing MB dataset when MS dataset is present: Microbiology Specimen (MB) dataset should be included, when a Microbiology Susceptibility Test (MS) dataset is present :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace request="http://exist-db.org/xquery/request";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the location of the MS dataset :)
let $msdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='MS']/def:leaf/@xlink:href
let $msdatasetlocation := concat($base,$msdatasetname)
(: get the location of the MB dataset - when given anyway :)
let $mbdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='MB']/def:leaf/@xlink:href
let $mbdatasetlocation := concat($base,$mbdatasetname)
(: when MB is present, MS may not be absent :)
where (doc-available($msdatasetlocation) and not(doc-available($mbdatasetlocation)))
return <warning rule="FDAC012" dataset="MB" rulelastupdate="2015-02-09">Document {data($mbdatasetname)} for domain MB could not be found in collection {data($base)} although document {data($msdatasetname)} is present</warning>
No records in data source - Domain table should have at least one record
ALL
(: Rule FDAC014 - No records in data source :)
(: P.S only the datasets that are listed in the define.xml are tested :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace request="http://exist-db.org/xquery/request";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Find all datasets :)
for $itemgroup in doc(concat($base,$define))//odm:ItemGroupDef
let $datasetname := $itemgroup/@Name
let $dataset := $itemgroup/def:leaf/@xlink:href
let $datasetpath := concat($base,$dataset)
(: iterate over each dataset, and count the number of records :)
for $numrecords in count(doc($datasetpath)//odm:ItemGroupData)
(: and check whether there is less than 1 record :)
where $numrecords < 1
return <error rule="FDAC014" dataset="{data($datasetname)}" rulelastupdate="2016-03-25">{$numrecords} found in dataset: {data($datasetname)}</error>
No records in data source - Domain table should have at least one record
ALL
(: Rule FDAC014 - No records in data source :)
(: P.S only the datasets that are listed in the define.xml are tested :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace request="http://exist-db.org/xquery/request";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
declare variable $domain external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Find the datasets that is requested :)
for $itemgroup in doc(concat($base,$define))//odm:ItemGroupDef[@Name=$domain or @Domain=$domain]
let $datasetname := $itemgroup/@Name
let $dataset := $itemgroup/def:leaf/@xlink:href
let $datasetpath := concat($base,$dataset)
(: iterate over each dataset, and count the number of records :)
for $numrecords in count(doc($datasetpath)//odm:ItemGroupData)
(: and check whether there is less than 1 record :)
where $numrecords < 1
return <error rule="FDAC014" dataset="{data($datasetname)}" rulelastupdate="2016-03-25">{$numrecords} found in dataset: {data($datasetname)}</error>
Dataset is greater than 1 GB in size - Large datasets should be split into smaller datasets no larger than 1 GB in size.
ALL
(: Rule FDAC016 - Dataset is greater than 1 GB in size :)
(: see: http://rvdb.wordpress.com/2013/02/26/an-xquery-script-for-listing-the-contents-of-collections-in-exist-db/ :)
(: TODO - xmldb:get-child-resources is eXist-specific, does not work for files :)
(: suggestion: use collection('file:///a/b/c/d?select=*.xml') - see http://stackoverflow.com/questions/5601764/xquery-all-files-under-a-specific-directory :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace request="http://exist-db.org/xquery/request";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
for $child in xmldb:get-child-resources($base)
let $datasetname := upper-case(substring-before($child,'.'))
let $path := concat($base, $child)
(: TODO: test further: file sizes obtained here are about 20% too high :)
let $size := fn:ceiling(xmldb:size($base, $child) div (1024*1024)) (: file size in MB :)
where $size > 1024
return
<warning rule="FDAC016" dataset="{$datasetname}" rulelastupdate="2016-03-25">Size of file {$child} is larger than 1GB - file size found = {$size} MB </warning>
SDTM Required variable not found - Variables described in SDTM as Required must be included in the dataset -
ALL
(: Rule FDAC017-FDAC018: SDTM Required variable not found - Variables described in SDTM as Required must be included in the dataset :)
(: The following Query relies on that the define.xml is complete and
that Mandatory='Yes' is set for each required variable :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace request="http://exist-db.org/xquery/request";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all datasets mentioned in the define.xml :)
for $itemgroup in doc(concat($base,$define))//odm:ItemGroupDef
(: get all the ItemRef-OIDs which have 'Mandatory="Yes" :)
let $mandatory := $itemgroup/odm:ItemRef[@Mandatory='Yes']/@ItemOID
(: get the dataset itself :)
let $datasetfilename := $itemgroup/def:leaf/@xlink:href
let $dataset := doc(concat($base,$datasetfilename))
let $datasetname := $itemgroup/@Name
(: iterate over all the records :)
for $record in $dataset//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: iterate over the 'mandatory' OIDs :)
for $m in $mandatory
(: and give an error when there is no such ItemData/@ItemOID :)
let $varname := doc(concat($base,$define))//odm:ItemDef[@OID=$m]/@Name
where not($record/odm:ItemData[@ItemOID=$m])
return <error rule="FDAC017" datasetname="{$datasetname}" variable="{data($varname)}" rulelastupdate="2015-08-31" recordnumber="{$recnum}">No data found for required variable {data($varname)} in record number {data($recnum)} in dataset {data($datasetname)}</error>
SDTM Required variable not found, single dataset or domain - Variables described in SDTM as Required must be included in the dataset -
ALL
(: Rule FDAC017-FDAC018: SDTM Required variable not found - Variables described in SDTM as Required must be included in the dataset :)
(: The following Query relies on that the define.xml is complete and
that Mandatory='Yes' is set for each required variable :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace request="http://exist-db.org/xquery/request";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
declare variable $domain external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all datasets mentioned in the define.xml and passed by the calling program through external variable $domain :)
for $itemgroup in doc(concat($base,$define))//odm:ItemGroupDef[@Name=$domain or @Domain=$domain]
(: get all the ItemRef-OIDs which have 'Mandatory="Yes" :)
let $mandatory := $itemgroup/odm:ItemRef[@Mandatory='Yes']/@ItemOID
(: get the dataset itself :)
let $datasetfilename := $itemgroup/def:leaf/@xlink:href
let $dataset := doc(concat($base,$datasetfilename))
let $datasetname := $itemgroup/@Name
(: iterate over all the records :)
for $record in $dataset//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: iterate over the 'mandatory' OIDs :)
for $m in $mandatory
(: and give an error when there is no such ItemData/@ItemOID :)
let $varname := doc(concat($base,$define))//odm:ItemDef[@OID=$m]/@Name
where not($record/odm:ItemData[@ItemOID=$m])
return <error rule="FDAC017" datasetname="{$datasetname}" variable="{data($varname)}" rulelastupdate="2015-08-31" recordnumber="{$recnum}">No data found for required variable {data($varname)} in record number {data($recnum)} in dataset {data($datasetname)}</error>
NULL value in variable marked as Required - Required variables (where Core attribute is 'Req') cannot be NULL for any records
ALL
(: Rule FDAC018: NULL value in variable marked as Required - Required variables (where Core attribute is 'Req') cannot be NULL for any records :)
(: The following Query relies on that the define.xml is complete and
that Mandatory='Yes' is set for each required variable :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
declare variable $domain external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: let $domain := 'VS' :)
(: EITHER provide $domain=:'ALL', meaning: validate for all domains referenced from the define.xml OR:
$domain:='XX' where XX is a specific domain, MEANING validate for a single domain only :)
(: get the definitions for the domains (ItemGroupDefs in define.xml) :)
let $domains := (
if($domain != 'ALL') then doc(concat($base,$define))//odm:ItemGroupDef[@Domain=$domain]
else doc(concat($base,$define))//odm:ItemGroupDef
)
(: iterate over all datasets mentioned in the define.xml :)
for $itemgroup in $domains
let $itemgroupoid := $itemgroup/@OID
let $dataset := $itemgroup/def:leaf/@xlink:href
let $datasetname := $itemgroup/@Name
let $datasetpath := concat($base,$dataset)
(: iterate over all ItemRefs that are mandatory, corresponding to 'required' variables :)
for $itemref in $itemgroup/odm:ItemRef[@Mandatory='Yes']
let $itemrefoid := $itemref/@ItemOID
let $itemname := $itemref/../../odm:ItemDef[@OID=$itemrefoid]/@Name
(: iterate over each dataset :)
for $record in doc($datasetpath)//odm:ItemGroupData[@ItemGroupOID=$itemgroupoid]
(: get the record number :)
let $recnum := $record/@data:ItemGroupDataSeq
(: data point is absent in this record :)
where empty($record/odm:ItemData[@ItemOID=$itemrefoid])
return <error rule="FDAC017" dataset="{$datasetname}" variable="{data($itemname)" rulelastupdate="2016-03-25" recordnumber="{$recnum}">No data found for required variable {data($itemname)} in record number {data($recnum)} in dataset {data($datasetname)}</error>
No Treatment Emergent info for Adverse Event - According to FDA expectations, a treatment-emergent flag should be included in SUPPAE according to SDTM IG v3.1.2 #8.4.3
AE
SUPPAE
(: Rule FDAC022 - No Treatment Emergent info for Adverse Event: According to FDA expectations, a treatment-emergent flag should be included in SUPPAE according to SDTM IG v3.1.2 #8.4.3 :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: look for a SUPPAE dataset and the AE dataset itself :)
let $suppaedataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='SUPPAE']
let $aedataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='AE']
(: get the OID of the QVAL SUPPAE variabke :)
let $suppaeqnamoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='QVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='SUPPAE']/odm:ItemRef/@ItemOID
return $a
)
(: now that we have the OID of the QVAL, check whether there is a ValueList attached :)
let $qvalvaluelistoid := doc(concat($base,$define))//odm:ItemDef[@OID=$suppaeqnamoid]/def:ValueListRef/@ValueListOID
(: and look for a "AETRTEM" in it :)
let $aetrtemoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AETRTEM']/@OID
where $a = doc(concat($base,$define))//def:ValueListDef[@OID=$qvalvaluelistoid]/odm:ItemRef/@ItemOID
return $a
)
(: and check whether the corresponding ItemDef exists :)
let $aetrtemdef := doc(concat($base,$define))//odm:ItemDef[@OID=$aetrtemoid]
(: when absent, report an error :)
where not($aetrtemdef)
return <warning rule="FDAC022" dataset="SUPPAE" rulelastupdate="2016-03-25">No Treatment Emergent info for Adverse Event - SUPPAE QVAL does not have an entry AETRTEM in ValueList</warning>
Dataset is not present in define.xml - Datasets included in study data must be described in the data definition document (define.xml)
ALL
(: Rule FDAC023 - Dataset is not present in define.xml :)
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace functx = "http://www.functx.com";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: need a function substring-after-last - see e.g. http://www.xqueryfunctions.com/xq/functx_substring-after-last.html :)
declare function functx:escape-for-regex
( $arg as xs:string? ) as xs:string {
replace($arg,
'(\.|\[|\]|\\|\||\-|\^|\$|\?|\*|\+|\{|\}|\(|\))','\\$1')
} ;
(: function "substring-after-last occurrence of a given delimiter :)
declare function functx:substring-after-last
( $arg as xs:string? ,
$delim as xs:string ) as xs:string {
replace ($arg,concat('^.*',functx:escape-for-regex($delim)),'')
} ;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
for $doc in collection($base)
(: get the filename :)
let $filename := functx:substring-after-last(document-uri($doc),'/')
(: and exclude the define.xml itself :)
where $filename != $define (: exclude the define.xml doc itself :)
(: now check whether it is referenced in the define.xml :)
and not(doc(concat($base,$define))//odm:ItemGroupDef/def:leaf[@xlink:href=$filename])
return <warning rule="FDAC023" rulelastupdate="2015-09-08">Dataset {data($filename)} is not present in {data($define)} </warning>
Domain referenced in define.xml but dataset is missing - Domains referenced in data definition document (define.xml) should be included in the submission
ALL
(: Rule FDAC024 - Domain referenced in define.xml but dataset is missing :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
for $filename in doc(concat($base,$define))//odm:ItemGroupDef/def:leaf/@xlink:href
let $datasetname := $filename/../../@Name (: go up to ItemGroupDef level :)
let $submdoc := concat($base,$filename)
where not(doc($submdoc))
return <warning rule="FDAC024" dataset="{data($datasetname)}" rulelastupdate="2015-02-09">Dataset {data($filename)} referenced in {$define} but dataset is missing in submission</warning>
Variable in dataset is not present in define.xml - Variables included in the dataset must be described in the data definition document (define.xml)
ALL
(: Rule FDAC026 - Variable in dataset is not present in define.xml:
Variables included in the dataset must be described in the data definition document (define.xml)
:)
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace functx = "http://www.functx.com";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: need a function substring-after-last - see e.g. http://www.xqueryfunctions.com/xq/functx_substring-after-last.html :)
declare function functx:escape-for-regex
( $arg as xs:string? ) as xs:string {
replace($arg,
'(\.|\[|\]|\\|\||\-|\^|\$|\?|\*|\+|\{|\}|\(|\))','\\$1')
} ;
declare function functx:substring-after-last
( $arg as xs:string? ,
$delim as xs:string ) as xs:string {
replace ($arg,concat('^.*',functx:escape-for-regex($delim)),'')
} ;
(: find all datasets :)
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
for $doc in collection($base)
(: get the filename :)
let $filename := functx:substring-after-last(document-uri($doc),'/')
(: get the corresponding ItemGroupDef node in the define.xml :)
let $itemgroupdef := doc(concat($base,$define))//odm:ItemGroupDef[def:leaf/@xlink:href=$filename]
let $itemgroupdefoid := $itemgroupdef/@OID
let $itemgroupdefname := $itemgroupdef/@Name
(: get the unique ItemOIDs in the dataset itself :)
let $distinctvaroids := distinct-values($doc//odm:ItemData/@ItemOID) (: this may be pretty slow :)
(: now exclude the define.xml itself :)
(: where $filename != $define (: exclude the define.xml doc itself :) :)
for $varoid in $distinctvaroids
let $varname := doc(concat($base,$define))//odm:ItemDef[@OID=$varoid]/@Name
where not($itemgroupdef[@OID=$itemgroupdefoid]/odm:ItemRef/@ItemOID=$varoid)
return <error rule="FDAC026" dataset="{data($itemgroupdefname)}" rulelastupdate="2015-02-10">variable with OID {data($varoid)} found in dataset {data($itemgroupdefname)} is not described in {data($define)} in ItemGroupDef with Name={data($itemgroupdefname)} and OID={data($itemgroupdefoid)} </error>
Variable appears in dataset, but is not in SDTM model - Only variables listed in SDTM model should appear in a dataset. New sponsor defined variables must not be added, and existing variables must not be renamed or modified
ALL
(: Rule FDAC027 - Variable appears in dataset, but is not in SDTM model :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare namespace functx = "http://www.functx.com";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: function to find out whether a value is in a sequence (array) :)
declare function functx:is-value-in-sequence
( $value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
(: value-intersect function: returns the intersection of two sequences :)
declare function functx:value-intersect
( $arg1 as xs:anyAtomicType* ,
$arg2 as xs:anyAtomicType* ) as xs:anyAtomicType* {
distinct-values($arg1[.=$arg2])
} ;
(: combines two sequences :)
declare function functx:value-union
( $arg1 as xs:anyAtomicType* ,
$arg2 as xs:anyAtomicType* ) as xs:anyAtomicType* {
distinct-values(($arg1, $arg2))
} ;
(: function replacing two subsequent dashes with the domain code :)
declare function local:replacedash($sequence,$domain) {
for $v in $sequence
return replace($v,'\-\-',$domain)
} ;
(: TODO: can we get the identifiers, timing variables, and all other variables from a RESTful web service as function of SDTM version?
Yes, this is possible - TODO :)
(: SDTM version 1.4 :)
(: Identifiers for all classes :)
let $identifiers := ('STUDYID','DOMAIN','USUBJID','POOLID','SPDEVID','--SEQ','--GRPID',
'--REFID','--SPID','--LNKID','--LNKGRP')
(: Timing variables for all classes :)
let $timingvars := ('VISITNUM','VISIT','VISITDY','TAETORD','EPOCH','--DTC','--STDTC','--ENDTC', '--DY','--STDY','--ENDY','--DUR','--TPT','--TPTNUM','--ELTM','--TPTREF','--RFTDTC','--STRF','--ENRF','--EVLINT','--EVINTX','--STRTPT','--STTPT','--ENRTPT','--ENTPT','--STINT','--ENINT','--DETECT')
let $dmvars := ('STUDYID','DOMAIN','USUBJID','SUBJID','RFSTDTC','RFENDTC','RFXSTDTC','RFXENDTC','RFICDTC','RFPENDTC','DTHDTC','DTHFL','SITEID','INVID','INVNAM','BRTHDTC','AGE','AGETXT','AGEU','SEX','RACE','ETHNIC','SPECIES','STRAIN','SBSTRAIN','ARMCD','ARM','ACTARMCD','ACTARM','SETCD','COUNTRY','DMDTC','DMDY')
(: variables for Interventions classes :)
let $interventionvars := ('--TRT','--MODIFY','--DECOD','--MOOD','--CAT','--SCAT','--PRESP','--OCCUR','--STAT','--REASND','--INDC','--CLAS','--CLASCD','--DOSE','--DOSTXT','--DOSU','--DOSFRM','--DOSFRQ','--DOSTOT','--DOSRGM','--ROUTE','--LOT','--LOC','--LAT','--DIR','--PORTOT','--FAST','--PSTRG','--PSTRGU','--TRTV','--VAMT','--VAMTU','--ADJ')
(: variables for all Event classes :)
let $eventvars := ('--TERM','--MODIFY','--LLT','--LLTCD','--DECOD','--PTCD','--HLT','--HLTCD','--HLGT','--HLGTCD','--CAT','--SCAT','--PRESP','--OCCUR','--STAT','--REASND','--BODSYS','--BDSYCD','--SOC','--SOCCD','--LOC','--LAT','--DIR','--PORTOT','--PARTY','--PRTYID','--SEV','--SER','--ACN','--ACNOTH','--ACNDEV','--REL','--RELNST','--PATT','--OUT','--SCAN','--SCONG','--SDISAB','--SDTH','--SHOSP','--SLIFE','--SOD','--SMIE','--CONTRT','--TOX','--TOXGR')
let $findingvars := ('--TESTCD','--TEST','--MODIFY','--TSTDTL','--CAT','--SCAT','--POS','--BODSYS','--ORRES','--ORRESU','--ORNRLO','--ORNRHI','--STRESC','--STRESN','--STRESU','--STNRLO','--STNRHI','--STNRC','--NRIND','--RESCAT','--STAT','--REASND','--XFN','--NAM','--LOINC','--SPEC','--ANTREG','--SPCCND','--SPCUFL','--LOC','--LAT','--DIR','--PORTOT','--METHOD','--RUNID','--ANMETH','--LEAD','--CSTATE','--BLFL','--FAST','--DRVFL','--EVAL','--EVALID','--ACPTFL','--TOX','--TOXGR','--SEV','--DTHREL','--LLOQ','--ULOQ','--EXCLFL','--REASEX')
(: FA-domains: --OBJ - comes after --TEST :)
let $findingsaboutvars := ('--TESTCD','--TEST','--OBJ','--MODIFY','--TSTDTL','--CAT','--SCAT','--POS','--BODSYS','--ORRES','--ORRESU','--ORNRLO','--ORNRHI','--STRESC','--STRESN','--STRESU','--STNRLO','--STNRHI','--STNRC','--NRIND','--RESCAT','--STAT','--REASND','--XFN','--NAM','--LOINC','--SPEC','--ANTREG','--SPCCND','--SPCUFL','--LOC','--LAT','--DIR','--PORTOT','--METHOD','--RUNID','--ANMETH','--LEAD','--CSTATE','--BLFL','--FAST','--DRVFL','--EVAL','--EVALID','--ACPTFL','--TOX','--TOXGR','--SEV','--DTHREL','--LLOQ','--ULOQ','--EXCLFL','--REASEX')
(: Special purpose: Comments (CO) domain -
Remark that we do not allow for COVAL1, COVAL2, ... as we are using Dataset-XML
which doesn't have the 200 character limitation :)
let $commentvars := ('STUDYID','DOMAIN','RDOMAIN','USUBJID','POOLID','COSEQ','IDVAR','IDVARVAL','COREF','COVAL','COEVAL','CODTC')
(: Subject Elements (SE) :)
let $subjectelementsvar := ('STUDYID','DOMAIN','USUBJID','SESEQ','ETCD','ELEMENT','SESTDTC','SEENDTC','TAETORD','EPOCH','SEUPDES')
(: Subject Visits (SV) :)
let $subjectvisitsvar := ('STUDYID','DOMAIN','USUBJID','VISITNUM','VISIT','VISITDY','SVSTDTC','SVENDTC','SVSTDY','SVENDY','SVUPDES')
(: Trial Design datasets :)
(: Trial Elements (TE) :)
let $trialelementvars := ('STUDYID','DOMAIN','ETCD','ELEMENT','TESTRL','TEENRL','TEDUR')
(: Trial Arms :)
let $trialarmvars := ('STUDYID','DOMAIN','ARMCD','ARM','TAETORD','ETCD','ELEMENT','TABRANCH','TATRANS','EPOCH')
(: Trial Visits (TV) :)
let $trialvisitvars := ('STUDYID','DOMAIN','VISITNUM','VISIT','VISITDY','ARMCD','ARM','TVSTRL','TVENRL')
(: Trial Sets (TX) :)
let $trialsetvars := ('STUDYID','DOMAIN','SETCD','SET','TXSEQ','TXPARMCD','TXPARM','TXVAL')
(: Trial Inclusion/Exclusion Criteria (TI) :)
let $trialievars := ('STUDYID','DOMAIN','IETESTCD','IETEST','IECAT','IESCAT','TIRL','TIVERS')
(: Trial Summary (TS) :)
let $trialsummaryvars := ('STUDYID','DOMAIN','TSSEQ','TSGRPID','TSPARMCD','TSPARM','TSVAL','TSVALNF','TSVALCD','TSVCDREF','TSVCDVER')
(: Trial Disease Assessments (TD) :)
let $trialdiseasevars := ('STUDYID','DOMAIN','TDORDER','TDANCVAR','TDSTOFF','TDTGTPAI','TDMINPAI','TDMAXPAI','TDNUMRPT')
(: Related Records (RELREC) :)
let $relrecvars := ('STUDYID','RDOMAIN','USUBJID','APID','POOLID','IDVAR','IDVARVAL','RELTYPE','RELID')
(: Get the define.xml file :)
(: let $base:= '/db/fda_submissions/cdiscpilot01/' :)
(: let $define := 'define_2_0.xml' :)
(: iterate over all ItemGroupDef elements in define.xml :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef
let $datasetname := $dataset/@Name
(: get the 2-letter domain (except for SUPPQUAL, RELREC, ...)
as we need it to replace the "--" by the domain code
:)
(: Get the domain name and class :)
(: let $domaincode := $dataset/@Name :)
let $domaincode := $dataset/@Domain
let $domainclass := $dataset/@def:Class
(: iterate over the ItemRef elements and get the OID - then transform it to the Name
make an array out of it :)
let $vararray := (
for $itemref in $dataset/odm:ItemRef
(: Attention - we need to exclude non-standard variables (NSVs) :)
let $itemrefoid := $itemref[not(starts-with(upper-case(@Role),'SUPPLEMENTAL'))]/@ItemOID
(: Get the name of the variable from the corresponding ItemDef :)
let $varname := doc(concat($base,$define))//odm:ItemDef[@OID=$itemrefoid]/@Name
return $varname
)
(: now create the array to compare with - we need to replace any '--' by the domain code :)
(: replace any dashes in the variable names by the domain code :)
let $identifiers := local:replacedash($identifiers,$domaincode)
let $timingvars := local:replacedash($timingvars,$domaincode)
let $interventionvars := local:replacedash($interventionvars,$domaincode)
let $eventvars := local:replacedash($eventvars,$domaincode)
let $findingvars := local:replacedash($findingvars,$domaincode)
(: combine all variables: identifiers, class-specific variables and timing variables
into a single sequence :)
let $standardvars := (
if ($domaincode = 'DM') then $dmvars
else if($domaincode = 'CO') then $commentvars
else if($domaincode = 'SE') then $subjectelementsvar
else if($domaincode = 'SV') then $subjectvisitsvar
else if($domaincode = 'TV') then $trialvisitvars
(: Trial Design datasets :)
else if($domaincode = 'TE') then $trialelementvars
else if($domaincode = 'TA') then $trialarmvars
else if($domaincode = 'TX') then $trialsetvars
else if($domaincode = 'TI') then $trialievars
else if($domaincode = 'TS') then $trialsummaryvars
else if($domaincode = 'TD') then $trialdiseasevars
(: Related Records dataset :)
else if($domaincode = 'RELREC') then $relrecvars
else if (upper-case($domainclass) = 'INTERVENTIONS' ) then
functx:value-union(functx:value-union($identifiers,$interventionvars),$timingvars)
else if (upper-case($domainclass) = 'EVENTS') then
functx:value-union(functx:value-union($identifiers,$eventvars),$timingvars)
else if (upper-case($domainclass) = 'FINDINGS') then
functx:value-union(functx:value-union($identifiers,$findingvars),$timingvars)
else ()
)
(: now check whether each of the variables in the SDTM dataset as declared in the define.xml is in the sequence of the allowed variables :)
for $var in $vararray
where functx:is-value-in-sequence($var,$standardvars) = false()
(: and give an error when this is not the case :)
return <error rule="FDAC027" dataset="{data($datasetname)}" variable="{data($var)}" rulelastupdate="2016-03-25">Variable {data($var)} is not in the SDTM model (v.1.4) for domain {data($domaincode)} </error>
Variable appears in dataset, but is not in SDTM model, single domain or dataset - Only variables listed in SDTM model should appear in a dataset. New sponsor defined variables must not be added, and existing variables must not be renamed or modified
ALL
(: Rule FDAC027 - Variable appears in dataset, but is not in SDTM model :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare namespace functx = "http://www.functx.com";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
declare variable $domain external;
(: function to find out whether a value is in a sequence (array) :)
declare function functx:is-value-in-sequence
( $value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
(: value-intersect function: returns the intersection of two sequences :)
declare function functx:value-intersect
( $arg1 as xs:anyAtomicType* ,
$arg2 as xs:anyAtomicType* ) as xs:anyAtomicType* {
distinct-values($arg1[.=$arg2])
} ;
(: combines two sequences :)
declare function functx:value-union
( $arg1 as xs:anyAtomicType* ,
$arg2 as xs:anyAtomicType* ) as xs:anyAtomicType* {
distinct-values(($arg1, $arg2))
} ;
(: function replacing two subsequent dashes with the domain code :)
declare function local:replacedash($sequence,$domain) {
for $v in $sequence
return replace($v,'\-\-',$domain)
} ;
(: TODO: can we get the identifiers, timing variables, and all other variables from a RESTful web service as function of SDTM version?
Yes, this is possible - TODO :)
(: SDTM version 1.4 :)
(: Identifiers for all classes :)
let $identifiers := ('STUDYID','DOMAIN','USUBJID','POOLID','SPDEVID','--SEQ','--GRPID',
'--REFID','--SPID','--LNKID','--LNKGRP')
(: Timing variables for all classes :)
let $timingvars := ('VISITNUM','VISIT','VISITDY','TAETORD','EPOCH','--DTC','--STDTC','--ENDTC', '--DY','--STDY','--ENDY','--DUR','--TPT','--TPTNUM','--ELTM','--TPTREF','--RFTDTC','--STRF','--ENRF','--EVLINT','--EVINTX','--STRTPT','--STTPT','--ENRTPT','--ENTPT','--STINT','--ENINT','--DETECT')
let $dmvars := ('STUDYID','DOMAIN','USUBJID','SUBJID','RFSTDTC','RFENDTC','RFXSTDTC','RFXENDTC','RFICDTC','RFPENDTC','DTHDTC','DTHFL','SITEID','INVID','INVNAM','BRTHDTC','AGE','AGETXT','AGEU','SEX','RACE','ETHNIC','SPECIES','STRAIN','SBSTRAIN','ARMCD','ARM','ACTARMCD','ACTARM','SETCD','COUNTRY','DMDTC','DMDY')
(: variables for Interventions classes :)
let $interventionvars := ('--TRT','--MODIFY','--DECOD','--MOOD','--CAT','--SCAT','--PRESP','--OCCUR','--STAT','--REASND','--INDC','--CLAS','--CLASCD','--DOSE','--DOSTXT','--DOSU','--DOSFRM','--DOSFRQ','--DOSTOT','--DOSRGM','--ROUTE','--LOT','--LOC','--LAT','--DIR','--PORTOT','--FAST','--PSTRG','--PSTRGU','--TRTV','--VAMT','--VAMTU','--ADJ')
(: variables for all Event classes :)
let $eventvars := ('--TERM','--MODIFY','--LLT','--LLTCD','--DECOD','--PTCD','--HLT','--HLTCD','--HLGT','--HLGTCD','--CAT','--SCAT','--PRESP','--OCCUR','--STAT','--REASND','--BODSYS','--BDSYCD','--SOC','--SOCCD','--LOC','--LAT','--DIR','--PORTOT','--PARTY','--PRTYID','--SEV','--SER','--ACN','--ACNOTH','--ACNDEV','--REL','--RELNST','--PATT','--OUT','--SCAN','--SCONG','--SDISAB','--SDTH','--SHOSP','--SLIFE','--SOD','--SMIE','--CONTRT','--TOX','--TOXGR')
let $findingvars := ('--TESTCD','--TEST','--MODIFY','--TSTDTL','--CAT','--SCAT','--POS','--BODSYS','--ORRES','--ORRESU','--ORNRLO','--ORNRHI','--STRESC','--STRESN','--STRESU','--STNRLO','--STNRHI','--STNRC','--NRIND','--RESCAT','--STAT','--REASND','--XFN','--NAM','--LOINC','--SPEC','--ANTREG','--SPCCND','--SPCUFL','--LOC','--LAT','--DIR','--PORTOT','--METHOD','--RUNID','--ANMETH','--LEAD','--CSTATE','--BLFL','--FAST','--DRVFL','--EVAL','--EVALID','--ACPTFL','--TOX','--TOXGR','--SEV','--DTHREL','--LLOQ','--ULOQ','--EXCLFL','--REASEX')
(: FA-domains: --OBJ - comes after --TEST :)
let $findingsaboutvars := ('--TESTCD','--TEST','--OBJ','--MODIFY','--TSTDTL','--CAT','--SCAT','--POS','--BODSYS','--ORRES','--ORRESU','--ORNRLO','--ORNRHI','--STRESC','--STRESN','--STRESU','--STNRLO','--STNRHI','--STNRC','--NRIND','--RESCAT','--STAT','--REASND','--XFN','--NAM','--LOINC','--SPEC','--ANTREG','--SPCCND','--SPCUFL','--LOC','--LAT','--DIR','--PORTOT','--METHOD','--RUNID','--ANMETH','--LEAD','--CSTATE','--BLFL','--FAST','--DRVFL','--EVAL','--EVALID','--ACPTFL','--TOX','--TOXGR','--SEV','--DTHREL','--LLOQ','--ULOQ','--EXCLFL','--REASEX')
(: Special purpose: Comments (CO) domain -
Remark that we do not allow for COVAL1, COVAL2, ... as we are using Dataset-XML
which doesn't have the 200 character limitation :)
let $commentvars := ('STUDYID','DOMAIN','RDOMAIN','USUBJID','POOLID','COSEQ','IDVAR','IDVARVAL','COREF','COVAL','COEVAL','CODTC')
(: Subject Elements (SE) :)
let $subjectelementsvar := ('STUDYID','DOMAIN','USUBJID','SESEQ','ETCD','ELEMENT','SESTDTC','SEENDTC','TAETORD','EPOCH','SEUPDES')
(: Subject Visits (SV) :)
let $subjectvisitsvar := ('STUDYID','DOMAIN','USUBJID','VISITNUM','VISIT','VISITDY','SVSTDTC','SVENDTC','SVSTDY','SVENDY','SVUPDES')
(: Trial Design datasets :)
(: Trial Elements (TE) :)
let $trialelementvars := ('STUDYID','DOMAIN','ETCD','ELEMENT','TESTRL','TEENRL','TEDUR')
(: Trial Arms :)
let $trialarmvars := ('STUDYID','DOMAIN','ARMCD','ARM','TAETORD','ETCD','ELEMENT','TABRANCH','TATRANS','EPOCH')
(: Trial Visits (TV) :)
let $trialvisitvars := ('STUDYID','DOMAIN','VISITNUM','VISIT','VISITDY','ARMCD','ARM','TVSTRL','TVENRL')
(: Trial Sets (TX) :)
let $trialsetvars := ('STUDYID','DOMAIN','SETCD','SET','TXSEQ','TXPARMCD','TXPARM','TXVAL')
(: Trial Inclusion/Exclusion Criteria (TI) :)
let $trialievars := ('STUDYID','DOMAIN','IETESTCD','IETEST','IECAT','IESCAT','TIRL','TIVERS')
(: Trial Summary (TS) :)
let $trialsummaryvars := ('STUDYID','DOMAIN','TSSEQ','TSGRPID','TSPARMCD','TSPARM','TSVAL','TSVALNF','TSVALCD','TSVCDREF','TSVCDVER')
(: Trial Disease Assessments (TD) :)
let $trialdiseasevars := ('STUDYID','DOMAIN','TDORDER','TDANCVAR','TDSTOFF','TDTGTPAI','TDMINPAI','TDMAXPAI','TDNUMRPT')
(: Related Records (RELREC) :)
let $relrecvars := ('STUDYID','RDOMAIN','USUBJID','APID','POOLID','IDVAR','IDVARVAL','RELTYPE','RELID')
(: Get the define.xml file :)
(: let $base:= '/db/fda_submissions/cdiscpilot01/' :)
(: let $define := 'define_2_0.xml' :)
(: iterate over all ItemGroupDef elements in define.xml :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name=$domain or @Domain=$domain]
let $datasetname := $dataset/@Name
(: get the 2-letter domain (except for SUPPQUAL, RELREC, ...)
as we need it to replace the "--" by the domain code
:)
(: Get the domain name and class :)
(: let $domaincode := $dataset/@Name :)
let $domaincode := $dataset/@Domain
let $domainclass := $dataset/@def:Class
(: iterate over the ItemRef elements and get the OID - then transform it to the Name
make an array out of it :)
let $vararray := (
for $itemref in $dataset/odm:ItemRef
(: Attention - we need to exclude non-standard variables (NSVs) :)
let $itemrefoid := $itemref[not(starts-with(upper-case(@Role),'SUPPLEMENTAL'))]/@ItemOID
(: Get the name of the variable from the corresponding ItemDef :)
let $varname := doc(concat($base,$define))//odm:ItemDef[@OID=$itemrefoid]/@Name
return $varname
)
(: now create the array to compare with - we need to replace any '--' by the domain code :)
(: replace any dashes in the variable names by the domain code :)
let $identifiers := local:replacedash($identifiers,$domaincode)
let $timingvars := local:replacedash($timingvars,$domaincode)
let $interventionvars := local:replacedash($interventionvars,$domaincode)
let $eventvars := local:replacedash($eventvars,$domaincode)
let $findingvars := local:replacedash($findingvars,$domaincode)
(: combine all variables: identifiers, class-specific variables and timing variables
into a single sequence :)
let $standardvars := (
if ($domaincode = 'DM') then $dmvars
else if($domaincode = 'CO') then $commentvars
else if($domaincode = 'SE') then $subjectelementsvar
else if($domaincode = 'SV') then $subjectvisitsvar
else if($domaincode = 'TV') then $trialvisitvars
(: Trial Design datasets :)
else if($domaincode = 'TE') then $trialelementvars
else if($domaincode = 'TA') then $trialarmvars
else if($domaincode = 'TX') then $trialsetvars
else if($domaincode = 'TI') then $trialievars
else if($domaincode = 'TS') then $trialsummaryvars
else if($domaincode = 'TD') then $trialdiseasevars
(: Related Records dataset :)
else if($domaincode = 'RELREC') then $relrecvars
else if (upper-case($domainclass) = 'INTERVENTIONS' ) then
functx:value-union(functx:value-union($identifiers,$interventionvars),$timingvars)
else if (upper-case($domainclass) = 'EVENTS') then
functx:value-union(functx:value-union($identifiers,$eventvars),$timingvars)
else if (upper-case($domainclass) = 'FINDINGS') then
functx:value-union(functx:value-union($identifiers,$findingvars),$timingvars)
else ()
)
(: now check whether each of the variables in the SDTM dataset as declared in the define.xml is in the sequence of the allowed variables :)
for $var in $vararray
where functx:is-value-in-sequence($var,$standardvars) = false()
(: and give an error when this is not the case :)
return <error rule="FDAC027" dataset="{data($datasetname)}" variable="{data($var)}" rulelastupdate="2016-03-26">Variable {data($var)} is not in the SDTM model (v.1.4) for domain {data($domaincode)} </error>
Define.xml/dataset variable type mismatch - Variable Data Types in the dataset must match the variable data types described in the data definition document (define.xml)
ALL
(: Rule FDAC034 - Define.xml/dataset variable type mismatch:
Variable Data Types in the dataset must match the variable data types described in the data definition document (define.xml)
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace functx = "http://www.functx.com";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
declare variable $domain external;
(: some own local functions :)
declare function functx:isPartialDatetime
( $arg as xs:string? ) as xs:string {
let $testvalue :=
(: only the year is given :)
if(string-length($arg) = 4) then concat($arg,'-01-01T00:00:00')
(: only the year and month is given :)
else if(string-length($arg) = 7) then concat($arg,'-01T00:00:00')
(: date is complete but time part is missing :)
else if(string-length($arg) = 10) then concat($arg,'T00:00:00')
(: data is complete but only hour is given :)
else if(string-length($arg) = 14) then concat($arg,':00:00')
(: date, hour and minutes are given, but seconds is missing :)
else if(string-length($arg) = 17) then concat($arg,':00')
(: date seems to be complete :)
else $arg
return $testvalue castable as xs:date
} ;
declare function functx:isPartialDate ( $arg as xs:string? ) as xs:boolean {
let $testvalue :=
(: only the year is given :)
if(string-length($arg) = 4) then concat($arg,'-01-01')
(: only year and month is given :)
else if(string-length($arg) = 7) then concat($arg,'-01')
(: date seems to be complete :)
else $arg
return $testvalue castable as xs:date
} ;
declare function functx:isPartialTime ( $arg as xs:string? ) as xs:boolean {
let $testvalue :=
(: only the hour is given :)
if(string-length($arg) = 4) then concat($arg,':00:00')
(: only hour and minutes are given :)
else if(string-length($arg) = 7) then concat($arg,':00')
(: time seems to be complete :)
else $arg
return $testvalue castable as xs:time
} ;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: let $domain := 'ALL' :)
(: EITHER provide $domain=:'ALL', meaning: validate for all domains referenced from the define.xml OR:
$domain:='XX' where XX is a specific domain, MEANING validate for a single domain only :)
(: get the definitions for the domains (ItemGroupDefs in define.xml) :)
let $domains := (
if($domain != 'ALL') then doc(concat($base,$define))//odm:ItemGroupDef[@Domain=$domain]
else doc(concat($base,$define))//odm:ItemGroupDef
)
(: iterate over all datasets :)
for $dataset in $domains
let $datasetname := $dataset/@Name
let $datasetlocation := concat($base,$dataset/def:leaf/@xlink:href)
for $record in doc($datasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: iterate over all datapoints in the record, get OID and value :)
for $datapoint in $record/odm:ItemData
let $itemoid := $datapoint/@ItemOID
let $itemvalue := $datapoint/@Value
(: get the datatype in the corresponding ItemDef :)
let $datatype := doc(concat($base,$define))//odm:ItemDef[@OID=$itemoid]/@DataType
let $varname := doc(concat($base,$define))//odm:ItemDef[@OID=$itemoid]/@Name
(: define.xml allows following datatypes:
text, integer, float, datetime, date, time, partialDate, partialTime, partialDatetime,
incompleteDatetime, durationDatetime
:)
(: $isValidDataTypeValue is boolean :)
let $isValidDataTypeValue :=
if ($datatype = 'text') then 'true' (: everything is text ... :)
else if($datatype = 'integer' and $itemvalue castable as xs:integer) then 'true'
else if($datatype = 'float' and $itemvalue castable as xs:double) then 'true'
else if($datatype = 'datetime' and $itemvalue castable as xs:dateTime) then 'true'
else if($datatype = 'date' and $itemvalue castable as xs:date) then 'true'
else if($datatype = 'time' and $itemvalue castable as xs:time) then 'true'
(: use function for partialDate :)
else if($datatype = 'partialDate' and functx:isPartialDate($itemvalue)) then 'true'
(: use function for partialTime :)
else if($datatype = 'partialTime' and functx:isPartialTime($itemvalue)) then 'true'
(: use function for partialDateTime :)
else if($datatype = 'partialDateTime' and functx:isPartialDatetime($itemvalue) = 'true') then true
(: TODO: write function for incompleteDatetime :)
else if($datatype = 'durationDatetime' and $itemvalue castable as xs:duration) then 'true'
(: TODO: write function for other form of durationDatetime ("from-to" format) :)
else 'false'
where $isValidDataTypeValue = 'false'
return <error rule="FDAC034" dataset="{data($datasetname)}" variable="{data($varname)}" rulelastupdate="2015-09-08" recordnumber="{data($recnum)}">Define.xml/dataset variable type mismatch - Data point with OID = {data($itemoid)} and name = {data($varname)} and value {data($itemvalue)} is expected to be of type {data($datatype)}</error>
Variable is in wrong order within domain - Order of variables should be as specified by CDISC standard
ALL
(: Rule FDAC035 - Variables are ordered with Identifiers first, followed by the Topic, Qualifier, and Timing variables.
Within each role, variables are ordered as shown in SDTM: Tables 2.2.1, 2.2.2, 2.2.3, 2.2.3.1, 2.2.4, and 2.2.5
We must look into the SDTM specification itself, make a list (how do we deal with prefixes?) and then compare the list with the order in the define.xml.
Is it also possible (in a second step?) to compare the order of the variables in each record with that in the define.xml?
:)
(: Rule FDAC035: Variable is in wrong order within domain: Order of variables should be as specified by CDISC standard :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare namespace functx = "http://www.functx.com";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: function to find out whether a value is in a sequence (array) :)
declare function functx:is-value-in-sequence
( $value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
(: value-intersect function: returns the intersection of two sequences :)
declare function functx:value-intersect
( $arg1 as xs:anyAtomicType* ,
$arg2 as xs:anyAtomicType* ) as xs:anyAtomicType* {
distinct-values($arg1[.=$arg2])
} ;
(: combines two sequences :)
declare function functx:value-union
( $arg1 as xs:anyAtomicType* ,
$arg2 as xs:anyAtomicType* ) as xs:anyAtomicType* {
distinct-values(($arg1, $arg2))
} ;
(: This function compares two sequences in which the second is a subset of the first.
If the order in both is the same, the function returns 'true', if the order is different, it returns 'false' :)
declare function local:compare($sequence1, $sequence2) {
let $new-list :=
for $id in $sequence1
where $id = $sequence2
return $id
return string-join($sequence2,'') eq string-join($new-list, '')
} ;
(: function replacing two subsequent dashes with the domain code :)
declare function local:replacedash($sequence,$domain) {
for $v in $sequence
return replace($v,'\-\-',$domain)
} ;
(: Identifiers for all classes :)
let $identifiers := ('STUDYID','DOMAIN','USUBJID','POOLID','SPDEVID','--SEQ','--GRPID',
'--REFID','--SPID','--LNKID','--LNKGRP')
(: Timing variables for all classes :)
let $timingvars := ('VISITNUM','VISIT','VISITDY','TAETORD','EPOCH','--DTC','--STDTC','--ENDTC', '--DY','--STDY','--ENDY','--DUR','--TPT','--TPTNUM','--ELTM','--TPTREF','--RFTDTC','--STRF','--ENRF','--EVLINT','--EVINTX','--STRTPT','--STTPT','--ENRTPT','--ENTPT','--STINT','--ENINT','--DETECT')
let $dmvars := ('STUDYID','DOMAIN','USUBJID','SUBJID','RFSTDTC','RFENDTC','RFXSTDTC','RFXENDTC','RFICDTC','RFPENDTC','DTHDTC','DTHFL','SITEID','INVID','INVNAM','BRTHDTC','AGE','AGETXT','AGEU','SEX','RACE','ETHNIC','SPECIES','STRAIN','SBSTRAIN','ARMCD','ARM','ACTARMCD','ACTARM','SETCD','COUNTRY','DMDTC','DMDY')
(: variables for Interventions classes :)
let $interventionvars := ('--TRT','--MODIFY','--DECOD','--MOOD','--CAT','--SCAT','--PRESP','--OCCUR','--STAT','--REASND','--INDC','--CLAS','--CLASCD','--DOSE','--DOSTXT','--DOSU','--DOSFRM','--DOSFRQ','--DOSTOT','--DOSRGM','--ROUTE','--LOT','--LOC','--LAT','--DIR','--PORTOT','--FAST','--PSTRG','--PSTRGU','--TRTV','--VAMT','--VAMTU','--ADJ')
(: variables for all Event classes :)
let $eventvars := ('--TERM','--MODIFY','--LLT','--LLTCD','--DECOD','--PTCD','--HLT','--HLTCD','--HLGT','--HLGTCD','--CAT','--SCAT','--PRESP','--OCCUR','--STAT','--REASND','--BODSYS','--BDSYCD','--SOC','--SOCCD','--LOC','--LAT','--DIR','--PORTOT','--PARTY','--PRTYID','--SEV','--SER','--ACN','--ACNOTH','--ACNDEV','--REL','--RELNST','--PATT','--OUT','--SCAN','--SCONG','--SDISAB','--SDTH','--SHOSP','--SLIFE','--SOD','--SMIE','--CONTRT','--TOX','--TOXGR')
let $findingvars := ('--TESTCD','--TEST','--MODIFY','--TSTDTL','--CAT','--SCAT','--POS','--BODSYS','--ORRES','--ORRESU','--ORNRLO','--ORNRHI','--STRESC','--STRESN','--STRESU','--STNRLO','--STNRHI','--STNRC','--NRIND','--RESCAT','--STAT','--REASND','--XFN','--NAM','--LOINC','--SPEC','--ANTREG','--SPCCND','--SPCUFL','--LOC','--LAT','--DIR','--PORTOT','--METHOD','--RUNID','--ANMETH','--LEAD','--CSTATE','--BLFL','--FAST','--DRVFL','--EVAL','--EVALID','--ACPTFL','--TOX','--TOXGR','--SEV','--DTHREL','--LLOQ','--ULOQ','--EXCLFL','--REASEX')
(: FA-domains: --OBJ - comes after --TEST :)
let $findingsaboutvars := ('--TESTCD','--TEST','--OBJ','--MODIFY','--TSTDTL','--CAT','--SCAT','--POS','--BODSYS','--ORRES','--ORRESU','--ORNRLO','--ORNRHI','--STRESC','--STRESN','--STRESU','--STNRLO','--STNRHI','--STNRC','--NRIND','--RESCAT','--STAT','--REASND','--XFN','--NAM','--LOINC','--SPEC','--ANTREG','--SPCCND','--SPCUFL','--LOC','--LAT','--DIR','--PORTOT','--METHOD','--RUNID','--ANMETH','--LEAD','--CSTATE','--BLFL','--FAST','--DRVFL','--EVAL','--EVALID','--ACPTFL','--TOX','--TOXGR','--SEV','--DTHREL','--LLOQ','--ULOQ','--EXCLFL','--REASEX')
(: Special purpose: Comments (CO) domain -
Remark that we do not allow for COVAL1, COVAL2, ... as we are using Dataset-XML
which doesn't have the 200 character limitation :)
let $commentvars := ('STUDYID','DOMAIN','RDOMAIN','USUBJID','POOLID','COSEQ','IDVAR','IDVARVAL','COREF','COVAL','COEVAL','CODTC')
(: Subject Elements (SE) :)
let $subjectelementsvar := ('STUDYID','DOMAIN','USUBJID','SESEQ','ETCD','ELEMENT','SESTDTC','SEENDTC','TAETORD','EPOCH','SEUPDES')
(: Subject Visits (SV) :)
let $subjectvisitsvar := ('STUDYID','DOMAIN','USUBJID','VISITNUM','VISIT','VISITDY','SVSTDTC','SVENDTC','SVSTDY','SVENDY','SVUPDES')
(: Trial Design datasets :)
(: Trial Elements (TE) :)
let $trialelementvars := ('STUDYID','DOMAIN','ETCD','ELEMENT','TESTRL','TEENRL','TEDUR')
(: Trial Arms :)
let $trialarmvars := ('STUDYID','DOMAIN','ARMCD','ARM','TAETORD','ETCD','ELEMENT','TABRANCH','TATRANS','EPOCH')
(: Trial Visits (TV) :)
let $trialvisitvars := ('STUDYID','DOMAIN','VISITNUM','VISIT','VISITDY','ARMCD','ARM','TVSTRL','TVENRL')
(: Trial Sets (TX) :)
let $trialsetvars := ('STUDYID','DOMAIN','SETCD','SET','TXSEQ','TXPARMCD','TXPARM','TXVAL')
(: Trial Inclusion/Exclusion Criteria (TI) :)
let $trialievars := ('STUDYID','DOMAIN','IETESTCD','IETEST','IECAT','IESCAT','TIRL','TIVERS')
(: Trial Summary (TS) :)
let $trialsummaryvars := ('STUDYID','DOMAIN','TSSEQ','TSGRPID','TSPARMCD','TSPARM','TSVAL','TSVALNF','TSVALCD','TSVCDREF','TSVCDVER')
(: Trial Disease Assessments (TD) :)
let $trialdiseasevars := ('STUDYID','DOMAIN','TDORDER','TDANCVAR','TDSTOFF','TDTGTPAI','TDMINPAI','TDMAXPAI','TDNUMRPT')
(: Related Records (RELREC) :)
let $relrecvars := ('STUDYID','RDOMAIN','USUBJID','APID','POOLID','IDVAR','IDVARVAL','RELTYPE','RELID')
(: supplemental qualifiers (SUPPxx) :)
let $suppqualvars := ('STUDYID','RDOMAIN','USUBJID','APID','POOLID','IDVAR','IDVARVAL','QNAM','QLABEL','QVAL','QORIG','QEVAL')
(: Get the define.xml file :)
(: let $base:= '/db/fda_submissions/cdiscpilot01/' :)
(: let $define := 'define_2_0.xml' :)
let $datasetdoc := doc(concat($base,$define))
(: iterate over all ItemGroupDef elements in define.xml :)
for $dataset in $datasetdoc//odm:ItemGroupDef
(: get the 2-letter domain (except for SUPPQUAL, RELREC, ...)
as we need it to replace the "--" by the domain code
:)
(: Get the domain name and class :)
(: let $domaincode := $dataset/@Name :)
(: take care of the case that the Domain attribute is absent :)
let $domaincode := if ($dataset/@Domain) then $dataset/@Domain
else $dataset/@Name
let $domainclass := $dataset/@def:Class
let $datasetname := $dataset/@Name
(: iterate over the ItemRef elements and get the OID - then transform it to the Name
make an array out of it :)
let $vararray := (
for $itemref in $dataset/odm:ItemRef
(: Attention - we need to exclude non-standard variables (NSVs) :)
let $itemrefoid := $itemref[not(starts-with(upper-case(@Role),'SUPPLEMENTAL'))]/@ItemOID
(: Get the name of the variable from the corresponding ItemDef :)
let $varname := doc(concat($base,$define))//odm:ItemDef[@OID=$itemrefoid]/@Name
return $varname
)
(: now create the array to compare with - we need to replace any '--' by the domain code :)
(: replace any dashes in the variable names by the domain code :)
let $identifiers := local:replacedash($identifiers,$domaincode)
let $timingvars := local:replacedash($timingvars,$domaincode)
let $interventionvars := local:replacedash($interventionvars,$domaincode)
let $eventvars := local:replacedash($eventvars,$domaincode)
let $findingvars := local:replacedash($findingvars,$domaincode)
(: combine all variables: identifiers, class-specific variables and timing variables
into a single sequence :)
let $standardvars := (
if ($domaincode = 'DM') then $dmvars
else if($domaincode = 'CO') then $commentvars
else if($domaincode = 'SE') then $subjectelementsvar
else if($domaincode = 'SV') then $subjectvisitsvar
else if($domaincode = 'TV') then $trialvisitvars
(: Trial Design datasets :)
else if($domaincode = 'TE') then $trialelementvars
else if($domaincode = 'TA') then $trialarmvars
else if($domaincode = 'TX') then $trialsetvars
else if($domaincode = 'TI') then $trialievars
else if($domaincode = 'TS') then $trialsummaryvars
else if($domaincode = 'TD') then $trialdiseasevars
else if(starts-with($domaincode,'SUPP')) then $suppqualvars
(: Related Records dataset :)
else if($domaincode = 'RELREC') then $relrecvars
else if (upper-case($domainclass) = 'INTERVENTIONS' ) then
functx:value-union(functx:value-union($identifiers,$interventionvars),$timingvars)
else if (upper-case($domainclass) = 'EVENTS') then
functx:value-union(functx:value-union($identifiers,$eventvars),$timingvars)
else if (upper-case($domainclass) = 'FINDINGS') then
functx:value-union(functx:value-union($identifiers,$findingvars),$timingvars)
else ()
)
(: if 'false' is returned by local:compare then the order is incorrect :)
where local:compare($standardvars,$vararray) = false()
return <warning rule="FDAC035" dataset="{data($datasetname)}" rulelastupdate="2017-03-11">{data($datasetname)} - domain {data($domaincode)}: Invalid order of variables in define.xml - found: {data($vararray)}
- expected: {data($standardvars)}</warning>
Value for variable not found in user-defined codelist - Variable values should be populated with terms found in the user-defined codelist associated with the variable in define.xml
ALL
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace functx = "http://www.functx.com";
declare function functx:is-value-in-sequence
( $value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: find all dataset definitions :)
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
let $definedoc := doc(concat($base,$define))
(: iterate over all dataset definitions :)
for $itemgroupdef in $definedoc//odm:ItemGroupDef
let $name := $itemgroupdef/@Name
(: get the location of the dataset and document :)
let $datasetlocation := $itemgroupdef/def:leaf/@xlink:href
let $datasetdoc := doc(concat($base,$datasetlocation))
(: get the OIDs of the coded variables for this dataset.
We currently still need to exclude "External" CodeLists as long as they do not have a RESTful WS available,
and as long as ODM/Dataset-XML does not support RESTful web services :)
let $codedoids := (
for $a in $definedoc//odm:ItemDef[odm:CodeListRef]/@OID
where $a = $itemgroupdef/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records in the dataset, but only when they contain coded values :)
for $record in $datasetdoc[count($codedoids)>0]//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: iterate over the coded variables :)
for $codeditem in $record/odm:ItemData[functx:is-value-in-sequence(@ItemOID,$codedoids)]
(: get the OID and value :)
let $oid := $codeditem/@ItemOID
let $value := $codeditem/@Value
(: also get the variable name for reporting :)
let $varname := $definedoc//odm:ItemDef[@OID=$oid]/@Name
(: look up the allowed values for this coded item in the define.xml :)
let $codelistoid := $definedoc//odm:ItemDef[@OID=$oid]/odm:CodeListRef/@CodeListOID
(: P.S. exclude "ExternalCodeList" :)
let $allowedvalues := $definedoc//odm:CodeList[not(odm:ExternalCodeList)][@OID=$codelistoid]/odm:*/@CodedValue
(: the value must be one of the coded values :)
where count($allowedvalues) > 0 and not(functx:is-value-in-sequence($value,$allowedvalues))
return <error rule="FDAC037" dataset="{data($name)}" variable="{data($varname)}" recordnumber="{data($recnum)}" rulelastupdate="2017-03-20">Value for variable {data($varname)}: value {data($value)} not found in not found in user-defined codelist {data($codelistoid)}</error>
Value for variable not found in user-defined codelist - Variable values should be populated with terms found in the user-defined codelist associated with the variable in define.xml
ALL
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace functx = "http://www.functx.com";
declare function functx:is-value-in-sequence
( $value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
declare variable $domain external;
(: find all dataset definitions :)
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
let $definedoc := doc(concat($base,$define))
(: iterate over all dataset definitions :)
for $itemgroupdef in $definedoc//odm:ItemGroupDef[@Domain=$domain or starts-with(@Name,domain)]
let $name := $itemgroupdef/@Name
(: get the location of the dataset and document :)
let $datasetlocation := $itemgroupdef/def:leaf/@xlink:href
let $datasetdoc := doc(concat($base,$datasetlocation))
(: get the OIDs of the coded variables for this dataset.
We currently still need to exclude "External" CodeLists as long as they do not have a RESTful WS available,
and as long as ODM/Dataset-XML does not support RESTful web services :)
let $codedoids := (
for $a in $definedoc//odm:ItemDef[odm:CodeListRef]/@OID
where $a = $itemgroupdef/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records in the dataset, but only when they contain coded values :)
for $record in $datasetdoc[count($codedoids)>0]//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: iterate over the coded variables :)
for $codeditem in $record/odm:ItemData[functx:is-value-in-sequence(@ItemOID,$codedoids)]
(: get the OID and value :)
let $oid := $codeditem/@ItemOID
let $value := $codeditem/@Value
(: also get the variable name for reporting :)
let $varname := $definedoc//odm:ItemDef[@OID=$oid]/@Name
(: look up the allowed values for this coded item in the define.xml :)
let $codelistoid := $definedoc//odm:ItemDef[@OID=$oid]/odm:CodeListRef/@CodeListOID
(: P.S. exclude "ExternalCodeList" :)
let $allowedvalues := $definedoc//odm:CodeList[not(odm:ExternalCodeList)][@OID=$codelistoid]/odm:*/@CodedValue
(: the value must be one of the coded values :)
where count($allowedvalues) > 0 and not(functx:is-value-in-sequence($value,$allowedvalues))
return <error rule="FDAC037" dataset="{data($name)}" variable="{data($varname)}" recordnumber="{data($recnum)}" rulelastupdate="2017-03-20">Value for variable {data($varname)}: value {data($value)} not found in not found in user-defined codelist {data($codelistoid)}</error>
Invalid ISO 8601 value for *DTC variable - Value of Dates/Time variables (*DTC) must conform to the ISO 8601 international standard
ALL
(: Rule FDAC038 - Invalid ISO 8601 value for *DTC variable :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: need a function substring-after-last - see e.g. http://www.xqueryfunctions.com/xq/functx_substring-after-last.html :)
declare namespace functx = "http://www.functx.com";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
declare function functx:escape-for-regex
( $arg as xs:string? ) as xs:string {
replace($arg,
'(\.|\[|\]|\\|\||\-|\^|\$|\?|\*|\+|\{|\}|\(|\))','\\$1')
} ;
declare function functx:substring-after-last
( $arg as xs:string? ,
$delim as xs:string ) as xs:string {
replace ($arg,concat('^.*',functx:escape-for-regex($delim)),'')
} ;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
for $doc in collection($base)
(: get the filename :)
let $filename := functx:substring-after-last(document-uri($doc),'/')
(: get the corresponding ItemGroupDef node in the define.xml :)
let $itemgroupdef := doc(concat($base,$define))//odm:ItemGroupDef[def:leaf/@xlink:href=$filename]
let $itemgroupdefoid := $itemgroupdef/@OID
let $itemgroupdefname := $itemgroupdef/@Name
(: get the Items for which the name ends with DTC :)
for $itemoid in $itemgroupdef/odm:ItemRef/@ItemOID
for $itemdefdatetimetype in $itemgroupdef/../odm:ItemDef[@OID=$itemoid][ends-with(@Name,'DTC')]
let $itemoiddtc := $itemdefdatetimetype/@OID
let $itemname := $itemgroupdef/../odm:ItemDef[@OID=$itemoid]/@Name
(: and now find them in the dataset itself :)
for $itemdata in $doc//odm:ItemData[@ItemOID=$itemoiddtc]
let $recnum := $itemdata/../@data:ItemGroupDataSeq
let $value := $itemdata/@Value
(: allow for partial dates and datetimes :)
let $testvalue :=
(: only the year is given :)
if(string-length($value) = 4) then concat($value,'-01-01')
(: only the month is given :)
else if(string-length($value) = 7) then concat($value,'-01')
(: T is given but no hours - might bei invalid anyway :)
else if(string-length($value) = 11) then concat($value,'00:00:00')
(: only hour is given :)
else if(string-length($value) = 13) then concat($value,':00:00')
(: hour and minutes are given, but no seconds :)
else if(string-length($value) = 16) then concat($value,':00')
(: all ok anyway :)
else ($value)
where not($testvalue castable as xs:date) and not($testvalue castable as xs:dateTime )
return <error rule="FDAC038" dataset="{data($itemgroupdefname)}" variable="{data($itemname)}" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">invalid ISO-8601 value for variable {data($itemname)} value = {data($value)} in dataset {data($itemgroupdefname)}</error>
Invalid ISO 8601 value for (--DUR, --ELTM, or --EVLINT) variable - Value of Duration, Elapsed Time, and Interval variables (--DUR, --ELTM, --EVLINT) must conform to the ISO 8601 international standard
ALL
(: Rule FDAC039 - Invalid ISO 8601 value for (--DUR, --ELTM, or --EVLINT) variable :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: need a function substring-after-last - see e.g. http://www.xqueryfunctions.com/xq/functx_substring-after-last.html :)
declare namespace functx = "http://www.functx.com";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
declare function functx:escape-for-regex
( $arg as xs:string? ) as xs:string {
replace($arg,
'(\.|\[|\]|\\|\||\-|\^|\$|\?|\*|\+|\{|\}|\(|\))','\\$1')
} ;
declare function functx:substring-after-last
( $arg as xs:string? ,
$delim as xs:string ) as xs:string {
replace ($arg,concat('^.*',functx:escape-for-regex($delim)),'')
} ;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
for $doc in collection($base)
(: get the filename :)
let $filename := functx:substring-after-last(document-uri($doc),'/')
(: get the corresponding ItemGroupDef node in the define.xml :)
let $itemgroupdef := doc(concat($base,$define))//odm:ItemGroupDef[def:leaf/@xlink:href=$filename]
let $itemgroupdefoid := $itemgroupdef/@OID
let $itemgroupdefname := $itemgroupdef/@Name
(: get the Items for which the name ends with DTC :)
for $itemoid in $itemgroupdef/odm:ItemRef/@ItemOID
for $itemdefdatetimetype in $itemgroupdef/../odm:ItemDef[@OID=$itemoid][ends-with(@Name,'DUR') or ends-with(@Name,'ELTM') or ends-with(@Name,'EVLINT')]
let $itemoiddtc := $itemdefdatetimetype/@OID
let $itemname := $itemgroupdef/../odm:ItemDef[@OID=$itemoid]/@Name
(: and now find them in the dataset itself :)
for $itemdata in $doc//odm:ItemData[@ItemOID=$itemoiddtc]
let $recnum := $itemdata/../@data:ItemGroupDataSeq
let $value := $itemdata/@Value
(: this still gives an error on PnW and -PnW so check on this :)
let $isweekduration :=
if ((starts-with($value,'P') and ends-with($value,'W')
and substring($value,2,string-length($value)-2) castable as xs:integer))
then 1
else if ((starts-with($value,'-P') and ends-with($value,'W')
and substring($value,3,string-length($value)-3) castable as xs:integer))
then 1
else 0 (: not a valid week duration :)
where not($value castable as xs:duration) and not($isweekduration = 1)
return <error rule="FDAC039" dataset="{data($itemgroupdefname)}" variable="{data($itemname)}" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">invalid ISO-8601 duration for variable {data($itemname)} value = {data($value)} in dataset {data($itemgroupdefname)} </error>
Subject is not present in DM domain - All Subjects (USUBJID) must be present in Demographics (DM) domain
ALL
(: Rule FDAC040 FAST ALTERNATIVE - All Subjects (USUBJID) must be present in Demographics (DM) domain :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace functx = "http://www.functx.com";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
declare function functx:is-value-in-sequence
( $value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: request-parameter allows to pass $base from an external programm :)
(: let $base:= request:get-parameter("mybase","/db/fda_submissions/cdiscpilot01/") :)
(: let $define := request:get-parameter("mydefine","define_2_0.xml") :)
(: let $base := '/db/fda_submissions/cdiscpilot01/' :)
(: let $define := 'define_2_0.xml' :)
(: we need the ItemOID of the USUBJID variable - and need to take care of the use case that people have used different ItemDefs for the same variable in
different domains/datasets :)
(: first get the one for the DM dataset :)
(: let $dmitemgroupdef := doc(concat($base,$define)) :)
let $dmitemgroupdef := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']
let $dmdatasetname := $dmitemgroupdef/def:leaf/@xlink:href
let $dmdatasetpath := concat($base,$dmdatasetname)
(: this assumes that the third variable in the DM is USUBJID (which essentially always should be the case :)
let $usubjoiddm := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: and all the values in the DM dataset :)
let $usubjiddm := doc($dmdatasetpath)//odm:ItemData[@ItemOID=$usubjoiddm]/@Value
(: now iterate over all dataset definitions in the define.xml and get the USUBJID :)
for $itemgroupdef in doc(concat($base,$define))//odm:ItemGroupDef
let $dataset := $itemgroupdef/def:leaf/@xlink:href
let $datasetname := $itemgroupdef/@Name
let $datasetpath := concat($base,$dataset)
(: find the variable for which the name is 'USUBJID' - there should be 0 or 1 :)
let $usubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = $itemgroupdef/odm:ItemRef/@ItemOID
return $a
)
for $d in doc($datasetpath)//odm:ItemGroupData[odm:ItemData[@ItemOID=$usubjidoid]]
let $recnum := $d/@data:ItemGroupDataSeq
let $value := $d/odm:ItemData[@ItemOID=$usubjidoid]/@Value
(: check whether it DM-USUBJID :)
where not(functx:is-value-in-sequence($value,$usubjiddm))
return <error rule="FDAC040" rulelastupdate="2015-02-10" dataset="{data($datasetname)}" variable="USUBJID" recordnumber="{data($recnum)}">USUBJID {data($value)} in dataset {data($datasetname)} could not be found in DM dataset</error>
Subject is not present in DM domain, single dataset or domain - All Subjects (USUBJID) must be present in Demographics (DM) domain
ALL
(: Rule FDAC040 FAST ALTERNATIVE - All Subjects (USUBJID) must be present in Demographics (DM) domain :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace functx = "http://www.functx.com";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
declare variable $domain external;
declare function functx:is-value-in-sequence
( $value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: request-parameter allows to pass $base from an external programm :)
(: let $base:= request:get-parameter("mybase","/db/fda_submissions/cdiscpilot01/") :)
(: let $define := request:get-parameter("mydefine","define_2_0.xml") :)
(: let $base := '/db/fda_submissions/cdiscpilot01/' :)
(: let $define := 'define_2_0.xml' :)
(: we need the ItemOID of the USUBJID variable - and need to take care of the use case that people have used different ItemDefs for the same variable in
different domains/datasets :)
(: first get the one for the DM dataset :)
(: let $dmitemgroupdef := doc(concat($base,$define)) :)
let $dmitemgroupdef := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']
let $dmdatasetname := $dmitemgroupdef/def:leaf/@xlink:href
let $dmdatasetpath := concat($base,$dmdatasetname)
(: this assumes that the third variable in the DM is USUBJID (which essentially always should be the case :)
let $usubjoiddm := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: and all the values in the DM dataset :)
let $usubjiddm := doc($dmdatasetpath)//odm:ItemData[@ItemOID=$usubjoiddm]/@Value
(: now iterate over all dataset definitions in the define.xml and get the USUBJID :)
for $itemgroupdef in doc(concat($base,$define))//odm:ItemGroupDef[@Name=$domain or @Domain=$domain]
let $dataset := $itemgroupdef/def:leaf/@xlink:href
let $datasetname := $itemgroupdef/@Name
let $datasetpath := concat($base,$dataset)
(: find the variable for which the name is 'USUBJID' - there should be 0 or 1 :)
let $usubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = $itemgroupdef/odm:ItemRef/@ItemOID
return $a
)
for $d in doc($datasetpath)//odm:ItemGroupData[odm:ItemData[@ItemOID=$usubjidoid]]
let $recnum := $d/@data:ItemGroupDataSeq
let $value := $d/odm:ItemData[@ItemOID=$usubjidoid]/@Value
(: check whether it DM-USUBJID :)
where not(functx:is-value-in-sequence($value,$usubjiddm))
return <error rule="FDAC040" rulelastupdate="2015-02-10" dataset="{data($datasetname)}" variable="USUBJID" recordnumber="{data($recnum)}">USUBJID {data($value)} in dataset {data($datasetname)} could not be found in DM dataset</error>
Missing or redundant values for USUBJID and POOLID - Either Unique Subject Identifier (Missing or redundant values for USUBJID and POOLIDUSUBJID) or Pool Identifier (POOLID) variables values and only one must be populated
ALL
(: Rule FDAC042 - Missing or redundant values for USUBJID and POOLID:
Either Unique Subject Identifier (Missing or redundant values for USUBJID and POOLIDUSUBJID) or Pool Identifier (POOLID) variables values and only one must be populated :)
xquery version "3.0";
(: POOLID is e.g. used in RELREC :)
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: declare variable $domain external; :)
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
let $domain := 'ALL'
(: EITHER provide $domain=:'ALL', meaning: validate for all domains referenced from the define.xml OR:
$domain:='XX' where XX is a specific domain, MEANING validate for a single domain only :)
(: get the definitions for the domains (ItemGroupDefs in define.xml) :)
let $datasets := (
if($domain != 'ALL') then doc(concat($base,$define))//odm:ItemGroupDef[@Domain=$domain]
else doc(concat($base,$define))//odm:ItemGroupDef
)
(: now iterate over all dataset definitions in the define.xm and get the USUBJID :)
for $itemgroupdef in $datasets
let $datasetname := $itemgroupdef/@Name
let $datasetlink := $itemgroupdef/def:leaf/@xlink:href
let $datasetpath := concat($base,$datasetlink)
(: get the OID of the POOLID variable :)
let $poolidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='POOLID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$datasetname]/odm:ItemRef/@ItemOID
return $a
)
(: find the variable for which the name is 'USUBJID' - there should be 0 or 1 :)
for $var in $itemgroupdef/odm:ItemRef
let $oid := $var/@ItemOID
(: we cannot have a "where" here - TODO is there a better way? :)
(: $oid now contains the OID of the USUBJID variable for this dataset (if any) :)
(: iterate over the records in the dataset :)
for $d in doc($datasetpath)//odm:ItemGroupData
let $recnum := $d/@data:ItemGroupDataSeq
(: There is no data point with USUBJID nor a data point with POOLID (though USUBJID is been defined for this dataset) :)
(: case that both USUBJID AND POOLID are populated :)
where ($itemgroupdef/../odm:ItemDef[@OID=$oid]/@Name = 'USUBJID') and not($d/odm:ItemData[@ItemOID=$oid]) and not($d/odm:ItemData[@ItemOID=$poolidoid])
(: case that both USUBJID AND POOLID are populated :)
or ($d/odm:ItemData[@ItemOID=$oid] and $d/odm:ItemData[@ItemOID=$poolidoid])
return <error rule="FDAC042" dataset="{$datasetname}" rulelastupdate="2016-03-25" recordnumber="{data($recnum)}">Both USUBJID and POOLID in dataset {data($datasetname)} are NULL or both POOLID and USUBJID are populated</error>
Missing or redundant values for USUBJID and POOLID, single domain or dataset - Either Unique Subject Identifier (Missing or redundant values for USUBJID and POOLIDUSUBJID) or Pool Identifier (POOLID) variables values and only one must be populated
ALL
(: Rule FDAC042 - Missing or redundant values for USUBJID and POOLID:
Either Unique Subject Identifier (Missing or redundant values for USUBJID and POOLIDUSUBJID) or Pool Identifier (POOLID) variables values and only one must be populated :)
xquery version "3.0";
(: POOLID is e.g. used in RELREC :)
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
declare variable $domain external;
(: declare variable $domain external; :)
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: let $domain := 'DS' :)
(: get the definitions for the domains (ItemGroupDefs in define.xml) :)
let $datasets := doc(concat($base,$define))//odm:ItemGroupDef[@Name=$domain or @Domain=$domain]
(: now iterate over all dataset definitions in the define.xm and get the USUBJID :)
for $itemgroupdef in $datasets
let $datasetname := $itemgroupdef/@Name
let $datasetlink := $itemgroupdef/def:leaf/@xlink:href
let $datasetpath := concat($base,$datasetlink)
(: get the OID of the POOLID variable :)
let $poolidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='POOLID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$datasetname]/odm:ItemRef/@ItemOID
return $a
)
(: find the variable for which the name is 'USUBJID' - there should be 0 or 1 :)
for $var in $itemgroupdef/odm:ItemRef
let $oid := $var/@ItemOID
(: we cannot have a "where" here - TODO is there a better way? :)
(: $oid now contains the OID of the USUBJID variable for this dataset (if any) :)
(: iterate over the records in the dataset :)
for $d in doc($datasetpath)//odm:ItemGroupData
let $recnum := $d/@data:ItemGroupDataSeq
(: There is no data point with USUBJID nor a data point with POOLID (though USUBJID is been defined for this dataset) :)
(: case that both USUBJID AND POOLID are populated :)
where ($itemgroupdef/../odm:ItemDef[@OID=$oid]/@Name = 'USUBJID') and not($d/odm:ItemData[@ItemOID=$oid]) and not($d/odm:ItemData[@ItemOID=$poolidoid])
(: case that both USUBJID AND POOLID are populated :)
or ($d/odm:ItemData[@ItemOID=$oid] and $d/odm:ItemData[@ItemOID=$poolidoid])
return <error rule="FDAC042" dataset="{$datasetname}" rulelastupdate="2016-03-25" recordnumber="{data($recnum)}">Both USUBJID and POOLID in dataset {data($datasetname)} are NULL or both POOLID and USUBJID are populated</error>
Invalid STUDYID - Study Identifier (STUDYID) values must match the STUDYID in Demographics (DM) domain
ALL
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the OID of the STUDYID variable in the define.xml :)
let $dmitemgroupdef := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']
let $dmstudyoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='STUDYID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: get the DM dataset :)
let $dmdatasetname := $dmitemgroupdef/def:leaf/@xlink:href
let $dmdatasetpath := concat($base,$dmdatasetname)
let $dmstudyidunique := distinct-values(doc($dmdatasetpath)//odm:ItemData[@ItemOID=$dmstudyoid]/@Value)
(: Surprisingly there is no FDA rule that STUDYID must be unique within DM :)
let $dmstudyid := $dmstudyidunique[1] (: just for the worst case that STUDYID is NOT unique in DM :)
(: now iterate over all dataset definitions in the define.xml :)
for $itemgroupdef in doc(concat($base,$define))//odm:ItemGroupDef
(: Also cover the case that there are several ItemDef[@Name='STUDYID'] e.g. one per dataset or domain :)
let $dataset := $itemgroupdef/def:leaf/@xlink:href
(: let $datasetpath := concat($base,$dataset) :)
let $datasetpath := concat($base,$dataset)
let $datasetname := $itemgroupdef/@Name
(: find the variable for which the name is 'STUDYID' - there should be 0 or 1 :)
let $studyoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='STUDYID']/@OID
where $a = $itemgroupdef/odm:ItemRef/@ItemOID
return $a
)
for $d in doc($datasetpath)//odm:ItemGroupData/odm:ItemData[@ItemOID=$studyoid]
let $recordnumber := $d/../@data:ItemGroupDataSeq
where not($d/@Value = $dmstudyid)
return <error rule="FDAC043" dataset="{data($datasetname)}" variable="STUDYID" rulelastupdate="2016-03-25" recordnumber="{data($recordnumber)}">STUDYID {data($d/@Value)} in dataset {data($dataset)} does not match the STUDYID {data($dmstudyid)} in the DM dataset</error>
Duplicate value for --SEQ variable - The value of Sequence Number (--SEQ) variable must be unique for each record within a domain and within each Unique Subject Identifier (USUBJID) or Pool Identifier (POOLID) variables value when they are present in the domain
ALL
(: Rule FDAC044 The value of Sequence Number (--SEQ) variable must be unique for each record within a domain and within each Unique Subject Identifier (USUBJID) or Pool Identifier (POOLID) variables value when they are present in the domain :)
(: TODO: must be done OVER datasets within the same domain :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
for $itemgroupdef in doc(concat($base,$define))//odm:ItemGroupDef
let $domain := $itemgroupdef/@Domain
let $itemgroupoid := $itemgroupdef/@OID
let $itemgroupname := $itemgroupdef/@Name
let $datasetname := $itemgroupdef/def:leaf/@xlink:href
let $datasets := concat($base,$datasetname) (: result is a set of datasets :)
(: get the OID of --SEQ, USUBJID :)
let $usubjidoid :=
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$itemgroupname]/odm:ItemRef/@ItemOID
return $a
let $seqoid :=
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'SEQ')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$itemgroupname]/odm:ItemRef/@ItemOID
return $a
(: get the Name of --SEQ :)
let $seqname := doc(concat($base,$define))//odm:ItemDef[@OID=$seqoid]/@Name
(: now iterate over all datasets, but not the Trial design datasets and not for SUPPxx datasets :)
for $datasetdoc in doc($datasets)
let $orderedrecords := (
for $record in $datasetdoc//odm:ItemGroupData[odm:ItemData[@ItemOID=$usubjidoid] and odm:ItemData[@ItemOID=$seqoid]]
group by
$b := $record/odm:ItemData[@ItemOID=$usubjidoid]/@Value,
$c := $record/odm:ItemData[@ItemOID=$seqoid]/@Value
return element group {
$record
}
)
for $group in $orderedrecords
(: each group has the same values for USUBJID and --SEQ :)
let $usubjid := $group/odm:ItemGroupData[1]/odm:ItemData[@ItemOID=$usubjidoid]/@Value
let $seq := $group/odm:ItemGroupData[1]/odm:ItemData[@ItemOID=$seqoid]/@Value
let $recnums := $group/odm:ItemGroupData/@data:ItemGroupDataSeq
(: for reporting the record number, we take the one of the last record in the group :)
let $recnum := $group/odm:ItemGroupData[last()]/@data:ItemGroupDataSeq
(: each group should only have one record. If not, there are duplicate values of USUBJID and --SEQ :)
where count($group/odm:ItemGroupData) > 1
return <error rule="FDAC044" dataset="{data($itemgroupname)}" variable="{data($seqname)}" rulelastupdate="2016-03-24" recordnumber="{data($recnum)}">The record with USUBJID = {data($usubjid)} and {data($seqname)} is not unique in the dataset {data($itemgroupname)}. The following records have the same combination of USUBJID and {data($seqname)}: records number {data($recnums)}</error>
Duplicate value for --SEQ variable, single domain or dataset - The value of Sequence Number (--SEQ) variable must be unique for each record within a domain and within each Unique Subject Identifier (USUBJID) or Pool Identifier (POOLID) variables value when they are present in the domain
ALL
(: Rule FDAC044-SD The value of Sequence Number (--SEQ) variable must be unique for each record within a domain and within each Unique Subject Identifier (USUBJID) or Pool Identifier (POOLID) variables value when they are present in the domain :)
(: TODO: must be done OVER datasets within the same domain :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
declare variable $domain external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
for $itemgroupdef in doc(concat($base,$define))//odm:ItemGroupDef[@Name=$domain or def:Class=$domain]
let $domain := $itemgroupdef/@Domain
let $itemgroupoid := $itemgroupdef/@OID
let $itemgroupname := $itemgroupdef/@Name
let $datasetname := $itemgroupdef/def:leaf/@xlink:href
let $datasets := concat($base,$datasetname) (: result is a set of datasets :)
(: get the OID of --SEQ, USUBJID :)
let $usubjidoid :=
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$itemgroupname]/odm:ItemRef/@ItemOID
return $a
let $seqoid :=
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'SEQ')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$itemgroupname]/odm:ItemRef/@ItemOID
return $a
(: get the Name of --SEQ :)
let $seqname := doc(concat($base,$define))//odm:ItemDef[@OID=$seqoid]/@Name
(: now iterate over all datasets, but not the Trial design datasets and not for SUPPxx datasets :)
for $datasetdoc in doc($datasets)
let $orderedrecords := (
for $record in $datasetdoc//odm:ItemGroupData[odm:ItemData[@ItemOID=$usubjidoid] and odm:ItemData[@ItemOID=$seqoid]]
group by
$b := $record/odm:ItemData[@ItemOID=$usubjidoid]/@Value,
$c := $record/odm:ItemData[@ItemOID=$seqoid]/@Value
return element group {
$record
}
)
for $group in $orderedrecords
(: each group has the same values for USUBJID and --SEQ :)
let $usubjid := $group/odm:ItemGroupData[1]/odm:ItemData[@ItemOID=$usubjidoid]/@Value
let $seq := $group/odm:ItemGroupData[1]/odm:ItemData[@ItemOID=$seqoid]/@Value
let $recnums := $group/odm:ItemGroupData/@data:ItemGroupDataSeq
(: for reporting the record number, we take the one of the last record in the group :)
let $recnum := $group/odm:ItemGroupData[last()]/@data:ItemGroupDataSeq
(: each group should only have one record. If not, there are duplicate values of USUBJID and --SEQ :)
where count($group/odm:ItemGroupData) > 1
return <error rule="FDAC044" dataset="{data($itemgroupname)}" variable="{data($seqname)}" rulelastupdate="2016-03-24" recordnumber="{data($recnum)}">The record with USUBJID = {data($usubjid)} and {data($seqname)} is not unique in the dataset {data($itemgroupname)}. The following records have the same combination of USUBJID and {data($seqname)}: records number {data($recnums)}</error>
Non-unique value for TSSEQ variable within TSPARMCD - The value of Sequence Number (--SEQ) variable must be unique for each record within a domain and within each Unique Subject Identifier (USUBJID) or Pool Identifier (POOLID) variables value when they are present in the domain.
TS
(: Rule FDAC045 - Non-unique value for TSSEQ variable within TSPARMCD -
Sequence Number (TSSEQ) must have a unique value for a given value of Trial Summary Parameter Short Name (TSPARMCD) within the domain,
i.e. combination of TSSEQ and TSPARMCD must be unique :)
(:can be made much more faster using "GROUP BY" :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the OID of the TSSEQ and TSPARMCD variables in the define.xml :)
let $tsseq := doc(concat($base,$define))//odm:ItemDef[@Name='TSSEQ']/@OID
let $tsparmcd := doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
(: get the TS dataset :)
let $tsdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/def:leaf/@xlink:href
let $tsdataset := concat($base,$tsdatasetname)
(: now iterate over the TS records :)
for $d in doc($tsdataset)//odm:ItemGroupData
let $seqvalue := $d/odm:ItemData[@ItemOID=$tsseq]/@Value
let $parmcdvalue := $d/odm:ItemData[@ItemOID=$tsparmcd]/@Value
let $recnum := $d/@data:ItemGroupDataSeq
(: and count the one with the (same) combination of TSSEQ and TSPARMCD in the dataset :)
(: additional possibility to speed up: add [@data:ItemGroupDataSeq > $recnum] :)
let $count := count(doc($tsdataset)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsseq and @Value=$seqvalue] and odm:ItemData[@ItemOID=$tsparmcd and @Value=$parmcdvalue]])
where $count > 1
return <error rule="FDAC045" dataset="TS" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">Non-unique value for TSSEQ variable within TSPARMCD - combination of TSSEQ={data($seqvalue)} and TSPARMCD={data($parmcdvalue)} occurs {data($count)} times</error>
Duplicate VISITNUM - The value of Visit Number (VISITNUM) variable should be unique for each record within a subject - Dataset SV
SV
(: Rule FDAC046 - Duplicate VISITNUM:
The value of Visit Number (VISITNUM) variable should be unique for each record within a subject - Dataset SV - Warning :)
(: OPTIMIZED - made much more faster using "GROUP BY" :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdiscpilot01/' :)
(: let $define := 'define_2_0.xml' :)
let $definedoc := doc(concat($base,$define))
let $svitemgroupdef := $definedoc//odm:ItemGroupDef[@Name='SV']
(: get the OID of VISITNUM in define.xml for dataset SV :)
let $visitnumoid := (
for $a in $definedoc//odm:ItemDef[@Name='VISITNUM']/@OID
where $a = $svitemgroupdef/odm:ItemRef/@ItemOID
return $a
)
(: get the OID of USUBJID in the SV dataset :)
let $usubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = $svitemgroupdef/odm:ItemRef/@ItemOID
return $a
)
(: get the location of the SV dataset :)
let $svdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='SV']/def:leaf/@xlink:href
let $svdatasetdoc := doc(concat($base,$svdatasetname))
(: group the records in the SV dataset by USUBJID and VISITNUM - there should be only one record per group :)
let $orderedrecords := (
for $record in $svdatasetdoc//odm:ItemGroupData
group by
$b := $record/odm:ItemData[@ItemOID=$usubjidoid]/@Value,
$c := $record/odm:ItemData[@ItemOID=$visitnumoid]/@Value
return element group {
$record
}
)
(: iterate over all the groups :)
for $group in $orderedrecords
let $visitnumvalue := $group/odm:ItemGroupData[1]/odm:ItemData[@ItemOID=$visitnumoid]/@Value
let $usubjidvalue := $group/odm:ItemGroupData[1]/odm:ItemData[@ItemOID=$usubjidoid]/@Value
let $recnum := $group/odm:ItemGroupData[1]/@data:ItemGroupDataSeq
let $count := count($group/odm:ItemGroupData)
where $count > 1
return <warning rule="FDAC046" dataset="SV" rulelastupdate="2017-03-19" recordnumber="{data($recnum)}">Non-unique combination of USUBID and VISITNUM in dataset SV - combination of USUBJID={data($usubjidvalue)} and VISITNUM={data($visitnumvalue)} occurrs {data($count)} times</warning>
Duplicate SUBJID - The value of Subject Identifier for the Study (SUBJID) variable must be unique for each subject within the study - DM
DM
(: Rule FDAC048 - Duplicate SUBJID - The value of Subject Identifier for the Study (SUBJID) variable must be unique for each subject within the study - DM :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdiscpilot01/' :)
(: let $define := 'define_2_0.xml' :)
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the OID of SUBJID in define.xml for dataset DM :)
let $subjidoid := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef[4]/@ItemOID (: It must always be the fourth one :)
(: and the file where to find the DM records :)
let $datasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/def:leaf/@xlink:href
let $dataset := concat($base,$datasetname)
(: iterate over all records in the DM dataset :)
for $record in doc($dataset)//odm:ItemGroupData
(: get the value for the SUBJID data point :)
let $subjidvalue := $record/odm:ItemData[@ItemOID=$subjidoid]/@Value
let $recnum := $record/@data:ItemGroupDataSeq
(: and get all following records with the same value of SUBJID :)
let $count := count(doc($dataset)//odm:ItemGroupData[@data:ItemGroupDataSeq > $recnum][odm:ItemData[@ItemOID=$subjidoid][@Value=$subjidvalue]])
where $count > 0
return <error rule="FDAC048" dataset="DM" variable="SUBJID" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">Duplicate value of SUBJID={data($subjidvalue)} - {data($count)} in dataset {data($datasetname)}</error>
EX record is present, when subject is not assigned to an arm - Subjects that have withdrawn from a trial before assignment to an Arm (ARMCD='NOTASSGN') should not have any Exposure records
EX
DM
(: Rule FDAC49: EX record is present, when subject is not assigned to an arm: Subjects that have withdrawn from a trial before assignment to an Arm (ARMCD='NOTASSGN') should not have any Exposure records :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the DM dataset :)
let $dmdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/def:leaf/@xlink:href
let $dmdataset := concat($base,$dmdatasetname)
(: Get the EX dataset :)
let $exdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='EX']/def:leaf/@xlink:href
let $exdataset := concat($base,$exdatasetname)
(: get the OID for the ARMCD variable in the DM dataset :)
(: TODO - change this, supposing there is only one is not always correct :)
(: let $armcdoid := doc(concat($base,$define))//odm:ItemDef[@Name='ARMCD']/@OID :) (: supposing there is only one :)
let $armcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: and the OID of USUBJID :)
let $usubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: we also need the OID of the USUBJID in the EX dataset :)
let $exusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='EX']/odm:ItemRef/@ItemOID
return $a
)
(: in the DM dataset, select the subjects which have ARMCD='NOTASSGN' :)
for $rec in doc($dmdataset)//odm:ItemGroupData[odm:ItemData[@ItemOID=$armcdoid and @Value='NOTASSGN']]
let $usubjidvalue := $rec/odm:ItemData[@ItemOID=$usubjidoid]/@Value
(: and the record number for which ARMCD='NOTASSGN' :)
let $recnum := $rec/@data:ItemGroupDataSeq
(: and now check whether there is a record in the EX dataset :)
let $count := count(doc($exdataset)//odm:ItemGroupData[odm:ItemData[@ItemOID=$exusubjidoid]])
where $count > 0 (: at least one EX record was found :)
return <warning rule="FDAC049" dataset="EX" rulelastupdate="2015-02-13" recordnumber="{data($recnum)}">{data($count)} EX records were found in EX dataset {data($exdatasetname)} for USUBJID={data($usubjidvalue)} although subject has not been assigned to an arm (ARMCD='NOTASSGN') in DM dataset {data($dmdatasetname)}</warning>
Exposure end date is after the latest Disposition date - End Date/Time of Treatment (EXENDTC) should be less than or equal to the Start Date/Time of the latest Disposition Event (DSSTDTC)
EX
DS
(: Rule FDAC50: Exposure end date is after the latest Disposition date:
End Date/Time of Treatment (EXENDTC) should be less than or equal to the Start Date/Time of the latest Disposition Event (DSSTDTC) :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the DS dataset :)
let $dsdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DS']/def:leaf/@xlink:href
let $dsdataset := concat($base,$dsdatasetname)
(: and the OID of the USUBJID :)
let $dsusubjoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DS']/odm:ItemRef/@ItemOID
return $a
)
let $dsstdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='DSSTDTC']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DS']/odm:ItemRef/@ItemOID
return $a
)
(: Get the EX dataset :)
let $exdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='EX']/def:leaf/@xlink:href
let $exdataset := concat($base,$exdatasetname)
let $exusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='EX']/odm:ItemRef/@ItemOID
return $a
)
let $exendtcoid := doc(concat($base,$define))//odm:ItemDef[@Name='EXENDTC']/@OID
(: iterate over all the records in the EX dataset :)
for $exrecord in doc($exdataset)//odm:ItemGroupData
let $recnum := $exrecord/@data:ItemGroupDataSeq
(: get als well the USUBJID as the EXENDTC :)
let $exusubjidvalue := $exrecord/odm:ItemData[@ItemOID=$exusubjidoid]/@Value
let $exendtcvalue := $exrecord/odm:ItemData[@ItemOID=$exendtcoid]/@Value
(: now get the latest (maximal) value DSSTDTC in the DS dataset for this subject :)
(: let $lastdssdtcvalue := max(doc($dsdataset)//odm:ItemGroupData[odm:ItemData[@ItemOID=$dsusubjoid and @Value=$exusubjidvalue]]/odm:ItemData[@ItemOID=$dsstdtcoid]/@Value) :)
let $dssdtcvalues := doc($dsdataset)//odm:ItemGroupData[odm:ItemData[@ItemOID=$dsusubjoid and @Value=$exusubjidvalue]]/odm:ItemData[@ItemOID=$dsstdtcoid]/@Value
(: get the latest DSSTDTC date :)
let $latestdate := max(for $date in $dssdtcvalues return xs:date($date))
(: and report an error when DSSTDTC before EXENDTC :)
(: remark that we need to test first whether there is an actual EXENDTC value :)
where $exendtcvalue and xs:date($latestdate) < xs:date($exendtcvalue)
return <warning rule="FDAC050" dataset="EX" variable="EXENDTC" rulelastupdate="2015-02-13" recordnumber="{data($recnum)}">Exposure end date EXENDTC={data($exendtcvalue)} for USUBJID={data($exusubjidvalue)} is after last disposition date {data($latestdate)}</warning>
No Disposition record found for subject - All Demographics (DM) subjects (USUBJID) should have at least one record in the Disposition (DS) domain with only possible exceptions to Screen Failures (ARMCD='SCRNFAIL') and Not Assigned Treatment (ARMCD='NOTASSGN') subjects
DS
DM
(: Rule FDAC052 - No Disposition record found for subject:
All Demographics (DM) subjects (USUBJID) should have at least one record in the Disposition (DS) domain with only possible exceptions to Screen Failures (ARMCD='SCRNFAIL') and Not Assigned Treatment (ARMCD='NOTASSGN') subjects
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the DM dataset :)
let $dmdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/def:leaf/@xlink:href
let $dmdataset := concat($base,$dmdatasetname)
(: Get the DS dataset :)
let $dsdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DS']/def:leaf/@xlink:href
let $dsdataset := concat($base,$dsdatasetname)
(: and the OID of the USUBJID and of ARMCD in the DM dataset :)
let $usubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
let $armcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: we also need the OID of USUBJID in the DS dataset :)
let $dsusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DS']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over the DM dataset and :)
for $record in doc($dmdataset)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
let $usubjidvalue := $record/odm:ItemData[@ItemOID=$usubjidoid]/@Value
(: $hasarmassigned sets whether the subject has been assigned to an arm :)
let $hasarmassigned := not($record/odm:ItemData[@ItemOID=$armcdoid]/@Value = 'SCRNFAIL' or $record/odm:ItemData[@ItemOID=$armcdoid]/@Value = 'NOTASSGN')
(: now count the number of records for this subject in the DS dataset :)
let $count := count(doc($dsdataset)//odm:ItemGroupData[odm:ItemData[@ItemOID=$dsusubjidoid and @Value=$usubjidvalue]])
let $arm := $record/odm:ItemData[@ItemOID=$armcdoid]/@Value
where $hasarmassigned and $count = 0
(: and now check whether there are any records in the DS dataset :)
return <warning rule="FDAC052" rulelastupdate="2015-02-13" dataset="DM" variable="USUBJID" recordnumber="{data($recnum)}">No disposition records were found in dataset {data($dsdatasetname)} for subject {data($usubjidvalue)} with assigned arm {data($arm)}</warning>
No Exposure record found for subject - All Demographics (DM) subjects (USUBJID) participating in a study that includes investigational product should have at least one record in the Exposure (EX) domain, except for subjects who failed screening (ARMCD = 'SCRNFAIL') or were not fully assigned to an Arm (ARMCD = 'NOTASSGN')
EX
DM
(: Rule FDAC053 - No Exposure record found for subject:
All Demographics (DM) subjects (USUBJID) participating in a study that includes investigational product should have at least one record in the Exposure (EX) domain, except for subjects who failed screening (ARMCD = 'SCRNFAIL') or were not fully assigned to an Arm (ARMCD = 'NOTASSGN')
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the DM dataset :)
let $dmdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/def:leaf/@xlink:href
let $dmdataset := concat($base,$dmdatasetname)
(: Get the EX dataset :)
let $exdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='EX']/def:leaf/@xlink:href
let $exdataset := concat($base,$exdatasetname)
(: and the OID of the USUBJID and of ARMCD in the DM dataset :)
let $usubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: Attention, there can be more than 1 of them - although bad practice :)
(: let $armcdoid := doc(concat($base,$define))//odm:ItemDef[@Name='ARMCD']/@OID :)
(: better and surer :)
let $armcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: we also need the OID of USUBJID in the EX dataset :)
let $exusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='EX']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over the DM dataset and :)
for $record in doc($dmdataset)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
let $usubjidvalue := $record/odm:ItemData[@ItemOID=$usubjidoid]/@Value
(: $hasarmassigned sets whether the subject has been assigned tom an arm :)
let $hasarmassigned := not($record/odm:ItemData[@ItemOID=$armcdoid]/@Value = 'SCRNFAIL' or $record/odm:ItemData[@ItemOID=$armcdoid]/@Value = 'NOTASSGN')
(: now count the number of records for this subject in the DS dataset :)
let $count := count(doc($exdataset)//odm:ItemGroupData[odm:ItemData[@ItemOID=$exusubjidoid and @Value=$usubjidvalue]])
let $arm := $record/odm:ItemData[@ItemOID=$armcdoid]/@Value
where $hasarmassigned and $count = 0
(: and now check whether there are any records in the DS dataset :)
return <warning rule="FDAC053" rulelastupdate="2015-02-13" dataset="DM" variable="USUBJID" recordnumber="{data($recnum)}">No exposure records were found in dataset {data($exdatasetname)} for subject {data($usubjidvalue)} with assigned arm {data($arm)}</warning>
Observation date is after the latest Disposition date - Date/Time of Collection (--DTC) should be less than or equal to the Start Date/Time of the latest Disposition Event (DSSTDTC)
EG
LB
VS
DS
(: Rule FDAC054 - Observation date is after the latest Disposition date:
Date/Time of Collection (--DTC) should be less than or equal to the Start Date/Time of the latest Disposition Event (DSSTDTC) :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the DM dataset :)
let $dmdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/def:leaf/@xlink:href
let $dmdataset := concat($base,$dmdatasetname)
(: Get the OID of USUBJID in the DM dataset :)
let $dmusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: Get the DS dataset :)
let $dsdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DS']/def:leaf/@xlink:href
let $dsdataset := concat($base,$dsdatasetname)
(: get the USUBJID and the OID of DSSTDTC in the DS dataset :)
let $dsusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DS']/odm:ItemRef/@ItemOID
return $a
)
let $dsstdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='DSSTDTC']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DS']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all subjects in the DM dataset :)
(: TODO: isn't it better to first iterate within the EG, LB and VS dataset itself :)
for $dmrecord in doc($dmdataset)//odm:ItemGroupData
let $dmusubjid := $dmrecord/odm:ItemData[@ItemOID=$dmusubjidoid]/@Value
(: now find the latest DSSTDTC in the DS dataset :)
let $dssdtcvalues := doc($dsdataset)//odm:ItemGroupData[odm:ItemData[@ItemOID=$dsusubjidoid and @Value=$dmusubjid]]/odm:ItemData[@ItemOID=$dsstdtcoid]/@Value
(: get the latest DSSTDTC date :)
let $latestdate := max(for $date in $dssdtcvalues return xs:date($date))
for $obsdataset in doc(concat($base,$define))//odm:ItemGroupDef[starts-with(@Name,'EG') or starts-with(@Name,'LB') or starts-with(@Name,'VS')]
let $itemgroupdefname := $obsdataset/@Name
(: get the OID of the USUBID :)
(: TODO: do NOT trust this is the third ItemRef :)
let $obsusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
let $datasetname := $obsdataset/def:leaf/@xlink:href
let $dataset := concat($base,$datasetname)
(: get the DTC variables :)
let $dtcoids := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'DTC')]/@OID
where $a = $obsdataset/odm:ItemRef/@ItemOID
return $a
)
(: and iterate over all the records for the current subject :)
for $record in doc($dataset)//odm:ItemGroupData[odm:ItemData[@ItemOID=$obsusubjidoid and @Value=$dmusubjid]]
let $recnum := $record/@data:ItemGroupDataSeq (: get the record number :)
(: and take any of the DTC data points :)
for $dtcoid in $dtcoids
(: get the name of the variable from the define.xml and the value from the record :)
let $dtcname := doc(concat($base,$define))//odm:ItemDef[@OID=$dtcoid]/@Name
let $dtcvalue := $record/odm:ItemData[@ItemOID=$dtcoid]/@Value
let $dtcvaluedate := if (string-length($dtcvalue)>10) then substring($dtcvalue,1,10)
else $dtcvalue
(: and check whether later then the lastest DSSTDTC :)
where $dtcvaluedate castable as xs:date and $latestdate castable as xs:date and xs:date($dtcvaluedate) > xs:date($latestdate)
return <warning rule="FDAC054" rulelastupdate="2015-02-13" dataset="{data($itemgroupdefname)}" variable="{data($dtcname)}" recordnumber="{data($recnum)}">Date/time of collection {data($dtcvalue)} for variable {data($dtcname)} for subject {data($dmusubjid)} is after last start Date/Time of the latest Disposition Event (DSSTDTC) {data($latestdate)}- in dataset {data($dataset)}</warning>
Observation date is after the latest Disposition date, single domain - Date/Time of Collection (--DTC) should be less than or equal to the Start Date/Time of the latest Disposition Event (DSSTDTC)
EG
LB
VS
DS
(: Rule FDAC054 - Observation date is after the latest Disposition date:
Date/Time of Collection (--DTC) should be less than or equal to the Start Date/Time of the latest Disposition Event (DSSTDTC) :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
declare variable $domain external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the DM dataset :)
let $dmdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/def:leaf/@xlink:href
let $dmdataset := concat($base,$dmdatasetname)
(: Get the OID of USUBJID in the DM dataset :)
let $dmusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: Get the DS dataset :)
let $dsdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DS']/def:leaf/@xlink:href
let $dsdataset := concat($base,$dsdatasetname)
(: get the USUBJID and the OID of DSSTDTC in the DS dataset :)
let $dsusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DS']/odm:ItemRef/@ItemOID
return $a
)
let $dsstdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='DSSTDTC']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DS']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all subjects in the DM dataset :)
(: TODO: isn't it better to first iterate within the EG, LB and VS dataset itself :)
for $dmrecord in doc($dmdataset)//odm:ItemGroupData[@Name=$domain or @Domain=$domain]
let $dmusubjid := $dmrecord/odm:ItemData[@ItemOID=$dmusubjidoid]/@Value
(: now find the latest DSSTDTC in the DS dataset :)
let $dssdtcvalues := doc($dsdataset)//odm:ItemGroupData[odm:ItemData[@ItemOID=$dsusubjidoid and @Value=$dmusubjid]]/odm:ItemData[@ItemOID=$dsstdtcoid]/@Value
(: get the latest DSSTDTC date :)
let $latestdate := max(for $date in $dssdtcvalues return xs:date($date))
(: for $obsdataset in doc(concat($base,$define))//odm:ItemGroupDef[starts-with(@Name,'EG') or starts-with(@Name,'LB') or starts-with(@Name,'VS')] :)
for $obsdataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name=$domain or @Domain=$domain]
let $itemgroupdefname := $obsdataset/@Name
(: get the OID of the USUBID :)
let $obsusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
let $datasetname := $obsdataset/def:leaf/@xlink:href
let $dataset := concat($base,$datasetname)
(: get the DTC variables :)
let $dtcoids := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'DTC')]/@OID
where $a = $obsdataset/odm:ItemRef/@ItemOID
return $a
)
(: and iterate over all the records for the current subject :)
for $record in doc($dataset)//odm:ItemGroupData[odm:ItemData[@ItemOID=$obsusubjidoid and @Value=$dmusubjid]]
let $recnum := $record/@data:ItemGroupDataSeq (: get the record number :)
(: and take any of the DTC data points :)
for $dtcoid in $dtcoids
(: get the name of the variable from the define.xml and the value from the record :)
let $dtcname := doc(concat($base,$define))//odm:ItemDef[@OID=$dtcoid]/@Name
let $dtcvalue := $record/odm:ItemData[@ItemOID=$dtcoid]/@Value
let $dtcvaluedate := if (string-length($dtcvalue)>10) then substring($dtcvalue,1,10)
else $dtcvalue
(: and check whether later then the lastest DSSTDTC :)
where $dtcvaluedate castable as xs:date and $latestdate castable as xs:date and xs:date($dtcvaluedate) > xs:date($latestdate)
return <warning rule="FDAC054" rulelastupdate="2015-02-13" dataset="{data($itemgroupdefname)}" variable="{data($dtcname)}" recordnumber="{data($recnum)}">Date/time of collection {data($dtcvalue)} for variable {data($dtcname)} for subject {data($dmusubjid)} is after last start Date/Time of the latest Disposition Event (DSSTDTC) {data($latestdate)}- in dataset {data($dataset)}</warning>
Permissible variable with missing value for all records - Permissible variable whould not be present in domain, when the variable has missing value for all records in the dataset
ALL
(: Rule FDAC055 - Permissible variable with missing value for all records:
Permissible variable whould not be present in domain, when the variable has missing value for all records in the dataset :)
(: How do we know that a variable is permissible? Mandatory="No" is essentially not sufficient.
Use the web service to find out - http://www.xml4pharmaserver.com:8080/CDISCCTService/rest/CDISCCoreFromSDTMVariable/{sdsVersion}/{domain}/{varName} :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all datasets and variables in the define.xml :)
for $itemgroup in doc(concat($base,$define))//odm:ItemGroupDef
let $itemgroupdefname := $itemgroup/@Name
(: get the dataset name and location :)
let $datasetname := $itemgroup//def:leaf/@xlink:href
let $dataset := concat($base,$datasetname)
(: iterate over all ItemRef elements that hava Mandatory="No" :)
for $itemref in $itemgroup/odm:ItemRef[@Mandatory='No']
(: get the OID and the Name of the variable :)
let $variableoid := $itemref/@ItemOID
let $variablename := doc(concat($base,$define))//odm:ItemDef[@OID=$variableoid]/@Name
(: invoke the webservice to find out whether the variable is permissible :)
let $webservice := concat('http://www.xml4pharmaserver.com:8080/CDISCCTService/rest/CDISCCoreFromSDTMVariable/1.4/',$itemgroupdefname,'/',$variablename)
let $webserviceresult := data(doc($webservice)/XML4PharmaServerWebServiceResponse/Response) (: returns 'Req', 'Exp', or 'Perm' :)
(: now take the dataset and count the number of data points for this variable :)
let $count := count(doc($dataset)//odm:ItemGroupData/odm:ItemData[@ItemOID=$variableoid])
(: no data points found :)
where $webserviceresult='Perm' and $count = 0
(: and give out an error message :)
return <warning rule="FDAC055" rulelastupdate="2016-03-28" dataset="{data($variablename)}" variable="{data($itemgroupdefname)}">Permissible variable {data($variablename)} has no values for all records in dataset {data($datasetname)}</warning>
Permissible variable with missing value for all records, single dataset or domain - Permissible variable whould not be present in domain, when the variable has missing value for all records in the dataset
ALL
(: Rule FDAC055 - Permissible variable with missing value for all records:
Permissible variable whould not be present in domain, when the variable has missing value for all records in the dataset :)
(: How do we know that a variable is permissible? Mandatory="No" is essentially not sufficient.
Use the web service to find out - http://www.xml4pharmaserver.com:8080/CDISCCTService/rest/CDISCCoreFromSDTMVariable/{sdsVersion}/{domain}/{varName} :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
declare variable $domain external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all datasets and variables in the define.xml :)
for $itemgroup in doc(concat($base,$define))//odm:ItemGroupDef[@Name=$domain or @Domain=$domain]
let $itemgroupdefname := $itemgroup/@Name
(: get the dataset name and location :)
let $datasetname := $itemgroup//def:leaf/@xlink:href
let $dataset := concat($base,$datasetname)
(: iterate over all ItemRef elements that hava Mandatory="No" :)
for $itemref in $itemgroup/odm:ItemRef[@Mandatory='No']
(: get the OID and the Name of the variable :)
let $variableoid := $itemref/@ItemOID
let $variablename := doc(concat($base,$define))//odm:ItemDef[@OID=$variableoid]/@Name
(: invoke the webservice to find out whether the variable is permissible :)
let $webservice := concat('http://www.xml4pharmaserver.com:8080/CDISCCTService/rest/CDISCCoreFromSDTMVariable/1.4/',$itemgroupdefname,'/',$variablename)
let $webserviceresult := data(doc($webservice)/XML4PharmaServerWebServiceResponse/Response) (: returns 'Req', 'Exp', or 'Perm' :)
(: now take the dataset and count the number of data points for this variable :)
let $count := count(doc($dataset)//odm:ItemGroupData/odm:ItemData[@ItemOID=$variableoid])
(: no data points found :)
where $webserviceresult='Perm' and $count = 0
(: and give out an error message :)
return <warning rule="FDAC055" rulelastupdate="2016-03-28" dataset="{data($variablename)}" variable="{data($itemgroupdefname)}">Permissible variable {data($variablename)} has no values for all records in dataset {data($datasetname)}</warning>
Inconsistent value for DOMAIN - Domain Abbreviation (DOMAIN) variable should be consistent with the name of the dataset
ALL
(: Rule FDAC056 - Inconsistent value for DOMAIN:
Domain Abbreviation (DOMAIN) variable should be consistent with the name of the dataset :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdiscpilot01/' :)
(: let $define := 'define_2_0.xml' :)
(: iterate over all datasets in the define.xml :)
for $itemgroup in doc(concat($base,$define))//odm:ItemGroupDef
let $itemgroupdefname := $itemgroup/@Name
(: get the dataset name and location :)
let $datasetname := $itemgroup//def:leaf/@xlink:href
let $dataset := concat($base,$datasetname)
(: get the OID of the "DOMAIN" variable :)
let $domainoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='DOMAIN']/@OID
(: where $a = doc(concat($base,$define))//odm:ItemGroupDef/odm:ItemRef/@ItemOID :)
where $a = $itemgroup/odm:ItemRef/@ItemOID
return $a
)
(: now get the unique values in the dataset - the number of unique values must be 1 :)
let $distinctdomainvalues := distinct-values(doc($dataset)//odm:ItemData[@ItemOID=$domainoid]/@Value)
where count($distinctdomainvalues) > 1
return <error rule="FDAC056" dataset="{data($itemgroupdefname)}" variable="DOMAIN" rulelastupdate="2015-08-15">Inconsistent Domain Abbreviation (DOMAIN) variable value in dataset {data($datasetname)}. Following values were found: {data($distinctdomainvalues)}</error>
Invalid value for --TEST variable - The value of Name of Measurement, Test or Examination (--TEST) should be no more than 40 characters in length
FINDINGS
(: Rule FDAC057 - Invalid value for --TEST variable:
The value of Name of Measurement, Test or Examination (--TEST) should be no more than 40 characters in length :)
(: This rule is really outdated! Even CDISC has published test names with > 40 characters. The rule is a relict of the ancient XPT format.
ALSO:IETEST is an exception: may be up to 200 characters :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare namespace functx = "http://www.functx.com";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all datasets and variables in the define.xml :)
for $itemgroup in doc(concat($base,$define))//odm:ItemGroupDef
let $itemgroupdefname := $itemgroup/@Name
(: Get the @Domain value when present, otherwise the @Name value -
this is for allowing 'splitted' domains, e.g. @Name=QSCG @Domain=QS :)
let $datasetname := $itemgroup/@Name
let $domain := (
if($itemgroup/@Domain != '') then $itemgroup/@Domain
else $itemgroup/@Name
)
(: The --TEST variable is the concatenation of the domain code and 'TEST' :)
let $testvar := concat($domain,'TEST')
(: Get the OID for the --TEST variable :)
let $testoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name=$testvar]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$datasetname]/odm:ItemRef/@ItemOID
return $a
)
(: we of course only look into datasets where there really is a --TEST :)
let $datasetname := $itemgroup//def:leaf/@xlink:href
let $dataset := concat($base,$datasetname)
(: iterate over all the records where there is a --TEST variable :)
for $record in doc($dataset)//odm:ItemGroupData
(: get the record number :)
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the value of the --TEST variable :)
let $testvalue := $record/odm:ItemData[@ItemOID=$testoid]/@Value
(: when it has more than 40 characters, give an error.
Attention: IETEST is an exception (may be up to 200 characters) :)
where string-length($testvalue) > 40 and not($testvar='IETEST')
return <error rule="FDAC057" recordnumber="{data($recnum)}" variable="{data($testvar)}" dataset="{data($itemgroupdefname)}" rulelastupdate="2015-08-26">The value for {data($testvar)} has more than 40 characters: '{data($testvalue)}' was found</error>
Invalid value for --TEST variable, single dataset or domain - The value of Name of Measurement, Test or Examination (--TEST) should be no more than 40 characters in length
FINDINGS
(: Rule FDAC057 - Invalid value for --TEST variable:
The value of Name of Measurement, Test or Examination (--TEST) should be no more than 40 characters in length :)
(: This rule is really outdated! Even CDISC has published test names with > 40 characters. The rule is a relict of the ancient XPT format.
ALSO:IETEST is an exception: may be up to 200 characters :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare namespace functx = "http://www.functx.com";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
declare variable $domain external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all datasets and variables in the define.xml :)
for $itemgroup in doc(concat($base,$define))//odm:ItemGroupDef[@Name=$domain or @Domain=$domain]
let $itemgroupdefname := $itemgroup/@Name
(: Get the @Domain value when present, otherwise the @Name value -
this is for allowing 'splitted' domains, e.g. @Name=QSCG @Domain=QS :)
let $datasetname := $itemgroup/@Name
let $domain := (
if($itemgroup/@Domain != '') then $itemgroup/@Domain
else $itemgroup/@Name
)
(: The --TEST variable is the concatenation of the domain code and 'TEST' :)
let $testvar := concat($domain,'TEST')
(: Get the OID for the --TEST variable :)
let $testoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name=$testvar]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$datasetname]/odm:ItemRef/@ItemOID
return $a
)
(: we of course only look into datasets where there really is a --TEST :)
let $datasetname := $itemgroup//def:leaf/@xlink:href
let $dataset := concat($base,$datasetname)
(: iterate over all the records where there is a --TEST variable :)
for $record in doc($dataset)//odm:ItemGroupData
(: get the record number :)
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the value of the --TEST variable :)
let $testvalue := $record/odm:ItemData[@ItemOID=$testoid]/@Value
(: when it has more than 40 characters, give an error.
Attention: IETEST is an exception (may be up to 200 characters) :)
where string-length($testvalue) > 40 and not($testvar='IETEST')
return <error rule="FDAC057" recordnumber="{data($recnum)}" variable="{data($testvar)}" dataset="{data($itemgroupdefname)}" rulelastupdate="2015-08-26">The value for {data($testvar)} has more than 40 characters: '{data($testvalue)}' was found</error>
Invalid value for --TESTCD variable - The value of a Short Name of Measurement, Test or Examination (--TESTCD) variable should be limited to 8 characters, cannot start with a number, and cannot contain characters other than letters in upper case, numbers, or underscores
ALL
(: Rule FDAC058 - Invalid value for --TESTCD variable:
The value of a Short Name of Measurement, Test or Examination (--TESTCD) variable should be limited to 8 characters, cannot start with a number, and cannot contain characters other than letters in upper case, numbers, or underscores :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace functx = "http://www.functx.com";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
declare function functx:is-value-in-sequence
( $value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
(: let $base := '/db/fda_submissions/cdiscpilot01/' :)
(: let $define := 'define_2_0.xml' :)
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
let $numbers := ("0","1","2","3","4","5","6","7","8","9")
(: iterate over all datasets in the define.xml :)
for $itemgroup in doc(concat($base,$define))//odm:ItemGroupDef
let $itemgroupdefname := $itemgroup/@Name
(: get the dataset name and location :)
let $datasetname := $itemgroup/def:leaf/@xlink:href
let $dataset := concat($base,$datasetname)
(: get the OID of the "--TEST" variable :)
let $testoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TESTCD')]/@OID
where $a = $itemgroup/odm:ItemRef/@ItemOID
return $a
)
let $testname := doc(concat($base,$define))//odm:ItemDef[@OID=$testoid]/@Name
for $record in doc($dataset)//odm:ItemGroupData[odm:ItemData[@ItemOID=$testoid]]
let $recnum := $record/@data:ItemGroupDataSeq
let $value := $record/odm:ItemData[@ItemOID=$testoid]/@Value
let $firstchar := substring($value,1,1)
(: TODO: pattern matching does not seem to work well, though the pattern seems to be correct! :)
where string-length($value) > 8 or functx:is-value-in-sequence($firstchar,$numbers) or not(matches($value,'[A-Z_][A-Z0-9_]*'))
return <error rule="FDAC058" recordnumber="{data($recnum)}" dataset="{data($itemgroupdefname)}" variable="{$testname}" rulelastupdate="2015-08-15">Invalid value for Short Name of Measurement, Test or Examination (--TESTCD) variable: it should be limited to 8 characters, cannot start with a number, and cannot contain characters other than letters in upper case, numbers, or underscores. Value '{data($value)}' was found for variable {data($testname)} in dataset {data($datasetname)}.</error>
Invalid value for --TESTCD variable, single dataset or domain - The value of a Short Name of Measurement, Test or Examination (--TESTCD) variable should be limited to 8 characters, cannot start with a number, and cannot contain characters other than letters in upper case, numbers, or underscores
ALL
(: Rule FDAC058 - Invalid value for --TESTCD variable:
The value of a Short Name of Measurement, Test or Examination (--TESTCD) variable should be limited to 8 characters, cannot start with a number, and cannot contain characters other than letters in upper case, numbers, or underscores :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace functx = "http://www.functx.com";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
declare variable $domain external;
declare function functx:is-value-in-sequence
( $value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
(: let $base := '/db/fda_submissions/cdiscpilot01/' :)
(: let $define := 'define_2_0.xml' :)
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
let $numbers := ("0","1","2","3","4","5","6","7","8","9")
(: iterate over all datasets in the define.xml :)
for $itemgroup in doc(concat($base,$define))//odm:ItemGroupDef[@Name=$domain or @Domain=$domain]
let $itemgroupdefname := $itemgroup/@Name
(: get the dataset name and location :)
let $datasetname := $itemgroup/def:leaf/@xlink:href
let $dataset := concat($base,$datasetname)
(: get the OID of the "--TEST" variable :)
let $testoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TESTCD')]/@OID
where $a = $itemgroup/odm:ItemRef/@ItemOID
return $a
)
let $testname := doc(concat($base,$define))//odm:ItemDef[@OID=$testoid]/@Name
for $record in doc($dataset)//odm:ItemGroupData[odm:ItemData[@ItemOID=$testoid]]
let $recnum := $record/@data:ItemGroupDataSeq
let $value := $record/odm:ItemData[@ItemOID=$testoid]/@Value
let $firstchar := substring($value,1,1)
(: TODO: pattern matching does not seem to work well, though the pattern seems to be correct! :)
where string-length($value) > 8 or functx:is-value-in-sequence($firstchar,$numbers) or not(matches($value,'[A-Z_][A-Z0-9_]*'))
return <error rule="FDAC058" recordnumber="{data($recnum)}" dataset="{data($itemgroupdefname)}" variable="{$testname}" rulelastupdate="2015-08-15">Invalid value for Short Name of Measurement, Test or Examination (--TESTCD) variable: it should be limited to 8 characters, cannot start with a number, and cannot contain characters other than letters in upper case, numbers, or underscores. Value '{data($value)}' was found for variable {data($testname)} in dataset {data($datasetname)}.</error>
Invalid value for --PARM variable - The value of Parameter (--PARM) variable should be no more than 40 characters in length
TS
(: Rule FDAC059 - Invalid value for --PARM variable:
The value of Parameter (--PARM) variable should be no more than 40 characters in length :)
(: This rule is really outdated! Even CDISC has published test names with > 40 characters. The rule is a relict of the ancient XPT format. :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare namespace functx = "http://www.functx.com";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all TS datasets (there should be only one) :)
for $itemgroup in doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
(: Get the OID for the TSPARM variable :)
let $testoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARM']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: we of course only look into datasets where there really is a --TEST :)
let $datasetname := $itemgroup//def:leaf/@xlink:href
let $dataset := concat($base,$datasetname)
(: iterate over all the records within the TS dataset :)
for $record in doc($dataset)//odm:ItemGroupData
(: get the record number :)
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the value of the TSPARM variable :)
let $testvalue := $record/odm:ItemData[@ItemOID=$testoid]/@Value
(: when it has more than 40 characters, give an error :)
where string-length($testvalue) > 40
return <error rule="FDAC059" dataset="TS" variable="TSPARM" recordnumber="{data($recnum)}" rulelastupdate="2015-08-26">The value for TSPARM in dataset {data($datasetname)} has more than 40 characters: '{data($testvalue)}' was found</error>
Invalid value for --PARMCD variable - The value of Parameter Short Name (--PARMCD) variables should be no more than 8 characters in length
ALL
(: Rule FDAC0060 - Invalid value for --PARMCD variable:
The value of Parameter Short Name (--PARMCD) variables should be no more than 8 characters in length :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare namespace functx = "http://www.functx.com";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all TS datasets (there should be only one) :)
for $itemgroup in doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
(: Get the OID for the TSPARMCD variable :)
let $testcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $datasetname := $itemgroup//def:leaf/@xlink:href
let $dataset := concat($base,$datasetname)
(: iterate over all the records within the TS dataset :)
for $record in doc($dataset)//odm:ItemGroupData
(: get the record number :)
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the value of the TSPARM variable :)
let $testvalue := $record/odm:ItemData[@ItemOID=$testcdoid]/@Value
(: when it has more than 8 characters, give an error :)
where string-length($testvalue) > 8
return <error rule="FDAC060" dataset="TS" variable="TSPARMCD" recordnumber="{data($recnum)}" rulelastupdate="2015-08-26">The value for TSPARMCD in dataset {data($datasetname)} has more than 8 characters: '{data($testvalue)}' was found</error>
Invalid ARMCD - Planned Arm Code (ARMCD) values should match entries in the Trial Arms (TA) dataset, except for subjects who failed screening (ARMCD = 'SCRNFAIL') or were not fully assigned to an Arm (ARMCD = 'NOTASSGN')
DM
TA
(: Rule FDAC061 - Invalid ARMCD:
Planned Arm Code (ARMCD) values should match entries in the Trial Arms (TA) dataset, except for subjects who failed screening (ARMCD = 'SCRNFAIL') or were not fully assigned to an Arm (ARMCD = 'NOTASSGN')
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the DM dataset :)
let $dmdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/def:leaf/@xlink:href
let $dmdataset := concat($base,$dmdatasetname)
(: Get the TA dataset :)
let $tadatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TA']/def:leaf/@xlink:href
let $tadataset := concat($base,$tadatasetname)
(: get the OID of ARMCD in the DM domain - attention: there ca be several ItemDefs for this,
but we only want the one from DM :)
let $dmarmcdoid :=
(for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a)
(: and the OID of ARMCD in the TA dataset :)
let $taarmcdoid :=
(for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TA']/odm:ItemRef/@ItemOID
return $a)
(: and the OID of USUBJID in the DM dataset - needed later for reporting :)
let $dmusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records in the DM dataset :)
for $record in doc($dmdataset)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value for ARMCD and the USUBJID :)
let $dmarmcd := $record/odm:ItemData[@ItemOID=$dmarmcdoid]/@Value
let $usubjidvalue := $record/odm:ItemData[@ItemOID=$dmusubjidoid]/@Value
(: and check whether there is such a value in TA :)
where not($dmarmcd='SCRNFAIL') and not($dmarmcd='NOTASSGN') and
not(doc($tadataset)//odm:ItemData[@ItemOID=$taarmcdoid][@Value=$dmarmcd])
return <error rule="FDAC061" rulelastupdate="2015-02-10" variable="ARMCD" dataset="DM" recordnumber="{data($recnum)}">Invalid ARMCD={data($dmarmcd)} in DM dataset {data($dmdatasetname)} for USUBJID={data($usubjidvalue)} - ARMCD was not found in the TA dataset {data($tadatasetname)}</error>
Invalid ETCD - Element Code (ETCD) values should match entries in the Trial Elements (TE) dataset, except for unplanned Element (ETCD = 'UNPLAN')
SE
TA
(: Rule FDAC062 - Invalid ETCD:
Element Code (ETCD) values should match entries in the Trial Elements (TE) dataset, except for unplanned Element (ETCD = 'UNPLAN')
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the TA and SE datasets :)
let $datasets := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TA' or @Name='SE']
(: Get the TE dataset :)
let $tedatasetlocation := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TE']/def:leaf/@xlink:href
(: and the OID for ETCD in the TE dataset :)
let $teectdoid :=
(for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ETCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TE']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over the two datasets :)
for $dataset in $datasets
let $datasetname := $dataset/@Name
let $datasetlocation := $dataset/def:leaf/@xlink:href
(: Get the OID for ETCD :)
let $etcdoid :=
(for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ETCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$datasetname]/odm:ItemRef/@ItemOID
return $a)
(: now iterate over all records within the dataset :)
for $record in doc(concat($base,$datasetlocation))//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: exclude the one for which the ETCD value is 'UNPLAN' :)
let $etcdvalue := $record/odm:ItemData[@ItemOID=$etcdoid]/@Value
(: and check whether present in the TE dataset, excluding the 'UNPLAN' ones :)
where not(doc(concat($base,$tedatasetlocation))//odm:ItemGroupData/odm:ItemData[@ItemOID=$teectdoid][@Value=$etcdvalue]) and not($etcdvalue='UNPLAN')
return <error rule="FDAC062" rulelastupdate="2015-02-10" dataset="SE" variable="ETCD" recordnumber="{data($recnum)}">Invalid ETCD: Element Code ETCD={data($etcdvalue)} in dataset {data($datasetlocation)} was not found in TE dataset {data($tedatasetlocation)}</error>
Invalid IETESTCD
IE
TI
(: Rule FDAC063 - Invalid IETESTCD
A value for Inclusion/Exclusion Criterion Short Name (IETESTCD) must be present the Trial Inclusion/Exclusion Criteria (TI) domain
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the TI dataset and the OID for IETESTCD in TI :)
let $tidatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TI']/def:leaf/@xlink:href
let $tidataset := concat($base,$tidatasetname)
let $tiietestcdoid :=
(for $a in doc(concat($base,$define))//odm:ItemDef[@Name='IETESTCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TI']/odm:ItemRef/@ItemOID
return $a
)
(: Get the IE dataset and the OID of IETESTCD :)
let $iedatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='IE']/def:leaf/@xlink:href
let $iedataset := concat($base,$iedatasetname)
let $ietestcdoid :=
(for $a in doc(concat($base,$define))//odm:ItemDef[@Name='IETESTCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='IE']/odm:ItemRef/@ItemOID
return $a
)
(: now iterate over all records in the IE dataset :)
for $record in doc($iedataset)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the value of IETESTCD :)
let $ietestcdvalue := $record/odm:ItemData[@ItemOID=$ietestcdoid]/@Value
(: and check whether present in the TI dataset :)
where not(doc($tidataset)//odm:ItemData[@ItemOID=$tiietestcdoid][@Value=$ietestcdvalue])
return <error rule="FDAC063" rulelastupdate="2015-02-10" dataset="IE" variable="IETESTCD" recordnumber="{$recnum}">Invalid IETESTCD={data($ietestcdvalue)} in dataset {data($iedatasetname)} short name was not found in TI dataset {data($tidatasetname)}</error>
Invalid ARM/ARMCD - The combination of Description of Planned Arm (ARM) and Planned Arm Code (ARMCD) values must match entries in the Trial Arms (TA) dataset, except for subjects who failed screening (ARMCD = 'SCRNFAIL') or were not fully assigned to an Arm (ARMCD = 'NOTASSGN')
DM
(: Rule FDAC064 - Invalid ARM/ARMCD:
The combination of Description of Planned Arm (ARM) and Planned Arm Code (ARMCD) values must match entries in the Trial Arms (TA) dataset, except for subjects who failed screening (ARMCD = 'SCRNFAIL') or were not fully assigned to an Arm (ARMCD = 'NOTASSGN')
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the DM dataset :)
let $dmdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/def:leaf/@xlink:href
let $dmdataset := concat($base,$dmdatasetname)
(: get the OID for the ARMCD variable in the DM dataset :)
let $dmarmcdoid :=
(for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a)
(: Get the OID for the ARM (arm name) in the DM dataset :)
let $dmarmoid :=
(for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ARM']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a)
(: and the OID of USUBJID - which is the third variable :)
let $usubjidoid := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef[3]/@ItemOID
(: Get the TA dataset :)
let $tadatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TA']/def:leaf/@xlink:href
let $tadataset := concat($base,$tadatasetname)
(: and the OID of the ARMCD and ARM in TA (can be different from the ones in DM) :)
let $taarmcdoid :=
(for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TA']/odm:ItemRef/@ItemOID
return $a)
(: Get the OID for the ARM (arm name) in the DM dataset :)
let $taarmoid :=
(for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ARM']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TA']/odm:ItemRef/@ItemOID
return $a)
(: now iterate over all records in the DM dataset :)
for $record in doc($dmdataset)//odm:ItemGroupData
let $recnum := $record/@data:ItemDataSeq
(: Get the values of ARMCD and ARM :)
let $armcdvalue := $record/odm:ItemData[@ItemOID=$dmarmcdoid]/@Value
let $armvalue := $record/odm:ItemData[@ItemOID=$dmarmoid]/@Value
(: and check whether present in the TA dataset,
but except for ARMCD=SCRNFAIL and ARMCD=NOTASSGN :)
where not(doc($tadataset)//odm:ItemData[@ItemOID=$taarmcdoid][@Value=$armcdvalue])
and not(doc($tadataset)//odm:ItemData[@ItemOID=$taarmoid][@Value=$armvalue])
and not($armcdvalue='SCRNFAIL') and not($armcdvalue='NOTASSGN')
return <error rule="FDAC064" rulelastupdate="2015-02-10" dataset="DM" variable="ARMCD" recordnumber="{data($recnum)}">Invalid ARMCD/ARM combination in DM dataset {data($dmdatasetname)}: combination of ARMCD={data($armcdvalue)} and ARM={data($armvalue)} was not found in the TA dataset {data($tadatasetname)}</error>
Invalid RDOMAIN - Related Domain Abbreviation (RDOMAIN) must have a valid value of Domains included in the study data
CO
RELREC
SUPPQUAL
(: Rule FDAC065 - Invalid RDOMAIN:
Related Domain Abbreviation (RDOMAIN) must have a valid value of Domains included in the study data (CO,RELREC,SUPxx)
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the RELREC, CO and SUPPxx datasets :)
let $datasets := doc(concat($base,$define))//odm:ItemGroupDef[@Name='RELREC' or @Name='CO' or starts-with(@Name,'SUPP')]
(: iterate over these datasets :)
for $dataset in $datasets
let $name := $dataset/@Name
(: Get the dataset location :)
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OID of the RDOMAIN variable :)
let $rdomainoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='RDOMAIN']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: now iterate over all the record in these dataset :)
for $record in doc($datasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the value of the RDOMAIN variable :)
let $rdomainvalue := $record/odm:ItemData[@ItemOID=$rdomainoid]/@Value
(: and check whether defined in the define.xml - we take into account that sometimes the "Domain" attribute is missing :)
where not(doc(concat($base,$define))//odm:ItemGroupDef[@Domain=$rdomainvalue or @Name=$rdomainvalue])
return <error rule="FDAC065" dataset="{data($name)}" variable="RDOMAIN" rulelastupdate="2015-08-30" recordnumber="{data($recnum)}">Invalid value for RDOMAIN={data($rdomainvalue)} in dataset {data($datasetname)} - domain {data($rdomainvalue)} was not found in the define.xml file {data($define)}</error>
Invalid IDVAR - Identifying Variable (IDVAR) must have a valid value of variables from a referenced Domain
RELREC
SUPPQUAL
(: Rule FDAC066 - Invalid IDVAR:
Identifying Variable (IDVAR) must have a valid value of variables from a referenced Domain :)
(: Rule CG0370 - When IDVAR != null then IDVAR is variable in domain = RDOMAIN :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
let $definedoc := doc(concat($base,$define))
(: iterate over all SUPP--, CO and RELREC dataset definitions :)
for $itemgroupdef in $definedoc//odm:ItemGroupDef[@Name='CO' or @Name='RELREC' or starts-with(@Name,'SUPP')]
let $name := $itemgroupdef/@Name
(: get the OID of RDOMAIN and of IDVAR:)
let $rdomainoid := (
for $a in $definedoc//odm:ItemDef[@Name='RDOMAIN']/@OID
where $a = $itemgroupdef/odm:ItemRef/@ItemOID
return $a
)
let $idvaroid := (
for $a in $definedoc//odm:ItemDef[@Name='IDVAR']/@OID
where $a = $itemgroupdef/odm:ItemRef/@ItemOID
return $a
)
(: get the dataset location and the document :)
let $datasetlocation := $itemgroupdef/def:leaf/@xlink:href
let $datasetdoc := doc(concat($base,$datasetlocation))
(: iterate over all the records in the dataset for which there is a value of RDOMAIN and of IDVAR :)
for $record in $datasetdoc//odm:ItemGroupData[odm:ItemData[@ItemOID=$rdomainoid] and odm:ItemData[@ItemOID=$idvaroid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of RDOMAIN and of IDVAR :)
let $rdomain := $record/odm:ItemData[@ItemOID=$rdomainoid]/@Value
let $idvarvalue := $record/odm:ItemData[@ItemOID=$idvaroid]/@Value
(: look up whether there is such a variable in the parent domain RDOMAIN :)
where $idvarvalue and (not($definedoc//odm:ItemDef[@Name=$idvarvalue]) or not($definedoc//odm:ItemGroupDef[@Name=$rdomain or starts-with(@Name,$rdomain)]/odm:ItemRef[@ItemOID=$definedoc//odm:ItemDef[@Name=$idvarvalue]/@OID]))
return <error rule="FDAC066" dataset="{data($name)}" variable="IDVAR" recordnumber="{data($recnum)}" rulelastupdate="2017-03-15">Variable '{data($idvarvalue)}' was not found in the parent dataset of the referenced domain RDOMAIN='{data($rdomain)}' </error>
Invalid value for ARMCD - The value of Planned Arm Code (ARMCD) should be no more than 20 characters in length
DM
TA
TV
(: Rule FDAC067 - Invalid value for ARMCD:
The value of Planned Arm Code (ARMCD) should be no more than 20 characters in length
:)
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the DM, TA and TV datasets :)
let $datasets := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM' or @Name='TA' or @Name='TV']
(: and iterate over these :)
for $dataset in $datasets
(: get the dataset name and location :)
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: and get the OID of the ARMCD variable - can be different in each dataset :)
let $armcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: start iterating over all records in the dataset :)
for $record in doc($datasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the value of the ARMCD variable :)
let $armcdvalue := $record/odm:ItemData[@ItemOID=$armcdoid]/@Value
(: and check whether not more than 20 characters :)
where string-length($armcdvalue) > 20
return <warning rule="FDAC067" dataset="{data($name)}" variable="ARMCD" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">Invalid value for ARMCD={data($armcdvalue)} in dataset {data($datasetname)} - it has more than 20 characters</warning>
Unexpected value for ARMCD variable - Records for subjects who failed a screening or were not assigned to study treatment (ARMCD is 'SCRNFAIL' or 'NOTASSGN') should not be included in the Trial Arms (TA) or Trial Visits (TV) datasets
TA
TV
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the OID of the ARMCD variable in the define.xml for TA and TV :)
for $itemgroupdef in doc(concat($base,$define))//odm:ItemGroupDef[@Name='TA' or @Name='TV']
let $itemgroupdefname := $itemgroupdef/@Name
(: get the OID of ARMCD :)
let $armcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ARMCD']/@OID
where $a = $itemgroupdef/odm:ItemRef/@ItemOID
return $a
)
(: and the location of the dataset :)
let $datasetname := $itemgroupdef/def:leaf/@xlink:href
let $dataset := concat($base,$datasetname)
(: iterate over all ARMCD record in the dataset :)
for $record in doc($dataset)//odm:ItemGroupData[odm:ItemData[@ItemOID=$armcdoid]]
let $recnum := $record/@data:ItemGroupDataSeq
let $armcdvalue := $record/odm:ItemData[@ItemOID=$armcdoid]/@Value
(: ARMCD is not allowed to be SCRNFAIL nor NOTASSGN :)
where $armcdvalue = 'SCRNFAIL' or $armcdvalue = 'NOTASSGN'
return <error rule="FDAC068" dataset="{data($itemgroupdefname)}" variable="ARMCD" rulelastupdate="2016-03-28" recordnumber="{data($recnum)}">Unexpected value for ARMCD={data($armcdvalue)} in dataset {data($itemgroupdefname)} - 'SCRNFAIL' and 'NOTASSGN' are not allowed to appear in TA nor TV</error>
Non-unique value for TAETORD within ARMCD - Order of Element within Arm (TAETORD) must have a unique value for a given value of Planned Arm Code (ARMCD) within the domain
TA
(: Rule FDAC069 - Non-unique value for TAETORD within ARMCD:
Order of Element within Arm (TAETORD) must have a unique value for a given value of Planned Arm Code (ARMCD) within the domain
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the TA dataset :)
let $tadatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TA']/def:leaf/@xlink:href
let $tadataset := concat($base,$tadatasetname)
(: also need to find out the OIDs of ARMCD and TAETORD :)
let $taarmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TA']/odm:ItemRef/@ItemOID
return $a
)
let $tataetordoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TAETORD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TA']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records in the TA dataset :)
for $record in doc($tadataset)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: Get the value of ARMCD and TAETORD :)
let $taarmcdvalue := $record/odm:ItemData[@ItemOID=$taarmcdoid]/@Value
let $tataetordvalue := $record/odm:ItemData[@ItemOID=$tataetordoid]/@Value
(: and have a second iteration over all subsequent record :)
for $nextrecord in doc($tadataset)//odm:ItemGroupData[@data:ItemGroupDataSeq > $recnum]
let $recnumnext := $nextrecord/@data:ItemGroupDataSeq
(: and look for duplicate values :)
let $taarmcdvaluenext := $nextrecord/odm:ItemData[@ItemOID=$taarmcdoid]/@Value
let $tataetordvaluenext := $nextrecord/odm:ItemData[@ItemOID=$tataetordoid]/@Value
where $taarmcdvalue = $taarmcdvaluenext and $tataetordvalue = $tataetordvaluenext
return <error rule="FDAC069" dataset="TA" variable="TAETORD" rulelastupdate="2015-02-10" recordnumber="{data($recnumnext)}">Non-unique value for TAETORD within ARMCD. Records {data($recnum)} and {data($recnumnext)} have the same value for ARMCD={data($taarmcdvalue)} and TAETORD={data($tataetordvalue)} in TA dataset {data($tadatasetname)}</error>
Invalid value for ETCD - The value of Element Code (ETCD) should be no more than 8 characters in length
SE
(: Rule FDAC070 - Invalid value for ETCD:
The value of Element Code (ETCD) should be no more than 8 characters in length
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the SE dataset :)
let $sedatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='SE']/def:leaf/@xlink:href
let $sedataset := concat($base,$sedatasetname)
(: also need to find out the OID of ETCD :)
let $seetcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ETCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='SE']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records in the SE dataset :)
for $record in doc($sedataset)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: Get the ETCD value :)
let $etcdvalue := $record/odm:ItemData[@ItemOID=$seetcdoid]/@Value
(: and check whether more than 8 characters :)
where string-length($etcdvalue) > 8
return <warning rule="FDAC070" dataset="SE" variable="ETCD" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">Invalid value for ETCD in SE dataset {data($sedatasetname)} - Value {data($etcdvalue)} has more than 8 characters</warning>
Invalid value for QLABEL - Qualifier Variable Label (QLABEL) value may have up to 40 characters
ALL
(: Rule FDAC071 - Invalid value for QLABEL:
Qualifier Variable Label (QLABEL) value may have up to 40 characters :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get all the SUPPxx datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[starts-with(@Name,'SUPP')]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OID of the QLABEL variable :)
let $qlabeloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='QLABEL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records in the dataset :)
for $record in doc($datasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: Get the QLABEL value :)
let $qlabelvalue := $record/odm:ItemData[@ItemOID=$qlabeloid]/@Value
(: and check whether more than 40 characters :)
where string-length($qlabelvalue) > 40
return <error rule="FDAC071" rulelastupdate="2015-02-10" dataset="{data($name)}" variable="QLABEL" recordnumber="{data($recnum)}">Invalid value for QLABEL in dataset {data($datasetname)} - Label={data($qlabelvalue)} has more than 40 characters</error>
Invalid dataset name for split domain - Split datasets must not have name of original domain. E.g., lbhm.xpt is a valid name, when lb.xpt is not a valid dataset name for split domain.
ALL
(: Rule FDAC072 - Split datasets must not have name of original domain.
E.g., lbhm.xpt is a valid name, when lb.xpt is not a valid dataset name for split domain.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare namespace functx = "http://www.functx.com";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all datasets in the define.xml that have a 'Domain' attribute :)
for $itemgroup in doc(concat($base,$define))//odm:ItemGroupDef[@Domain]
(: get the domain name - value of the 'Domain' attribute :)
let $domain := $itemgroup/@Domain
(: and the dataset name (@Name attribute) :)
let $name := $itemgroup/@Name
(: and get the filename :)
let $filename := $itemgroup/def:leaf/@xlink:href
(: get the position of the current ItemGroupDef in the series :)
let $pos := $itemgroup/position()
(: get all the ItemGroupDefs with the same value for the 'Domain' attribute
If so, this means that the dataset is a 'splitted' dataset.
P.S. There currently is no other way to find out :)
let $count := count(doc(concat($base,$define))//odm:ItemGroupDef[@Domain=$domain])
(: in case there is more than one such dataset, the prefix (part before the dot)
MUST have MORE than two characters (e.g. qscs.xpt) :)
where $count > 1 and not(string-length(substring-before($filename,'.')) > 2)
(: filenames should have >2 characters before the dot :)
return <error rule="FDAC072" dataset="{data($name)}" rulelastupdate="2015-08-26">Split dataset {data($name)} has a file name '{data($filename)}' that is typical for non-split datasets</error>
Invalid value for QNAM variable - The value of Qualifier Variable Name (QNAM) should be limited to 8 characters, cannot start with a number, and cannot contain characters other than letters in upper case, numbers, or underscores
SUPPQUAL
(: Rule FDAC073 - Invalid value for QNAM variable:
The value of Qualifier Variable Name (QNAM) should be limited to 8 characters, cannot start with a number, and cannot contain characters other than letters in upper case, numbers, or underscores
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get all the SUPPxx datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[starts-with(@Name,'SUPP')]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OID of the QNAM variable :)
let $qnamoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='QNAM']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records in the dataset :)
for $record in doc($datasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: Get the QNAM value :)
let $qnamvalue := $record/odm:ItemData[@ItemOID=$qnamoid]/@Value
(: and check whether more than 8 characters and that the character types are correct :)
where string-length($qnamvalue) > 8 or not(matches($qnamvalue,'[A-Z_][A-Z0-9_]*'))
return <warning rule="FDAC073" variable="QNAM" dataset="{data($name)}" rulelastupdate="2015-09-01" recordnumber="{data($recnum)}">Invalid value for QNAM in dataset {data($datasetname)} - Label={data($qnamvalue)} has more than 8 characters or starts with a number or contains characters other than letters in upper case, numbers, or underscores</warning>
Invalid referenced record - Reference record defined by Related Domain Abbreviation (RDOMAIN), Unique Subject Identifier (USUBJID), Identifying Variable (IDVAR) and Identifying Variable Value (IDVARVAL) must exist in the target Domain
CO
RELREC
SUPPQUAL
(: Rule FDAC074 - Invalid referenced record:
Reference record defined by Related Domain Abbreviation (RDOMAIN), Unique Subject Identifier (USUBJID), Identifying Variable (IDVAR) and Identifying Variable Value (IDVARVAL) must exist in the target Domain
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the CO, RELREC and SUPP-- datasets :)
let $datasets := doc(concat($base,$define))//odm:ItemGroupDef[@Name='RELREC' or starts-with(@Name,'CO') or starts-with(@Name,'SUPP')]
(: iterate over these datasets :)
for $dataset in $datasets
(: Get the name and location :)
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: and take the OIDs of USUBJID, RDOMAIN, IDVAR and IDVARVAL :)
let $usubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $rdomainoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='RDOMAIN']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $idvaroid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='IDVAR']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $idvarvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='IDVARVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records in the dataset :)
for $record in doc($datasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: and retrieve the values of RDOMAIN, USUBJID, IDVAR and IDVARVAL :)
let $rdomainval := $record/odm:ItemData[@ItemOID=$rdomainoid]/@Value
let $usubjidvalue := $record/odm:ItemData[@ItemOID=$usubjidoid]/@Value
let $idvarvalue := $record/odm:ItemData[@ItemOID=$idvaroid]/@Value
let $idvarvalvalue := $record/odm:ItemData[@ItemOID=$idvarvaloid]/@Value
(: find the corresponding record in the parent domain, which can have splitted datasets :)
(: IMPORTANT REMARK: @Domain is only required in the context of a regulatory submission - so we must look at the first characters of the name too :)
let $parentdatasets := doc(concat($base,$define))//odm:ItemGroupDef[@Domain=$rdomainval or substring(@Name,1,2)=$rdomainval]
(: in case of splitted datasets, $parentrecordcount gives e.g. 0 0 21 :)
let $parentrecordcount := (
for $parentdataset in $parentdatasets
let $parentname := $parentdataset/@Name
let $parentdatasetname := $parentdataset/def:leaf/@xlink:href
let $parentdatasetlocation := concat($base,$parentdatasetname)
(: get the OID of USUBJID in the parent dataset :)
let $parentusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$parentname]/odm:ItemRef/@ItemOID
return $a
)
(: get the OID of the identifying variable in the parent dataset :)
let $parentidvaroid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name=$idvarvalue]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$parentname]/odm:ItemRef/@ItemOID
return $a
)
(: try to find the record in this dataset :)
return
(: case DM - no IDVAR or IDVARVAL :)
if($rdomainval = 'DM') then
count(doc($parentdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$parentusubjidoid][@Value=$usubjidvalue]])
(: RDOMAIN is NOT DM - check on IDVAR/IDVARVAL :)
else (
count(doc($parentdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$parentusubjidoid][@Value=$usubjidvalue] and odm:ItemData[@ItemOID=$parentidvaroid][@Value=$idvarvalvalue]] )
)
)
let $parentrecordcountsummed := sum($parentrecordcount) (: sum the counts over the (splitted) datasets :)
where $parentrecordcountsummed = 0 (: parent no records found at all :)
return <error rule="FDAC074" dataset="{data($name)}" variable="RDOMAIN" rulelastupdate="2017-03-15" recordnumber="{data($recnum)}">Invalid referenced record - Dataset={data($name)}: no parent records found in RDOMAIN={data($rdomainval)} for USUBJID={data($usubjidvalue)}</error>
Invalid ETCD/ELEMENT - The combination of Element Code (ETCD) and Description of Element (ELEMENT) values should match entries in the Trial Elements (TE) dataset, except for unplanned Element (ETCD = 'UNPLAN') - dataset SE,TA
SE
TA
(: Rule FDA075 - Invalid ETCD/ELEMENT:
The combination of Element Code (ETCD) and Description of Element (ELEMENT) values should match entries in the Trial Elements (TE) dataset, except for unplanned Element (ETCD = 'UNPLAN') - dataset SE,TA :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the TE dataset :)
let $tedatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TE']/def:leaf/@xlink:href
let $tedatasetlocation := concat($base,$tedatasetname)
(: Get the OID of ETCD and ELEMENT in the TE dataset :)
let $teetcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ETCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TE']/odm:ItemRef/@ItemOID
return $a
)
let $teelementoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ELEMENT']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TE']/odm:ItemRef/@ItemOID
return $a
)
(: Get the TA and SE datasets :)
let $datasets := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TA' or @Name='SE']
(: iterate over these datasets :)
for $dataset in $datasets
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OIDs of the ETCD and ELEMENT variables in the TA or SE datasets :)
let $etcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ETCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $elementoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ELEMENT']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records in the dataset :)
for $record in doc($datasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the value for ETCD and ELEMENT :)
let $etcdvalue := $record/odm:ItemData[@ItemOID=$etcdoid]/@Value
let $elementvalue := $record/odm:ItemData[@ItemOID=$elementoid]/@Value
(: and find a record in the TE dataset - exclude however ETCD='UNPLAN' :)
where not(doc($tedatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$teetcdoid][@Value=$etcdvalue] and odm:ItemData[@ItemOID=$teelementoid][@Value=$elementvalue]]) and not($etcdvalue='UNPLAN')
return <error rule="FDAC075" dataset="{data($name)}" variable="ETCD" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">Invalid ETCD/ELEMENT in dataset {data($datasetname)}. The combination of Element Code ETCD={data($etcdvalue)} and Description of Element ELEMENT={data($elementvalue)} was not found in the TE dataset {data($tedatasetname)}</error>
Invalid TAETORD - Order of Element within Arm (TAETORD) values for all datasets should match entries in the Trial Arms (TA) dataset
ALL
(: Rule FDAC076 - Invalid TAETORD:
Order of Element within Arm (TAETORD) values for all datasets should match entries in the Trial Arms (TA) dataset
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the TA dataset :)
let $tadataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TA']
let $tadatasetname := $tadataset/def:leaf/@xlink:href
let $tadatasetlocation := concat($base,$tadatasetname)
(: and the OID of TAETORD :)
let $taetordoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TAETORD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TA']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all other datasets :)
let $datasets := doc(concat($base,$define))//odm:ItemGroupDef[not(@Name='TA')]
for $dataset in $datasets
(: get name and location :)
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: and the OID of TAETORD :)
let $datasettaetordoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TAETORD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: now iterate over all the records that have a TAETORD :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$datasettaetordoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the value of TAETORD :)
let $taetord := $record/odm:ItemData[@ItemOID=$datasettaetordoid]/@Value
(: and check whether it can be found in the TA dataset :)
where not((doc($tadatasetlocation))//odm:ItemGroupData/odm:ItemData[@ItemOID=$taetordoid][@Value=$taetord])
return <error rule="FDAC076" dataset="TA" variable="TAETORD" rulelastupdate="2015-02-10" recordnumer="{data($recnum)}">Invalid TAETORD in {data($name)} in dataset {data($datasetname)}. TAETORD={data($taetord)} was not found in dataset {data($tadatasetname)}</error>
Invalid value for RELTYPE variable - Relationship Type (RELTYPE) in RELREC must be NULL, when Identifying Variable (IDVAR) is populated with a --SEQ value
RELREC
(: Rule FDAC077 - Invalid value for RELTYPE variable:
Relationship Type (RELTYPE) in RELREC must be NULL, when Identifying Variable (IDVAR) is populated with a --SEQ value
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the RELREC dataset :)
let $relrecdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='RELREC']
let $relrecdatasetname := $relrecdataset/def:leaf/@xlink:href
let $relrecdatasetlocation := concat($base,$relrecdatasetname)
(: and the OID of RELID and of the IDVAR :)
let $reltypeoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='RELTYPE']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='RELREC']/odm:ItemRef/@ItemOID
return $a
)
let $idvaroid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='IDVAR']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='RELREC']/odm:ItemRef/@ItemOID
return $a
)
(: now iterate over all the records in the RELREC dataset :)
for $record in doc($relrecdatasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
let $idvarvalue := $record/odm:ItemData[@ItemOID=$idvaroid]/@Value
let $relvalue := $record/odm:ItemData[@ItemOID=$reltypeoid]/@Value
(: and check those that have IDVAR ending with 'SEQ' - for these RELTYPE must be null :)
where ends-with($idvarvalue,'SEQ') and string-length($relvalue) > 0
return <error rule="FDAC077" dataset="RELREC" variable="RELTYPE" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">Invalid value for RELTYPE variable. Non-null value={data($relvalue)} was found though identifying variable is {data($idvarvalue)}</error>
Invalid value for RELTYPE variable - Relationship Type (RELTYPE) variable values should be populated with terms 'ONE', 'MANY', when Related Records (RELREC) dataset is used to identify relationships between datasets.
RELREC
(: Rule FDAC078 - Invalid value for RELTYPE variable:
Relationship Type (RELTYPE) variable values should be populated with terms 'ONE', 'MANY', when Related Records (RELREC) dataset is used to identify relationships between datasets.
TODO: how can we see that the RELREC dataset is used to identify relationships between datasets?
The only thing we do here is check whether RELTYPE is either empty (but then the data point should be absent when using Dataset-XML
or either has the value "ONE" or "MANY"
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdiscpilot01/' :)
(: let $define := 'define_2_0.xml' :)
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all RELREC datasets in the define.xml -
usually there will be only one :)
for $itemgroup in doc(concat($base,$define))//odm:ItemGroupDef[@Name='RELREC']
(: get the dataset name and location :)
let $datasetname := $itemgroup/def:leaf/@xlink:href
let $dataset := concat($base,$datasetname)
(: get the OID of the "RELTYPE" variable :)
let $reltypeoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='RELTYPE']/@OID
where $a = $itemgroup/odm:ItemRef/@ItemOID
return $a
)
(: now iterate over all RELREC records for which there IS a RELTYPE datapoint :)
for $record in doc($dataset)//odm:ItemGroupData[odm:ItemData[@ItemOID=$reltypeoid]]
(: get the record number and the value for RELTYPE :)
let $recnum := $record/@data:ItemGroupDataSeq
let $value := $record/odm:ItemData[@ItemOID=$reltypeoid]/@Value
(: the value may only be 'ONE' or 'MANY' - if null, the data point should not exist in Dataset-XML :)
where not($value='ONE') and not($value='MANY')
return <error rule="FDAC078" dataset="RELREC" variable="RELTYPE" recordnumber="{data($recnum)}" rulelastupdate="2015-08-15">Invalid value for RELTYPE variable: only 'ONE' or 'MANY' is allowed. The value '{data($value)}'was found</error>
Invalid EPOCH - Epoch (EPOCH) values in all datasets should match entries in the Trial Arms (TA) dataset
ALL
(: Rule FDAC079 - Invalid EPOCH:
Epoch (EPOCH) values in all datasets should match entries in the Trial Arms (TA) dataset
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the TA dataset :)
let $tadataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TA']
let $tadatasetname := $tadataset/def:leaf/@xlink:href
let $tadatasetlocation := concat($base,$tadatasetname)
(: and get the OID of the EPOCH variable :)
let $taepochoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='EPOCH']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TA']/odm:ItemRef/@ItemOID
return $a
)
(: now iterate over all other datasets :)
let $datasets := doc(concat($base,$define))//odm:ItemGroupDef[not(@Name='TA')]
for $dataset in $datasets
(: get name and location :)
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: and the OID of EPOCH :)
let $datasetepochoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='EPOCH']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records in this dataset that have a EPOCH variable :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$datasetepochoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: now get the value of the EPOCH variable :)
let $epochvalue := $record/odm:ItemData[@ItemOID=$datasetepochoid]/@Value
(: and check whether it is present in the TA dataset :)
where not(doc($tadatasetlocation)//odm:ItemGroupData/odm:ItemData[@ItemOID=$taepochoid][@Value=$epochvalue])
return <error rule="FDAC079" dataset="{data($name)}" variable="EPOCH" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">Invalid EPOCH. Value for EPOCH={data($epochvalue)} in dataset {data($datasetname)} was not found in the TA dataset {data($tadatasetname)}</error>
Invalid IETESTCD/IETEST/IECAT - The combination of Inclusion/Exclusion Criterion Short Name (IETESTCD), Criterion (IETEST), and Category (IECAT) values in IE should match entries in the Trial Inclusion/Exclusion Criteria (TI) dataset
IE
(: Rule FDAC080 - Invalid IETESTCD/IETEST/IECAT
The combination of Inclusion/Exclusion Criterion Short Name (IETESTCD), Criterion (IETEST), and Category (IECAT) values in IE should match entries in the Trial Inclusion/Exclusion Criteria (TI) dataset
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the TI dataset :)
let $tidataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TI']
let $tidatasetname := $tidataset/def:leaf/@xlink:href
let $tidatasetlocation := concat($base,$tidatasetname)
(: and get the OID of the IETESTCD variable :)
let $tiietestcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='IETESTCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TI']/odm:ItemRef/@ItemOID
return $a
)
let $tiietestoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='IETEST']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TI']/odm:ItemRef/@ItemOID
return $a
)
(: Get the OID of the IECAT variable :)
let $tiiecatoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='IECAT']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TI']/odm:ItemRef/@ItemOID
return $a
)
(: Get the IE dataset :)
let $iedataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='IE']
let $iedatasetname := $iedataset/def:leaf/@xlink:href
let $iedatasetlocation := concat($base,$iedatasetname)
(: and get the OIDs of the IETESTCD, IETEST and IECAT variables in IE :)
let $ieitestcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='IETESTCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='IE']/odm:ItemRef/@ItemOID
return $a
)
let $ieietestoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='IETEST']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='IE']/odm:ItemRef/@ItemOID
return $a
)
(: Get the OID of the IECAT variable :)
let $ieiecatoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='IECAT']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='IE']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records in the IE dataset :)
for $record in doc($iedatasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the values of IETESTCD, IETEST and IECAT :)
let $ietestcdvalue := $record/odm:ItemData[@ItemOID=$ieitestcdoid]/@Value
let $ietestvalue := $record/odm:ItemData[@ItemOID=$ieietestoid]/@Value
let $ieietcatvalue := $record/odm:ItemData[@ItemOID=$ieiecatoid]/@Value
(: and compare these with the IETESTCD, IETEST and IECAT in the TI dataset :)
where not(doc($tidatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tiietestcdoid][@Value=$ietestcdvalue]
and odm:ItemData[@ItemOID=$tiietestoid][@Value=$ietestvalue]
and odm:ItemData[@ItemOID=$tiiecatoid][@Value=$ieietcatvalue] ] )
return <error rule="FDAC080" dataset="IE" variable="IETESTCD" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">Invalid IETESTCD/IETEST/IECAT in dataset {data($iedatasetname)}. The combination of IETESTCD={data($ietestcdvalue)} and IETEST={data($ietestvalue)} and IECAT={data($ieietcatvalue)} cannot be found in the TI dataset {data($tidatasetname)}</error>
Negative value for –DOSE - Non-missing Dose (--DOSE) value must be greater than or equal to 0
INTERVENTIONS
(: Rule FDAC081 - Negative value for --DOSE (Intervention domains)
Non-missing Dose (--DOSE) value must be greater than or equal to 0
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all datasets that have a --DOSE variable - TODO? Limit to @def:Class=INTERVENTIONS ? :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: find the OID of the --DOSE variable :)
let $doseoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'DOSE')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $dosename := doc(concat($base,$define))//odm:ItemDef[@OID=$doseoid]/@Name
(: now iterate over all in the dataset itself :)
for $record in doc($datasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the value :)
let $dosevalue := $record/odm:ItemData[@ItemOID=$doseoid]/@Value
(: and check whether >= 0 :)
where $dosevalue and number($dosevalue) < 0
return <error rule="FDAC081" dataset="{data($name)}" variable="{data($dosename)}" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">Negative value for {data($dosename)} in dataset {data($datasetname)}: {data($dosevalue)} was found</error>
Negative value for --DUR - Non-missing Duration of Event, Exposure or Observation (--DUR) value must be greater than or equal to 0
ALL
(: Rule FDAC082 - Negative value for --DUR (all domains)
Non-missing Duration of Event, Exposure or Observation (--DUR) value must be greater than or equal to 0
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all datasets that have a --DOSE variable :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: find the OID of the --DOSE variable :)
let $duroid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'DUR')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $durname := doc(concat($base,$define))//odm:ItemDef[@OID=$duroid]/@Name
(: now iterate over all in the dataset itself :)
for $record in doc($datasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the value :)
let $durvalue := $record/odm:ItemData[@ItemOID=$duroid]/@Value
(: and check whether >= 0 :)
where $durvalue and starts-with($durvalue,'-') (: a --DUR value is present and it is a -P so negative value :)
return <error rule="FDAC081" dataset="{data($name)}" variable="data{data($durname)}" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">Negative value for {data($durname)} in dataset {data($datasetname)}: {data($durvalue)} was found</error>
Negative value for AGE - The value of Age (AGE) cannot be less than 0
DM
(: Rule FDAC083 - Negative value for AGE (DM)
The value of Age (AGE) cannot be less than 0
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the DM dataset :)
let $dmdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']
let $dmdatasetname := $dmdataset/def:leaf/@xlink:href
let $dmdatasetlocation := concat($base,$dmdatasetname)
(: find the OID of the AGE variable :)
let $ageoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AGE']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: now iterate over all in the dataset itself :)
for $record in doc($dmdatasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the value :)
let $agevalue := $record/odm:ItemData[@ItemOID=$ageoid]/@Value
(: and check whether >= 0 :)
where $agevalue and number($agevalue) < 0
return <error rule="FDAC082" dataset="DM" variable="AGE" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">Negative value for AGE in DM dataset {data($dmdatasetname)}: {data($agevalue)} was found</error>
Inconsistent value for --TEST within --TESTCD - All values of Name of Measurement, Test or Examination (--TEST) should be the same for a given value of Short Name of Measurement, Test or Examination (--TESTCD)
FINDINGS
(: Rule FDAC085 - Inconsistent value for --TEST within --TESTCD
All values of Name of Measurement, Test or Examination (--TEST) should be the same for a given value of Short Name of Measurement, Test or Examination (--TESTCD)
:)
(: NEW: made this considerably faster using "GROUP BY" :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdiscpilot01/' :)
(: let $define := 'define_2_0.xml' :)
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all datasets that have --TESTCD and --TEST :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: and get the OID of --TESTCD and --TEST :)
let $testcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TESTCD')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $testcdname := doc(concat($base,$define))//odm:ItemDef[@OID=$testcdoid]/@Name
let $testoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TEST')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $testname := doc(concat($base,$define))//odm:ItemDef[@OID=$testoid]/@Name
(: Group the records by the value of --TESTCD :)
let $orderedrecords := (
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$testcdoid]]
group by
$b:=$record/odm:ItemData[@ItemOID=$testcdoid]/@Value
return element group {
$record
}
)
(: all the records in the same group have the same value for --TESTCD.
They must also all have the same value for --TEST :)
for $group in $orderedrecords
let $testcdvalue := $group/odm:ItemGroupData[1]/odm:ItemData[@ItemOID=$testcdoid]/@Value
for $record in $group/odm:ItemGroupData[position()>1] (: start from the second one :)
let $recnum := $record/@data:ItemGroupDataSeq
let $testvalue := $record/odm:ItemData[@ItemOID=$testoid]/@Value
(: take the previous record in the same group, and take its --TEST value :)
let $precrecord := $record/preceding-sibling::odm:ItemGroupData[1] (: as they come in descending order :)
let $recnum2 := $precrecord/@data:ItemGroupDataSeq
let $testvalue2 := $precrecord/odm:ItemData[@ItemOID=$testoid]/@Value
let $recnum2 := $precrecord/@data:ItemGroupDataSeq
(: when the value of--TEST in both records is different, report an error :)
where not($testvalue2 = $testvalue)
return <error rule="FDAC085" dataset="{data($name)}" variable="{data($testcdname)}" rulelastupdate="2016-03-24" recordnumber="{data($recnum)}">Inconsistent value for {data($testname)} within {data($testcdname)}={data($testcdvalue)} in dataset {data($datasetname)}. Following values were found: record number {data($recnum2)}: {data($testname)}='{data($testvalue2)}' - record number {data($recnum)}: {data($testname)}='{data($testvalue)}'</error>
Inconsistent value for --TEST within --TESTCD, single dataset or domain - All values of Name of Measurement, Test or Examination (--TEST) should be the same for a given value of Short Name of Measurement, Test or Examination (--TESTCD)
FINDINGS
(: Rule FDAC085 - Inconsistent value for --TEST within --TESTCD
All values of Name of Measurement, Test or Examination (--TEST) should be the same for a given value of Short Name of Measurement, Test or Examination (--TESTCD)
:)
(: NEW: made this considerably faster using "GROUP BY" :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
declare variable $domain external;
(: let $base := '/db/fda_submissions/cdiscpilot01/' :)
(: let $define := 'define_2_0.xml' :)
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all datasets that have --TESTCD and --TEST :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name=$domain or @Domain=$domain]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: and get the OID of --TESTCD and --TEST :)
let $testcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TESTCD')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $testcdname := doc(concat($base,$define))//odm:ItemDef[@OID=$testcdoid]/@Name
let $testoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TEST')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $testname := doc(concat($base,$define))//odm:ItemDef[@OID=$testoid]/@Name
(: Group the records by the value of --TESTCD :)
let $orderedrecords := (
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$testcdoid]]
group by
$b:=$record/odm:ItemData[@ItemOID=$testcdoid]/@Value
return element group {
$record
}
)
(: all the records in the same group have the same value for --TESTCD.
They must also all have the same value for --TEST :)
for $group in $orderedrecords
let $testcdvalue := $group/odm:ItemGroupData[1]/odm:ItemData[@ItemOID=$testcdoid]/@Value
for $record in $group/odm:ItemGroupData[position()>1] (: start from the second one :)
let $recnum := $record/@data:ItemGroupDataSeq
let $testvalue := $record/odm:ItemData[@ItemOID=$testoid]/@Value
(: take the previous record in the same group, and take its --TEST value :)
let $precrecord := $record/preceding-sibling::odm:ItemGroupData[1] (: as they come in descending order :)
let $recnum2 := $precrecord/@data:ItemGroupDataSeq
let $testvalue2 := $precrecord/odm:ItemData[@ItemOID=$testoid]/@Value
let $recnum2 := $precrecord/@data:ItemGroupDataSeq
(: when the value of--TEST in both records is different, report an error :)
where not($testvalue2 = $testvalue)
return <error rule="FDAC085" dataset="{data($name)}" variable="{data($testcdname)}" rulelastupdate="2016-03-24" recordnumber="{data($recnum)}">Inconsistent value for {data($testname)} within {data($testcdname)}={data($testcdvalue)} in dataset {data($datasetname)}. Following values were found: record number {data($recnum2)}: {data($testname)}='{data($testvalue2)}' - record number {data($recnum)}: {data($testname)}='{data($testvalue)}'</error>
Inconsistent value for --TESTCD within --TEST - All values of Short Name of Measurement, Test or Examination (--TESTCD) should be the same for a given value of Name of Measurement, Test or Examination (--TEST)
FINDINGS
(: Rule FDAC086 - Inconsistent value for --TESTCD within --TEST
All values of Short Name of Measurement, Test or Examination (--TESTCD) should be the same for a given value of Name of Measurement, Test or Examination (--TEST)
:)
(: NEW: made this considerably faster using "GROUP BY" :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdiscpilot01/' :)
(: let $define := 'define_2_0.xml' :)
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all datasets that have --TESTCD and --TEST :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: and get the OID of --TESTCD and --TEST :)
let $testcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TESTCD')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $testcdname := doc(concat($base,$define))//odm:ItemDef[@OID=$testcdoid]/@Name
let $testoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TEST')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $testname := doc(concat($base,$define))//odm:ItemDef[@OID=$testoid]/@Name
(: Group the records by the value of --TEST :)
let $orderedrecords := (
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$testoid]]
group by
$b:=$record/odm:ItemData[@ItemOID=$testoid]/@Value
return element group {
$record
}
)
(: all the records in the same group have the same value for --TEST.
They must also all have the same value for --TESTCD :)
for $group in $orderedrecords
let $testvalue := $group/odm:ItemGroupData[1]/odm:ItemData[@ItemOID=$testoid]/@Value
for $record in $group/odm:ItemGroupData[position()>1] (: start from the second one :)
let $recnum := $record/@data:ItemGroupDataSeq
let $testcdvalue := $record/odm:ItemData[@ItemOID=$testcdoid]/@Value
(: take the previous record in the same group, and take its --TESTCD value :)
let $precrecord := $record/preceding-sibling::odm:ItemGroupData[1] (: as they come in descending order :)
let $recnum2 := $precrecord/@data:ItemGroupDataSeq
let $testcdvalue2 := $precrecord/odm:ItemData[@ItemOID=$testcdoid]/@Value
let $recnum2 := $precrecord/@data:ItemGroupDataSeq
(: when the value of--TESTCD in both records is different, report an error :)
where not($testcdvalue2 = $testcdvalue)
return <error rule="FDAC086" dataset="{data($name)}" variable="{data($testname)}" rulelastupdate="2016-03-24" recordnumber="{data($recnum)}">Inconsistent value for {data($testcdname)} within {data($testname)}='{data($testvalue)}' in dataset {data($datasetname)}. Following values were found: record number {data($recnum2)}: {data($testcdname)}={data($testcdvalue2)} - record number {data($recnum)}: {data($testcdname)}={data($testcdvalue)}</error>
Inconsistent value for --TESTCD within --TEST, single dataset or domain - All values of Short Name of Measurement, Test or Examination (--TESTCD) should be the same for a given value of Name of Measurement, Test or Examination (--TEST)
FINDINGS
(: Rule FDAC086 - Inconsistent value for --TESTCD within --TEST
All values of Short Name of Measurement, Test or Examination (--TESTCD) should be the same for a given value of Name of Measurement, Test or Examination (--TEST)
:)
(: NEW: made this considerably faster using "GROUP BY" :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
declare variable $domain external;
(: let $base := '/db/fda_submissions/cdiscpilot01/' :)
(: let $define := 'define_2_0.xml' :)
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all datasets that have --TESTCD and --TEST :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name=$domain or @Domain=$domain]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: and get the OID of --TESTCD and --TEST :)
let $testcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TESTCD')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $testcdname := doc(concat($base,$define))//odm:ItemDef[@OID=$testcdoid]/@Name
let $testoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TEST')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $testname := doc(concat($base,$define))//odm:ItemDef[@OID=$testoid]/@Name
(: Group the records by the value of --TEST :)
let $orderedrecords := (
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$testoid]]
group by
$b:=$record/odm:ItemData[@ItemOID=$testoid]/@Value
return element group {
$record
}
)
(: all the records in the same group have the same value for --TEST.
They must also all have the same value for --TESTCD :)
for $group in $orderedrecords
let $testvalue := $group/odm:ItemGroupData[1]/odm:ItemData[@ItemOID=$testoid]/@Value
for $record in $group/odm:ItemGroupData[position()>1] (: start from the second one :)
let $recnum := $record/@data:ItemGroupDataSeq
let $testcdvalue := $record/odm:ItemData[@ItemOID=$testcdoid]/@Value
(: take the previous record in the same group, and take its --TESTCD value :)
let $precrecord := $record/preceding-sibling::odm:ItemGroupData[1] (: as they come in descending order :)
let $recnum2 := $precrecord/@data:ItemGroupDataSeq
let $testcdvalue2 := $precrecord/odm:ItemData[@ItemOID=$testcdoid]/@Value
let $recnum2 := $precrecord/@data:ItemGroupDataSeq
(: when the value of--TESTCD in both records is different, report an error :)
where not($testcdvalue2 = $testcdvalue)
return <error rule="FDAC086" dataset="{data($name)}" variable="{data($testname)}" rulelastupdate="2016-03-24" recordnumber="{data($recnum)}">Inconsistent value for {data($testcdname)} within {data($testname)}='{data($testvalue)}' in dataset {data($datasetname)}. Following values were found: record number {data($recnum2)}: {data($testcdname)}={data($testcdvalue2)} - record number {data($recnum)}: {data($testcdname)}={data($testcdvalue)}</error>
Inconsistent value for --PARM within --PARMCD - All values of a Parameter (--PARM) variables should be the same for a given value of a Parameter Short Name (--PARMCD) variables - TS domain
TS
(: Rule FDAC087 - Inconsistent value for --PARM within --PARMCD:
All values of a Parameter (--PARM) variables should be the same for a given value of a Parameter Short Name (--PARMCD) variables - TS domain
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Remark that rules FDAC087 and FDAC088 could easily be combined into a single rule :)
(: iterate over all TS datasets in the define.xml -
usually there will be only one :)
for $itemgroup in doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
(: get the dataset name and location :)
let $datasetname := $itemgroup/def:leaf/@xlink:href
let $dataset := concat($base,$datasetname)
(: we need the OID of the TSPARMCD and TSPARM variables :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = $itemgroup/odm:ItemRef/@ItemOID
return $a
)
let $tsparmoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARM']/@OID
where $a = $itemgroup/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records in the TS dataset
where both TSPARMCD AND TSPARM are present -
this should essentially be the case for all records :)
for $record in doc($dataset)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid] and odm:ItemData[@ItemOID=$tsparmoid]]
let $recnum := $record/@data:ItemGroupDataSeq
let $tsparmcdvalue1 := $record/odm:ItemData[@ItemOID=$tsparmcdoid]/@Value
let $tsparmvalue1 := $record/odm:ItemData[@ItemOID=$tsparmoid]/@Value
(: iterate over all following records having the same value for TSPARMCD:)
for $record2 in doc($dataset)//odm:ItemGroupData[@data:ItemGroupDataSeq>$recnum][odm:ItemData[@ItemOID=$tsparmcdoid and @Value=$tsparmcdvalue1]]
let $recnum2 := $record2/@data:ItemGroupDataSeq
(: let $tsparmcdvalue2 := $record/odm:ItemData[@ItemOID=$tsparmcdoid]/@Value :)
let $tsparmvalue2 := $record2/odm:ItemData[@ItemOID=$tsparmoid]/@Value
(: and compare the values - both must be equal :)
where not($tsparmvalue1=$tsparmvalue2)
return <warning rule="FDAC087" dataset="TS" variable="TSPARM" rulelastupdate="2015-08-15" recordnumber="{data($recnum2)}">Inconsistent value for --PARM within --PARMCD: both records {data($recnum)} and {data($recnum2)} have --PARMCD='{data($tsparmcdvalue1)}' but the values for --PARM '{data($tsparmvalue1)}' and '{data($tsparmvalue2)}' are different</warning>
Inconsistent value for --PARMCD within --PARM - All values of a Parameter Short Name (--PARMCD) variables should be the same for a given value of a Parameter (--PARM) variables
TS
(: Rule FDAC088 - Inconsistent value for --PARMCD within --PARM:
All values of a Parameter Short Name (--PARMCD) variables should be the same for a given value of a Parameter (--PARM) variables - TS domain
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Remark that rules FDAC087 and FDAC088 could easily be combined into a single rule :)
(: iterate over all TS datasets in the define.xml -
usually there will be only one :)
for $itemgroup in doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
(: get the dataset name and location :)
let $datasetname := $itemgroup/def:leaf/@xlink:href
let $dataset := concat($base,$datasetname)
(: we need the OID of the TSPARMCD and TSPARM variables :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = $itemgroup/odm:ItemRef/@ItemOID
return $a
)
let $tsparmoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARM']/@OID
where $a = $itemgroup/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records in the TS dataset
where both TSPARMCD AND TSPARM are present -
this should essentially be the case for all records :)
for $record in doc($dataset)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid] and odm:ItemData[@ItemOID=$tsparmoid]]
let $recnum := $record/@data:ItemGroupDataSeq
let $tsparmcdvalue1 := $record/odm:ItemData[@ItemOID=$tsparmcdoid]/@Value
let $tsparmvalue1 := $record/odm:ItemData[@ItemOID=$tsparmoid]/@Value
(: iterate over all following records having the same value for TSPARM:)
for $record2 in doc($dataset)//odm:ItemGroupData[@data:ItemGroupDataSeq>$recnum][odm:ItemData[@ItemOID=$tsparmoid and @Value=$tsparmvalue1]]
let $recnum2 := $record2/@data:ItemGroupDataSeq
let $tsparmcdvalue2 := $record2/odm:ItemData[@ItemOID=$tsparmcdoid]/@Value
(: and compare the values - both must be equal :)
where not($tsparmcdvalue1=$tsparmcdvalue2)
return <warning rule="FDAC088" dataset="TS" variable="TSPARMCD" rulelastupdate="2015-08-15" recordnumber="{data($recnum2)}">Inconsistent value for --PARMCD within --PARM: both records {data($recnum)} and {data($recnum2)} have --PARM='{data($tsparmvalue1)}' but the values for --PARMCD '{data($tsparmcdvalue1)}' and '{data($tsparmcdvalue2)}' are different</warning>
Inconsistent value for QLABEL within QNAM - All values of Qualifier Variable Label (QLABEL) should be the same for a given value of Qualifier Variable Name (QNAM)
SUPPQUAL
(: Rule FDAC089 - Inconsistent value for QLABEL within QNAM
All values of Qualifier Variable Label (QLABEL) should be the same for a given value of Qualifier Variable Name (QNAM) in SUPPxx
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Iterate over all SUPPxx datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[starts-with(@Name,'SUPP')]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: and get the OID of QLABEL and of QNAM :)
let $qlabeloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='QLABEL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $qnamoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='QNAM']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: get all unique QNAM values within the dataset :)
let $uniqueqnamvalues := distinct-values(doc($datasetlocation)//odm:ItemGroupData/odm:ItemData[@ItemOID=$qnamoid]/@Value)
(: iterate over these unique QNAM values and for each of them,
find all records - also all with the same value for QNAM :)
for $uniqueqnam in $uniqueqnamvalues
let $records := doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$qnamoid][@Value=$uniqueqnam]]
(: now get the distinct values for QLABEL within each QNAM :)
let $uniqueqlabelvalues := distinct-values($records/odm:ItemData[@ItemOID=$qlabeloid]/@Value)
(: the number of unique QLABEL values for each QNAM must be 1 :)
let $uniqueqlabelvaluescount := count($uniqueqlabelvalues)
where $uniqueqlabelvaluescount != 1
return <warning rule="FDAC089" dataset="{data($name)}" variable="QLABEL" rulelastupdate="2015-02-10">Inconsistent value for QLABEL within QNAM={data($uniqueqnam)} in dataset {data($datasetname)}. {data($uniqueqlabelvaluescount)} different combinations were found</warning>
Inconsistent value for QNAM within QLABEL - All values of Qualifier Variable Name (QNAM) should be the same for a given value of Qualifier Variable Label (QLABEL)
SUPPQUAL
(: Rule FDAC090 - Inconsistent value for QNAM within QLABEL
All values of Qualifier Variable Name (QNAM) should be the same for a given value of Qualifier Variable Label (QLABEL)
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Iterate over all SUPPxx datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[starts-with(@Name,'SUPP')]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: and get the OID of QLABEL and of QNAM :)
let $qlabeloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='QLABEL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $qnamoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='QNAM']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: get all unique QLABEL values within the dataset :)
let $uniqueqlabelvalues := distinct-values(doc($datasetlocation)//odm:ItemGroupData/odm:ItemData[@ItemOID=$qlabeloid]/@Value)
(: iterate over these unique QLABEL values and for each of them,
find all records - also all with the same value for QLABEL :)
for $uniqueqlabel in $uniqueqlabelvalues
let $records := doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$qlabeloid][@Value=$uniqueqlabel]]
(: now get the distinct values for QNAM within each QLABEL :)
let $uniqueqnamvalues := distinct-values($records/odm:ItemData[@ItemOID=$qnamoid]/@Value)
(: the number of unique QNAM values for each QLABEL must be 1 :)
let $uniqueqnamvaluescount := count($uniqueqnamvalues)
where $uniqueqnamvaluescount != 1
return <warning rule="FDAC090" dataset="{data($name)}" variable="QNAM" rulelastupdate="2015-02-10">Inconsistent value for QNAM within QLABEL={data($uniqueqlabel)} in dataset {data($datasetname)}. {data($uniqueqnamvaluescount)} different combinations were found</warning>
Inconsistent value for VISIT within VISITNUM - All values of Visit Name (VISIT) should be the same for a given value of Visit Number (VISITNUM) in domains TV and SV
SV
TV
(: Rule FDAC091 - Inconsistent value for VISIT within VISITNUM
All values of Visit Name (VISIT) should be the same for a given value of Visit Number (VISITNUM) in domains TV and SV
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Iterate over the TV and VS datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name='TV' or @Name='SV']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: and get the OID of VISITNUM and VISIT :)
let $visitnumoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='VISITNUM']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $visitoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='VISIT']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: get all unique VISITNUM values within the dataset :)
let $uniquevisitnumvalues := distinct-values(doc($datasetlocation)//odm:ItemGroupData/odm:ItemData[@ItemOID=$visitnumoid]/@Value)
(: iterate over these unique VISITNUM values and for each of them, find all records - also all with the same value for VISITNUM :)
for $uniquevisitnum in $uniquevisitnumvalues
let $records := doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$visitnumoid][@Value=$uniquevisitnum]]
(: now get the distinct values for VISIT within each VISITNUM :)
let $uniquevisitvalues := distinct-values($records/odm:ItemData[@ItemOID=$visitoid]/@Value)
(: the number of unique VISIT values for each VISITNUM must be 1 :)
let $uniquevisitvaluescount := count($uniquevisitvalues)
where $uniquevisitvaluescount != 1
return <error rule="FDAC091" dataset="{data($name)}" variable="VISIT" rulelastupdate="2015-02-10">Inconsistent value for VISIT within VISITNUM={data($uniquevisitnum)} in dataset {data($datasetname)}. {data($uniquevisitvaluescount)} different combinations were found</error>
Inconsistent value for VISITNUM within VISIT - All values of Visit Number (VISITNUM) should be the same for a given value of Visit Name (VISIT)
SV
TV
(: Rule FDAC092 - Inconsistent value for VISITNUM within VISIT
All values of Visit Number (VISITNUM) should be the same for a given value of Visit Name (VISIT)
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Iterate over the TV and VS datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name='TV' or @Name='SV']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: and get the OID of VISITNUM and VISIT :)
let $visitnumoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='VISITNUM']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $visitoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='VISIT']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: get all unique VISIT values within the dataset :)
let $uniquevisitvalues := distinct-values(doc($datasetlocation)//odm:ItemGroupData/odm:ItemData[@ItemOID=$visitoid]/@Value)
(: iterate over these unique VISIT values and for each of them, find all records - also all with the same value for VISIT :)
for $uniquevisit in $uniquevisitvalues
let $records := doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$visitoid][@Value=$uniquevisit]]
(: now get the distinct values for VISIT within each VISITNUM :)
let $uniquevisitnumvalues := distinct-values($records/odm:ItemData[@ItemOID=$visitnumoid]/@Value)
(: the number of unique VISITNUM values for each VISIT must be 1 :)
let $uniquevisitnumvaluescount := count($uniquevisitnumvalues)
where $uniquevisitnumvaluescount != 1
return <error rule="FDAC092" dataset="{data($name)}" variable="VISITNUM" rulelastupdate="2015-02-10">Inconsistent value for VISITNUM within VISIT={data($uniquevisit)} in dataset {data($datasetname)}. {data($uniquevisitnumvaluescount)} different combinations were found</error>
Inconsistent value for ARM - A value for Description of Planned Arm (ARM) must have a unique value for Planned Arm Code (ARMCD) with the domain DM, TA, TV
DM
TA
TV
(: Rule FDAC093 - Inconsistent value for ARM:
A value for Description of Planned Arm (ARM) must have a unique value for Planned Arm Code (ARMCD) with the domain DM, TA, TV
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Iterate over the DM, TA and TV datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM' or @Name='TA' or @Name='TV']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: and get the OID of ARMCD and ARM :)
let $armcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $armoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ARM']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: get all unique ARMCD values within the dataset :)
let $uniquearmcdvalues := distinct-values(doc($datasetlocation)//odm:ItemGroupData/odm:ItemData[@ItemOID=$armcdoid]/@Value)
(: iterate over these unique ARMCD values and for each of them, find all records - also all with the same value for ARMCD:)
for $uniquearmcd in $uniquearmcdvalues
let $records := doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$armcdoid][@Value=$uniquearmcd]]
(: now get the distinct values for ARM within each ARMCD :)
let $uniquearmvalues := distinct-values($records/odm:ItemData[@ItemOID=$armoid]/@Value)
(: the number of unique ARM values for each ARMCD must be 1 :)
let $uniquearmvaluescount := count($uniquearmvalues)
where $uniquearmvaluescount != 1
return <error rule="FDAC093" dataset="{data($name)}" variable="ARM" rulelastupdate="2015-02-10">Inconsistent value for ARM within ARMCD={data($uniquearmcd)} in dataset {data($datasetname)}. {data($uniquearmvaluescount)} different combinations were found</error>
Inconsistent value for ARMCD - A value for Planned Arm Code (ARMCD) must have a unique value for Description of Planned Arm (ARM) with the domain within the domain DM, TA, TV
DM
TA
TV
(: Rule FDAC094 - Inconsistent value for ARMCD
A value for Planned Arm Code (ARMCD) must have a unique value for Description of Planned Arm (ARM) with the domain within the domain DM, TA, TV
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Iterate over the TV and VS datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM' or @Name='TA' or @Name='TV']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: and get the OID of ARMCD and ARM :)
let $armcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $armoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ARM']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: get all unique ARM values within the dataset :)
let $uniquearmvalues := distinct-values(doc($datasetlocation)//odm:ItemGroupData/odm:ItemData[@ItemOID=$armoid]/@Value)
(: iterate over these unique ARM values and for each of them, find all records - also all with the same value for ARM :)
for $uniquearm in $uniquearmvalues
let $records := doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$armoid][@Value=$uniquearm]]
(: now get the distinct values for ARMCD within each ARM :)
let $uniquearmcdvalues := distinct-values($records/odm:ItemData[@ItemOID=$armcdoid]/@Value)
(: the number of unique ARMCD values for each ARM must be 1 :)
let $uniquearmcdvaluescount := count($uniquearmcdvalues)
where $uniquearmcdvaluescount != 1
return <error rule="FDAC094" dataset="{data($name)}" variable="ARMCD" rulelastupdate="2015-02-10">Inconsistent value for ARMCD within ARM={data($uniquearm)} in dataset {data($datasetname)}. {data($uniquearmcdvaluescount)} different combinations were found</error>
Inconsistent values for IEORRES/IECAT - I/E Criterion Original Result (IEORRES) must equal 'Y', when Inclusion/Exclusion Category (IECAT) is 'EXCLUSION'
IE
(: Rule FDAC095 - Inconsistent values for IEORRES/IECAT:
I/E Criterion Original Result (IEORRES) must equal 'Y', when Inclusion/Exclusion Category (IECAT) is 'EXCLUSION'
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the IE dataset :)
let $iedataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name="IE"]
let $iedatasetname := $iedataset/def:leaf/@xlink:href
let $iedatasetlocation := concat($base,$iedatasetname)
(: and get the OID of the IEORRES and IECAT variables :)
let $ieorresoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='IEORRES']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='IE']/odm:ItemRef/@ItemOID
return $a
)
let $iecatoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='IECAT']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='IE']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records in the IE dataset :)
for $record in doc($iedatasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the values for IEORRES and IECAT :)
let $ieorresvalue := $record/odm:ItemData[@ItemOID=$ieorresoid]/@Value
let $iecatvalue := $record/odm:ItemData[@ItemOID=$iecatoid]/@Value
(: in case that IECAT=EXCLUSION, IEORRES MUST be Y :)
where $iecatvalue='EXCLUSION' and not($ieorresvalue='Y')
return <error rule="FDAC095" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}" dataset="IE" variable="IEORRES">Inconsistent values for IEORRES/IECAT. For IECAT=EXCLUSION, IEORRES must be 'Y' but {data($ieorresvalue)} was found</error>
Inconsistent values for IEORRES/IECAT - I/E Criterion Original Result (IEORRES) must equal 'N', when Inclusion/Exclusion Category (IECAT) is 'INCLUSION'
IE
(: Rule FDAC096 - Inconsistent values for IEORRES/IECAT:
I/E Criterion Original Result (IEORRES) must equal 'N', when Inclusion/Exclusion Category (IECAT) is 'INCLUSION'
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the IE dataset :)
let $iedataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name="IE"]
let $iedatasetname := $iedataset/def:leaf/@xlink:href
let $iedatasetlocation := concat($base,$iedatasetname)
(: and get the OID of the IEORRES and IECAT variables :)
let $ieorresoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='IEORRES']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='IE']/odm:ItemRef/@ItemOID
return $a
)
let $iecatoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='IECAT']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='IE']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records in the IE dataset :)
for $record in doc($iedatasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the values for IEORRES and IECAT :)
let $ieorresvalue := $record/odm:ItemData[@ItemOID=$ieorresoid]/@Value
let $iecatvalue := $record/odm:ItemData[@ItemOID=$iecatoid]/@Value
(: in case that IECAT=INCLUSION, IEORRES MUST be N :)
where $iecatvalue='INCLUSION' and not($ieorresvalue='N')
return <error rule="FDAC096" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}" dataset="IE" variable="IEORRES">Inconsistent values for IEORRES/IECAT. For IECAT=INCLUSION, IEORRES must be 'N' but {data($ieorresvalue)} was found</error>
ARM is not 'Screen Failure', when ARMCD equals 'SCRNFAIL', or vice versa - Description of Arm (ARM) must equal 'Screen Failure', when Arm Code (ARMCD) is 'SCRNFAIL', and vice versa
ALL
(: Rule FDAC097 - ARM is not 'Screen Failure', when ARMCD equals 'SCRNFAIL', or vice versa:
Description of Arm (ARM) must equal 'Screen Failure', when Arm Code (ARMCD) is 'SCRNFAIL', and vice versa
ATTENTION: FDA rule does NOT say anything about case sensitiveness
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the DM and TA dataset :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM' or @Name='TA']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation:= concat($base,$datasetname)
(: and get the OIDs of ARMCD and ARM :)
let $armcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $armoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ARM']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records in the dataset :)
for $record in doc($datasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the values for ARMCD and ARM :)
let $armcdvalue := $record/odm:ItemData[@ItemOID=$armcdoid]/@Value
let $armvalue := $record/odm:ItemData[@ItemOID=$armoid]/@Value
(: in case that ARMCD=SCRNFAIL then ARM must be 'Screen Failure' and vice versa - CASE SENSITIVE :)
where ($armcdvalue='SCRNFAIL' and not($armvalue='Screen Failure')) or ($armvalue='Screen Failure' and not($armcdvalue='SCRNFAIL'))
(: and give out an error message :)
return <error rule="FDAC097" dataset="{data($name)}" variable="ARM" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">ARM is not 'Screen Failure', when ARMCD equals 'SCRNFAIL', or vice versa. ARMCD={data($armcdvalue)} with ARM={data($armvalue)} was found</error>
ARM is not 'Not Assigned', when ARMCD equals 'NOTASSGN', or vice versa - Description of Arm (ARM) must equal 'Not Assigned', when Arm Code (ARMCD) is 'NOTASSGN', and vice versa
DM
TA
(: Rule FDAC098 - ARM is not 'Not Assigned', when ARMCD equals 'NOTASSGN', or vice versa
Description of Arm (ARM) must equal 'Not Assigned', when Arm Code (ARMCD) is 'NOTASSGN', and vice versa
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the DM and TA dataset :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM' or @Name='TA']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation:= concat($base,$datasetname)
(: and get the OIDs of ARMCD and ARM :)
let $armcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $armoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ARM']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records in the dataset :)
for $record in doc($datasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the values for ARMCD and ARM :)
let $armcdvalue := $record/odm:ItemData[@ItemOID=$armcdoid]/@Value
let $armvalue := $record/odm:ItemData[@ItemOID=$armoid]/@Value
(: in case that ARMCD=NOTASSGN then ARM must be 'Not Assigned' and vice versa - CASE SENSITIVE :)
where ($armcdvalue='NOTASSGN' and not($armvalue='Not Assigned')) or ($armvalue='Not Assigned' and not($armcdvalue='NOTASSGN'))
(: and give out an error message :)
return <error rule="FDAC098" dataset="{data($name)}" variable="ARM" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">ARM is not 'Not Assigned', when ARMCD equals 'NOTASSGN', or vice versa. ARMCD={data($armcdvalue)} with ARM={data($armvalue)} was found</error>
Inconsistent value for --TPT within --ELTM - All values of Planned Elapsed Time (--ELTM) variable should be the same for a given value of Planned Time Point Name (--TPT) variable
INTERVENTIONS
EVENTS
FINDINGS
(: Rule FDAC099 - Inconsistent value for --TPT within --ELTM
All values of Planned Elapsed Time (--ELTM) variable should be the same for a given value of Planned Time Point Name (--TPT) variable (Interventions, Findings, Events)
OR: there is a 1:1 relationship
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation:= concat($base,$datasetname)
(: and get the OIDs of --TPT and --ELTM :)
let $tptoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TPT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $tptname := doc(concat($base,$define))//odm:ItemDef[@OID=$tptoid]/@Name
let $eltmoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ELTM')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $eltmname := doc(concat($base,$define))//odm:ItemDef[@OID=$eltmoid]/@Name
(: Get all unique values of --TPT :)
let $tptuniquevalues := distinct-values(doc($datasetlocation)//odm:ItemGroupData/odm:ItemData[@ItemOID=$tptoid]/@Value)
(: iterate over the unique values and get the records :)
for $tptuniquevalue in $tptuniquevalues
(: get all the records :)
let $uniquetptrecords := doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tptoid][@Value=$tptuniquevalue]]
let $uniquetptrecordcount := count($uniquetptrecords)
(: get the unique values for ELTM within each of the unique TPT values, and count them :)
let $uniqueeltmvalues := distinct-values($uniquetptrecords/odm:ItemData[@ItemOID=$eltmoid]/@Value)
let $uniqueeltmvaluescount := count($uniqueeltmvalues)
(: the value of the count of unique ELTM values for each TPT must be 1 :)
where not($uniqueeltmvaluescount = 1)
return <warning rule="FDAC099" dataset="{data($name)}" variable="{data(eltmname)}" rulelastupdate="2015-02-10">Inconsistent value for {data($eltmname)} within {data($tptname)} in dataset {data($datasetname)}. {data($uniqueeltmvaluescount)} different {data($eltmname)} values were found for {data($tptname)}={data($tptuniquevalue)}</warning>
Inconsistent value for --TPT within --TPTNUM - All values of Planned Time Point Name (--TPT) variable should be the same for a given value of Planned Time Point Number (--TPTNUM) variable
INTERVENTIONS
EVENTS
FINDINGS
(: Rule FDAC100 - Inconsistent value for --TPT within --TPTNUM
All values of Planned Time Point Name (--TPT) variable should be the same for a given value of Planned Time Point Number (--TPTNUM) variable
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation:= concat($base,$datasetname)
(: and get the OIDs of --TPT and --TPTNUM :)
let $tptoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TPT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $tptname := doc(concat($base,$define))//odm:ItemDef[@OID=$tptoid]/@Name
let $tptnumoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TPTNUM')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $tptnumname := doc(concat($base,$define))//odm:ItemDef[@OID=$tptnumoid]/@Name
(: Get all unique values of --TPTNUM :)
let $tptnumuniquevalues := distinct-values(doc($datasetlocation)//odm:ItemGroupData/odm:ItemData[@ItemOID=$tptnumoid]/@Value)
(: iterate over the unique TPTNUM values and get the records :)
for $tptnumuniquevalue in $tptnumuniquevalues
(: get all the records :)
let $uniquetptnumrecords := doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tptnumoid][@Value=$tptnumuniquevalue]]
(: get the unique values for TPT within each of the unique TPTNUM values, and count them :)
let $uniquetptvalues := distinct-values($uniquetptnumrecords/odm:ItemData[@ItemOID=$tptoid]/@Value)
let $uniquetptvaluescount := count($uniquetptvalues)
(: the value of the count of unique TPT values for each TPTNUM must be 1 :)
where not($uniquetptvaluescount = 1)
return <warning rule="FDAC100" dataset="{data($name)}" variable="{data(tptname)}" rulelastupdate="2015-02-10">Inconsistent value for {data($tptname)} within {data($tptnumname)} in dataset {data($datasetname)}. {data($uniquetptvaluescount)} different {data($tptname)} values were found for {data($tptnumname)}={data($tptnumuniquevalue)}</warning>
Inconsistent value for --TPTNUM within --TPT - All values of Planned Time Point Number (--TPTNUM) variable should be the same for a given value of Planned Time Point Name (--TPT) variable
INTERVENTION
FINDING
EVENTS
(: Rule FDAC101 - Inconsistent value for --TPTNUM within --TPT:
All values of Planned Time Point Number (--TPTNUM) variable should be the same for a given value of Planned Time Point Name (--TPT) variable :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation:= concat($base,$datasetname)
(: and get the OIDs of --TPT and --TPTNUM :)
let $tptoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TPT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $tptname := doc(concat($base,$define))//odm:ItemDef[@OID=$tptoid]/@Name
let $tptnumoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TPTNUM')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $tptnumname := doc(concat($base,$define))//odm:ItemDef[@OID=$tptnumoid]/@Name
(: Get all unique values of --TPT :)
let $tptuniquevalues := distinct-values(doc($datasetlocation)//odm:ItemGroupData/odm:ItemData[@ItemOID=$tptoid]/@Value)
(: iterate over the unique TPTNUM values and get the records :)
for $tptuniquevalue in $tptuniquevalues
(: get all the records :)
let $uniquetptrecords := doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tptoid][@Value=$tptuniquevalue]]
(: get the unique values for TPTNUM within each of the unique TPT values, and count them :)
let $uniquetptnumvalues := distinct-values($uniquetptrecords/odm:ItemData[@ItemOID=$tptnumoid]/@Value)
let $uniquetptnumvaluescount := count($uniquetptnumvalues)
(: the value of the count of unique TPT values for each TPTNUM must be 1 :)
where not($uniquetptnumvaluescount = 1)
return <warning rule="FDAC101" dataset="{data($name)}" variable="{data($tptnumname)}" rulelastupdate="2015-02-10">Inconsistent value for {data($tptnumname)} within {data($tptname)} in dataset {data($datasetname)}. {data($uniquetptnumvaluescount)} different {data($tptnumname)} values were found for {data($tptname)}={data($tptuniquevalue)}</warning>
Mismatch between IEORRES and IESTRESC values - I/E Criterion Original Result (IEORRES) and I/E Criterion Result in Std Format (IESTRESC) should have the same value
IE
(: Rule FDAC102 - Mismatch between IEORRES and IESTRESC values
I/E Criterion Original Result (IEORRES) and I/E Criterion Result in Std Format (IESTRESC) should have the same value
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the IE data :)
let $iedataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='IE']
let $iedatasetname := $iedataset/def:leaf/@xlink:href
let $iedatasetlocation := concat($base,$iedatasetname)
(: and the OID of the USUBJID in the IE dataset :)
let $ieusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='IE']/odm:ItemRef/@ItemOID
return $a
)
(: as well as the OIDs of IEORRES and IESTRESC :)
let $ieorresoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='IEORRES']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='IE']/odm:ItemRef/@ItemOID
return $a
)
let $iestrescoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='IESTRESC']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='IE']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records in the IE dataset :)
for $record in doc($iedatasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
let $usubjid := $record/odm:ItemData[@ItemOID=$ieusubjidoid]/@Value
let $ieorres := $record/odm:ItemData[@ItemOID=$ieorresoid]/@Value
let $iestresc := $record/odm:ItemData[@ItemOID=$iestrescoid]/@Value
(: value for IEORRES and IESTRESC must be equal :)
where not($ieorres = $iestresc)
return <warning rule="FDAC102" dataset="IE" variable="IESTRESC" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">Mismatch between IEORRES and IESTRESC values for USUBJID={data($usubjid)}. IEORRES found is {data($ieorres)}, whereas IESTRESC found is {data($iestresc)}</warning>
No records for 'SCRNFAIL' subject are found in IE domain - All subjects with Planned Arm Code (ARMCD) equals 'SCRNFAIL' should have records in the Inclusion/Exclusion Criteria Not Met (IE) domain
IE
DM
(: Rule FDAC103 - No records for 'SCRNFAIL' subject are found in IE domain:
All subjects with Planned Arm Code (ARMCD) equals 'SCRNFAIL' should have records in the Inclusion/Exclusion Criteria Not Met (IE) domain
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all records in the DM datasets :)
let $dmdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']
let $dmdatasetname := $dmdataset/def:leaf/@xlink:href
let $dmdatasetlocation:= concat($base,$dmdatasetname)
(: and get the OIDs of USUBJID and ARMCD :)
let $usubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
let $armcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: Get the IE data :)
let $iedataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='IE']
let $iedatasetname := $iedataset/def:leaf/@xlink:href
let $iedatasetlocation := concat($base,$iedatasetname)
(: and the OID of the USUBJID in the IE dataset :)
let $ieusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='IE']/odm:ItemRef/@ItemOID
return $a
)
(: get the records for which ARMCD=SCRNFAIL :)
for $record in doc($dmdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$armcdoid][@Value='SCRNFAIL']]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the USUBJID of this record :)
let $dmusubjid := $record/odm:ItemData[@ItemOID=$usubjidoid]/@Value
(: and count the number of records for this subject in the IE dataset :)
let $ierecordcount := count(doc($iedatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$ieusubjidoid][@Value=$dmusubjid]])
(: there must be at least one record in IE :)
where $ierecordcount < 1
return <warning rule="FDAC103" dataset="DM" variable="ARMCD" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">No records for in IE dataset {data($iedatasetname)} for Screen Failure subject with USUBJID {data($dmusubjid)} </warning>
VISIT/VISITNUM values do not match TV domain data - Combination of Visit Name (VISIT) and Visit Number (VISITNUM) in subject-level domains should match that in the TV domain with the exception of Unscheduled and Unplanned visits
ALL
(: Rule FDAC105 - VISIT/VISITNUM values do not match TV domain data
Combination of Visit Name (VISIT) and Visit Number (VISITNUM) in subject-level domains should match that in the TV domain with the exception of Unscheduled and Unplanned visits
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the TV data :)
let $tvdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TV']
let $tvdatasetname := $tvdataset/def:leaf/@xlink:href
let $tvdatasetlocation := concat($base,$tvdatasetname)
(: and the OID of the VISIT and VISITNUM in TV dataset :)
let $tvvisitnumoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='VISITNUM']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TV']/odm:ItemRef/@ItemOID
return $a
)
let $tvvisitoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='VISIT']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TV']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all other datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[not(@Name='TV')]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OID of the VISITNUM and VISIT variables, if any :)
let $visitnumoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='VISITNUM']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $visitoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='VISIT']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records in the dataset that have a VISIT and VISITNUM data point :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$visitnumoid] and odm:ItemData[@ItemOID=$visitoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of VISIT and VISITNUM :)
let $visitnumvalue := $record/odm:ItemData[@ItemOID=$visitnumoid]/@Value
let $visitvalue := $record/odm:ItemData[@ItemOID=$visitoid]/@Value
(: and check whether there is such a value in TV, except when VISITNUM contains a "." (unplanned visit) :)
let $isunplannedvisit := contains($visitnumvalue,'.')
(: count the number of records in TV for this combination of VISIT and VISITNUM :)
let $recordsintv := doc($tvdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tvvisitnumoid][@Value=$visitnumvalue] and odm:ItemData[@ItemOID=$tvvisitoid][@Value=$visitvalue]]
let $recordsintvcount := count($recordsintv)
(: no records found and not an unplanned visit :)
where not($isunplannedvisit) and $recordsintvcount < 1
return <warning rule="FDAC105" dataset="{data($name)}" variable="VISITNUM" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">VISIT={data($visitvalue)}, VISITUM={data($visitnumvalue)} in dataset {data($datasetname)} does not match TV domain data in dataset TV</warning>
VISIT/VISITNUM values do not match TV domain data, single dataset or domain - Combination of Visit Name (VISIT) and Visit Number (VISITNUM) in subject-level domains should match that in the TV domain with the exception of Unscheduled and Unplanned visits
ALL
(: Rule FDAC105 - VISIT/VISITNUM values do not match TV domain data
Combination of Visit Name (VISIT) and Visit Number (VISITNUM) in subject-level domains should match that in the TV domain with the exception of Unscheduled and Unplanned visits
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
declare variable $domain external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the TV data :)
let $tvdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TV']
let $tvdatasetname := $tvdataset/def:leaf/@xlink:href
let $tvdatasetlocation := concat($base,$tvdatasetname)
(: and the OID of the VISIT and VISITNUM in TV dataset :)
let $tvvisitnumoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='VISITNUM']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TV']/odm:ItemRef/@ItemOID
return $a
)
let $tvvisitoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='VISIT']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TV']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all other datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[not(@Name='TV') and (@Name=$domain or @Domain=$domain)]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OID of the VISITNUM and VISIT variables, if any :)
let $visitnumoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='VISITNUM']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $visitoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='VISIT']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records in the dataset that have a VISIT and VISITNUM data point :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$visitnumoid] and odm:ItemData[@ItemOID=$visitoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of VISIT and VISITNUM :)
let $visitnumvalue := $record/odm:ItemData[@ItemOID=$visitnumoid]/@Value
let $visitvalue := $record/odm:ItemData[@ItemOID=$visitoid]/@Value
(: and check whether there is such a value in TV, except when VISITNUM contains a "." (unplanned visit) :)
let $isunplannedvisit := contains($visitnumvalue,'.')
(: count the number of records in TV for this combination of VISIT and VISITNUM :)
let $recordsintv := doc($tvdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tvvisitnumoid][@Value=$visitnumvalue] and odm:ItemData[@ItemOID=$tvvisitoid][@Value=$visitvalue]]
let $recordsintvcount := count($recordsintv)
(: no records found and not an unplanned visit :)
where not($isunplannedvisit) and $recordsintvcount < 1
return <warning rule="FDAC105" dataset="{data($name)}" variable="VISITNUM" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">VISIT={data($visitvalue)}, VISITUM={data($visitnumvalue)} in dataset {data($datasetname)} does not match TV domain data in dataset TV </warning>
--STDY is after --ENDY - Study Day of Start of Event, Exposure or Observation (--STDY) must be less or equal to Study Day of End of Event, Exposure or Observation (--ENDY)
INTERVENTIONS
EVENTS
FINDINGS
(: Rule FDAC106 - --STDY is after --ENDY
Study Day of Start of Event, Exposure or Observation (--STDY) must be less or equal to Study Day of End of Event, Exposure or Observation (--ENDY)
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all the datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OIDs of the --STDY and --ENDY variables :)
let $stdyoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STDY')]/@OID
where $a = $dataset/odm:ItemRef/@ItemOID
return $a
)
let $stdyname := doc(concat($base,$define))//odm:ItemDef[@OID=$stdyoid]/@Name
let $endyoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ENDY')]/@OID
where $a = $dataset/odm:ItemRef/@ItemOID
return $a
)
let $endyname := doc(concat($base,$define))//odm:ItemDef[@OID=$endyoid]/@Name
(: iterate over all the records for which STDY and ENDY are present :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$stdyoid] and odm:ItemData[@ItemOID=$endyoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the values :)
let $stdyvalue := $record/odm:ItemData[@ItemOID=$stdyoid]/@Value
let $endyvalue := $record/odm:ItemData[@ItemOID=$endyoid]/@Value
(: and compare the values :)
where $stdyvalue castable as xs:double and $endyvalue castable as xs:double and number($stdyvalue) > number($endyvalue)
return <error rule="FDAC106" dataset="{data($name)}" variable="{data($stdyname)}" rulelastupdate="2016-03-28" recordnumber="{data($recnum)}">{data($stdyname)}={data($stdyvalue)} is after {data($endyname)}={data($endyvalue)}</error>
--STDY is after --ENDY, single dataset or domain - Study Day of Start of Event, Exposure or Observation (--STDY) must be less or equal to Study Day of End of Event, Exposure or Observation (--ENDY)
INTERVENTIONS
EVENTS
FINDINGS
(: Rule FDAC106 - --STDY is after --ENDY
Study Day of Start of Event, Exposure or Observation (--STDY) must be less or equal to Study Day of End of Event, Exposure or Observation (--ENDY)
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
declare variable $domain external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all the datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name=$domain or @Domain=$domain]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OIDs of the --STDY and --ENDY variables :)
let $stdyoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STDY')]/@OID
where $a = $dataset/odm:ItemRef/@ItemOID
return $a
)
let $stdyname := doc(concat($base,$define))//odm:ItemDef[@OID=$stdyoid]/@Name
let $endyoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ENDY')]/@OID
where $a = $dataset/odm:ItemRef/@ItemOID
return $a
)
let $endyname := doc(concat($base,$define))//odm:ItemDef[@OID=$endyoid]/@Name
(: iterate over all the records for which STDY and ENDY are present :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$stdyoid] and odm:ItemData[@ItemOID=$endyoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the values :)
let $stdyvalue := $record/odm:ItemData[@ItemOID=$stdyoid]/@Value
let $endyvalue := $record/odm:ItemData[@ItemOID=$endyoid]/@Value
(: and compare the values :)
where $stdyvalue castable as xs:double and $endyvalue castable as xs:double and number($stdyvalue) > number($endyvalue)
return <error rule="FDAC106" dataset="{data($name)}" variable="{data($stdyname)}" rulelastupdate="2016-03-28" recordnumber="{data($recnum)}">{data($stdyname)}={data($stdyvalue)} is after {data($endyname)}={data($endyvalue)}</error>
--STDTC is after --ENDTC - Start Date/Time of Event, Exposure or Observation (--STDTC) must be less or equal to End Date/Time of Event, Exposure or Observation (--ENDTC)
ALL
(: Rule FDAC107 - --STDTC is after --ENDTC
Start Date/Time of Event, Exposure or Observation (--STDTC) must be less or equal to End Date/Time of Event, Exposure or Observation (--ENDTC)
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all the datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the prefix for STDTC and ENDTC from either the domain or the dataset name :)
let $prefix := if($dataset/@Domain) then $dataset/@Domain
else substring($name,1,2)
(: Get the OIDs of the --STDTC and --ENDTC variables :)
(: We must iterate over all xxSTDTC and xxxSTDTC and xxxxSTDTC :)
let $stdtcoids := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STDTC')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
for $stdtcoid in $stdtcoids
let $stdtcname := doc(concat($base,$define))//odm:ItemDef[@OID=$stdtcoid]/@Name
(: get the corresponding ENDTC :)
let $endtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name=replace($stdtcname,'STDTC','ENDTC')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $endtcname := doc(concat($base,$define))//odm:ItemDef[@OID=$endtcoid]/@Name
(: now iterate over all the records in the dataset that do have an SDTY AND ENDY variable :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$stdtcoid] and odm:ItemData[@ItemOID=$endtcoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the values :)
let $stdtcvalue := $record/odm:ItemData[@ItemOID=$stdtcoid]/@Value
let $endtcvalue := $record/odm:ItemData[@ItemOID=$endtcoid]/@Value
(: take care that both are datetime, as it can be that only one of the two is of datetime
and that the other is of type date, which would make them incomparable :)
(: first for --STDTC :)
let $stdtctestvalue :=
(: only the year is given :)
if(string-length($stdtcvalue) = 4) then concat($stdtcvalue,'-01-01T00:00:00')
(: only the month is given :)
else if(string-length($stdtcvalue) = 7) then concat($stdtcvalue,'-01T00:00:00')
(: complete date is given but no time :)
else if(string-length($stdtcvalue) = 10) then concat($stdtcvalue,'T00:00:00')
(: T is given but no hours - might bei invalid anyway :)
else if(string-length($stdtcvalue) = 11) then concat($stdtcvalue,'00:00:00')
(: only hour is given :)
else if(string-length($stdtcvalue) = 13) then concat($stdtcvalue,':00:00')
(: hour and minutes are given, but no seconds :)
else if(string-length($stdtcvalue) = 16) then concat($stdtcvalue,':00')
(: all ok anyway :)
else ($stdtcvalue)
(: and then for --ENDTC :)
let $endtctestvalue :=
(: only the year is given :)
if(string-length($endtcvalue) = 4) then concat($endtcvalue,'-01-01T00:00:00')
(: only the month is given :)
else if(string-length($endtcvalue) = 7) then concat($endtcvalue,'-01T00:00:00')
(: complete date is given but no time :)
else if(string-length($endtcvalue) = 10) then concat($endtcvalue,'T00:00:00')
(: T is given but no hours - might bei invalid anyway :)
else if(string-length($endtcvalue) = 11) then concat($endtcvalue,'00:00:00')
(: only hour is given :)
else if(string-length($endtcvalue) = 13) then concat($endtcvalue,':00:00')
(: hour and minutes are given, but no seconds :)
else if(string-length($endtcvalue) = 16) then concat($endtcvalue,':00')
(: all ok anyway :)
else ($endtcvalue)
(: ENDTC value must be equal or higher than STDTY - but first check whether it really is a datetime :)
where $stdtctestvalue castable as xs:dateTime and $endtctestvalue castable as xs:dateTime and xs:dateTime($stdtctestvalue) > xs:dateTime($endtctestvalue)
return <error rule="FDAC107" dataset="{data($name)}" variable="{data($stdtcname)}" rulelastupdate="2016-03-28" recordnumber="{data($recnum)}">{data($stdtcname)}={data($stdtcvalue)} is after {data($endtcname)}={data($endtcvalue)} in dataset {data($datasetname)}</error>
--STDTC is after --ENDTC, single dataset or domain - Start Date/Time of Event, Exposure or Observation (--STDTC) must be less or equal to End Date/Time of Event, Exposure or Observation (--ENDTC)
ALL
(: Rule FDAC107 - --STDTC is after --ENDTC
Start Date/Time of Event, Exposure or Observation (--STDTC) must be less or equal to End Date/Time of Event, Exposure or Observation (--ENDTC)
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
declare variable $domain external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all the datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name=$domain or @Domain=$domain]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the prefix for STDTC and ENDTC from either the domain or the dataset name :)
let $prefix := if($dataset/@Domain) then $dataset/@Domain
else substring($name,1,2)
(: Get the OIDs of the --STDTC and --ENDTC variables :)
(: We must iterate over all xxSTDTC and xxxSTDTC and xxxxSTDTC :)
let $stdtcoids := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STDTC')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
for $stdtcoid in $stdtcoids
let $stdtcname := doc(concat($base,$define))//odm:ItemDef[@OID=$stdtcoid]/@Name
(: get the corresponding ENDTC :)
let $endtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name=replace($stdtcname,'STDTC','ENDTC')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $endtcname := doc(concat($base,$define))//odm:ItemDef[@OID=$endtcoid]/@Name
(: now iterate over all the records in the dataset that do have an SDTY AND ENDY variable :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$stdtcoid] and odm:ItemData[@ItemOID=$endtcoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the values :)
let $stdtcvalue := $record/odm:ItemData[@ItemOID=$stdtcoid]/@Value
let $endtcvalue := $record/odm:ItemData[@ItemOID=$endtcoid]/@Value
(: take care that both are datetime, as it can be that only one of the two is of datetime
and that the other is of type date, which would make them incomparable :)
(: first for --STDTC :)
let $stdtctestvalue :=
(: only the year is given :)
if(string-length($stdtcvalue) = 4) then concat($stdtcvalue,'-01-01T00:00:00')
(: only the month is given :)
else if(string-length($stdtcvalue) = 7) then concat($stdtcvalue,'-01T00:00:00')
(: complete date is given but no time :)
else if(string-length($stdtcvalue) = 10) then concat($stdtcvalue,'T00:00:00')
(: T is given but no hours - might bei invalid anyway :)
else if(string-length($stdtcvalue) = 11) then concat($stdtcvalue,'00:00:00')
(: only hour is given :)
else if(string-length($stdtcvalue) = 13) then concat($stdtcvalue,':00:00')
(: hour and minutes are given, but no seconds :)
else if(string-length($stdtcvalue) = 16) then concat($stdtcvalue,':00')
(: all ok anyway :)
else ($stdtcvalue)
(: and then for --ENDTC :)
let $endtctestvalue :=
(: only the year is given :)
if(string-length($endtcvalue) = 4) then concat($endtcvalue,'-01-01T00:00:00')
(: only the month is given :)
else if(string-length($endtcvalue) = 7) then concat($endtcvalue,'-01T00:00:00')
(: complete date is given but no time :)
else if(string-length($endtcvalue) = 10) then concat($endtcvalue,'T00:00:00')
(: T is given but no hours - might bei invalid anyway :)
else if(string-length($endtcvalue) = 11) then concat($endtcvalue,'00:00:00')
(: only hour is given :)
else if(string-length($endtcvalue) = 13) then concat($endtcvalue,':00:00')
(: hour and minutes are given, but no seconds :)
else if(string-length($endtcvalue) = 16) then concat($endtcvalue,':00')
(: all ok anyway :)
else ($endtcvalue)
(: ENDTC value must be equal or higher than STDTY - but first check whether it really is a datetime :)
where $stdtctestvalue castable as xs:dateTime and $endtctestvalue castable as xs:dateTime and xs:dateTime($stdtctestvalue) > xs:dateTime($endtctestvalue)
return <error rule="FDAC107" dataset="{data($name)}" variable="{data($stdtcname)}" rulelastupdate="2016-03-28" recordnumber="{data($recnum)}">{data($stdtcname)}={data($stdtcvalue)} is after {data($endtcname)}={data($endtcvalue)} in dataset {data($datasetname)}</error>
--DTC is after --ENDTC - Date/Time of Specimen Collection (--DTC) must be less or equal to End Date/Time of Specimen Collection (--ENDTC)
FINDINGS
(: Rule FDAC108 - --DTC is after --ENDTC:
Date/Time of Specimen Collection (--DTC) must be less or equal to End Date/Time of Specimen Collection (--ENDTC)
:)
(: TODO: not well tested yet - make it more efficient :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all the datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OIDs of the --DTC and --ENDTC variables :)
(: For xxDTC we only take those for which the string length=5 :)
let $dtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'DTC') and string-length(@Name) = 5]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $dtcname := doc(concat($base,$define))//odm:ItemDef[@OID=$dtcoid]/@Name
let $endtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ENDTC') and string-length() = 7]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $endtcname := doc(concat($base,$define))//odm:ItemDef[@OID=$endtcoid]/@Name
(: now iterate over all the records in the dataset that do have an SDTY AND ENDY variable :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$dtcoid] and odm:ItemData[@ItemOID=$endtcoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the values :)
let $dtcvalue := $record/odm:ItemData[@ItemOID=$dtcoid]/@Value
let $endtcvalue := $record/odm:ItemData[@ItemOID=$endtcoid]/@Value
(: take care that both are datetime, as it can be that only one of the two is of datetime
and that the other is of type date, which would make them incomparable :)
(: first for --DTC :)
let $dtctestvalue :=
(: only the year is given :)
if(string-length($dtcvalue) = 4) then concat($dtcvalue,'-01-01T00:00:00')
(: only the month is given :)
else if(string-length($dtcvalue) = 7) then concat($dtcvalue,'-01T00:00:00')
(: complete date is given but no time :)
else if(string-length($dtcvalue) = 10) then concat($dtcvalue,'T00:00:00')
(: T is given but no hours - might bei invalid anyway :)
else if(string-length($dtcvalue) = 11) then concat($dtcvalue,'00:00:00')
(: only hour is given :)
else if(string-length($dtcvalue) = 13) then concat($dtcvalue,':00:00')
(: hour and minutes are given, but no seconds :)
else if(string-length($dtcvalue) = 16) then concat($dtcvalue,':00')
(: all ok anyway :)
else ($dtcvalue)
(: and then for --ENDTC :)
let $endtctestvalue :=
(: only the year is given :)
if(string-length($endtcvalue) = 4) then concat($endtcvalue,'-01-01T00:00:00')
(: only the month is given :)
else if(string-length($endtcvalue) = 7) then concat($endtcvalue,'-01T00:00:00')
(: complete date is given but no time :)
else if(string-length($endtcvalue) = 10) then concat($endtcvalue,'T00:00:00')
(: T is given but no hours - might be invalid anyway :)
else if(string-length($endtcvalue) = 11) then concat($endtcvalue,'00:00:00')
(: only hour is given :)
else if(string-length($endtcvalue) = 13) then concat($endtcvalue,':00:00')
(: hour and minutes are given, but no seconds :)
else if(string-length($endtcvalue) = 16) then concat($endtcvalue,':00')
(: all ok anyway :)
else ($endtcvalue)
(: ENDTC value must be equal or higher than DTC :)
where $dtctestvalue castable as xs:dateTime and $endtctestvalue castable as xs:dateTime and xs:dateTime($dtctestvalue) > xs:dateTime($endtctestvalue)
return <error rule="FDAC108" dataset="{data($name)}" variable="{data(dtcname)}" rulelastupdate="2016-03-28" recordnumber="{data($recnum)}">{data($dtcname)}={data($dtcvalue)} is after {data($endtcname)}={data($endtcvalue)} in dataset {data($datasetname)}</error>
RFSTDTC is not provided for a randomized subject - Subject Reference Start Date/Time (RFSTDTC) should be populated for all randomized subjects, those where Planned Arm Code (ARMCD) is not equal to 'SCRNFAIL' or 'NOTASSGN'
DM
(: Rule FDAC109 - RFSTDTC is not provided for a randomized subject
Subject Reference Start Date/Time (RFSTDTC) should be populated for all randomized subjects, those where Planned Arm Code (ARMCD) is not equal to 'SCRNFAIL' or 'NOTASSGN'
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the DM dataset :)
let $dmdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']
let $dmdatasetname := $dmdataset/def:leaf/@xlink:href
let $dmdatasetlocation := concat($base,$dmdatasetname)
(: and get the OIDs of USUBJID and ARMCD :)
let $usubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
let $armcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: and the OID for RFSTDTC :)
let $rfstdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='RFSTDTC']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records in the DM dataset :)
for $record in doc($dmdatasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the values for USUBJID and ARMCD and RFSTDTC :)
let $armcdvalue := $record/odm:ItemData[@ItemOID=$armcdoid]/@Value
let $rfstdtcvalue := $record/odm:ItemData[@ItemOID=$rfstdtcoid]/@Value
let $usubjidvalue := $record/odm:ItemData[@ItemOID=$usubjidoid]/@Value
(: except for the case that ARMCD=SCRNFAIL or NOTASSGN, there MUST be an RFSTDTC :)
where not($armcdvalue = 'SCRNFAIL') and not($armcdvalue='NOTASSGN') and not($rfstdtcvalue)
return <warning rule="FDAC109" dataset="DM" variable="RFSTDTC" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">RFSTDTC is not provided for a randomized subject with USUBJID={data($usubjidvalue)}</warning>
RFENDTC is not provided for a randomized subject - Subject Reference End Date/Time (RFENDTC) should be populated for all randomized subjects, those where Planned Arm Code (ARMCD) is not equal to 'SCRNFAIL' or 'NOTASSGN'
DM
(: Rule FDAC110 - RFENDTC is not provided for a randomized subject
Subject Reference End Date/Time (RFENDTC) should be populated for all randomized subjects, those where Planned Arm Code (ARMCD) is not equal to 'SCRNFAIL' or 'NOTASSGN'
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the DM dataset :)
let $dmdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']
let $dmdatasetname := $dmdataset/def:leaf/@xlink:href
let $dmdatasetlocation := concat($base,$dmdatasetname)
(: and get the OIDs of USUBJID and ARMCD :)
let $usubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
let $armcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: and the OID for RFENDTC :)
let $rfendtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='RFENDTC']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records in the DM dataset :)
for $record in doc($dmdatasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the values for USUBJID and ARMCD and RFSTDTC :)
let $armcdvalue := $record/odm:ItemData[@ItemOID=$armcdoid]/@Value
let $rfendtcvalue := $record/odm:ItemData[@ItemOID=$rfendtcoid]/@Value
let $usubjidvalue := $record/odm:ItemData[@ItemOID=$usubjidoid]/@Value
(: except for the case that ARMCD=SCRNFAIL or NOTASSGN, there MUST be an RFSTDTC :)
where not($armcdvalue = 'SCRNFAIL') and not($armcdvalue='NOTASSGN') and not($rfendtcvalue)
return <warning rule="FDAC110" dataset="DM" variable="RFENDTC" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">RFENDTC is not provided for a randomized subject with USUBJID={data($usubjidvalue)}</warning>
RFSTDTC is after RFENDTC - Subject Reference Start Date/Time (RFSTDTC) must be less than or equal to Subject Reference End Date/Time (RFENDTC)
DM
(: TODO - test on large submission file :)
(: Rule FDAC111 - RFSTDTC is after RFENDTC
Subject Reference Start Date/Time (RFSTDTC) must be less than or equal to Subject Reference End Date/Time (RFENDTC)
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the DM dataset :)
let $dmdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']
let $dmdatasetname := $dmdataset/def:leaf/@xlink:href
let $dmdatasetlocation := concat($base,$dmdatasetname)
(: and get the OIDs of USUBJID :)
let $usubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: and the OIDs for RFSTDTC RFENDTC :)
let $rfstdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='RFSTDTC']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
let $rfendtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='RFENDTC']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records in the DM dataset :)
for $record in doc($dmdatasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the values for USUBJID and ARMCD and RFSTDTC :)
let $rfstdtcvalue := $record/odm:ItemData[@ItemOID=$rfstdtcoid]/@Value
let $rfendtcvalue := $record/odm:ItemData[@ItemOID=$rfendtcoid]/@Value
let $usubjidvalue := $record/odm:ItemData[@ItemOID=$usubjidoid]/@Value
(: except for the case that ARMCD=SCRNFAIL or NOTASSGN, there MUST be an RFSTDTC :)
(: convert RFSTDTC and RFENDTC to a datetime for the case that one of both is a datetime
(or partial) and the other is not making them essentally incomparable :)
let $rfstdtctestvalue :=
(: only the year is given :)
if(string-length($rfstdtcvalue) = 4) then concat($rfstdtcvalue,'-01-01T00:00:00')
(: only the month is given :)
else if(string-length($rfstdtcvalue) = 7) then concat($rfstdtcvalue,'-01T00:00:00')
(: complete date is given but no time :)
else if(string-length($rfstdtcvalue) = 10) then concat($rfstdtcvalue,'T00:00:00')
(: T is given but no hours - might bei invalid anyway :)
else if(string-length($rfstdtcvalue) = 11) then concat($rfstdtcvalue,'00:00:00')
(: only hour is given :)
else if(string-length($rfstdtcvalue) = 13) then concat($rfstdtcvalue,':00:00')
(: hour and minutes are given, but no seconds :)
else if(string-length($rfstdtcvalue) = 16) then concat($rfstdtcvalue,':00')
(: all ok anyway :)
else ($rfstdtcvalue)
(: and then for --ENDTC :)
let $endtctestvalue :=
(: only the year is given :)
if(string-length($rfendtcvalue) = 4) then concat($rfendtcvalue,'-01-01T00:00:00')
(: only the month is given :)
else if(string-length($rfendtcvalue) = 7) then concat($rfendtcvalue,'-01T00:00:00')
(: complete date is given but no time :)
else if(string-length($rfendtcvalue) = 10) then concat($rfendtcvalue,'T00:00:00')
(: T is given but no hours - might bei invalid anyway :)
else if(string-length($rfendtcvalue) = 11) then concat($rfendtcvalue,'00:00:00')
(: only hour is given :)
else if(string-length($rfendtcvalue) = 13) then concat($rfendtcvalue,':00:00')
(: hour and minutes are given, but no seconds :)
else if(string-length($rfendtcvalue) = 16) then concat($rfendtcvalue,':00')
(: all ok anyway :)
else ($rfendtcvalue)
where ($rfstdtctestvalue castable as xs:dateTime) and ($rfstdtctestvalue castable as xs:dateTime) and xs:dateTime($rfstdtctestvalue) > xs:dateTime($endtctestvalue)
return <error rule="FDAC111" dataset="DM" variable="RFSTDTC" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">RFSTDTC={data($rfstdtcvalue)} is after RFENDTC={data($rfendtcvalue)} for subject with USUBJID={data($usubjidvalue)}</error>
Value of Study Day variable equals 0 - Study Day variables (*DY) value should not equal 0
ALL
(: Rule FDAC112 - Value of Study Day variable equals 0
Study Day variables (*DY) value should not equal 0
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all the datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: for this dataset, find all *DY variables - attention, there can be more than one :)
let $dyvaroids := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'DY')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records in the dataset :)
for $record in doc($datasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: iterate over all *DY variables :)
for $dyvaroid in $dyvaroids
let $dyname := doc(concat($base,$define))//odm:ItemDef[@OID=$dyvaroid]/@Name
let $dyvalue := $record/odm:ItemData[@ItemOID=$dyvaroid]/@Value
(: and check whether it is 0 :)
where number($dyvalue) = 0
(: and give out a warning :)
return <warning rule="FDAC112" dataset="{data($name)}" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">Value of Study Day {data($dyname)} variable equals 0</warning>
No baseline result in Domain for subject - All subjects should have at least one baseline observation (--BLFL = 'Y') in EG, LB, MB, MS, PC and VS domains, except for subjects who failed screening (ARMCD = 'SCRNFAIL') or were not fully assigned to an Arm (ARMCD = 'NOTASSGN') or were not treated (ACTARMCD = 'NOTTRT')
EG
LB
MB
MS
PC
VS
(: TODO: test on large submission with more splitted datasets :)
(: Rule FDAC113 - No baseline result in Domain for subject
All subjects should have at least one baseline observation (--BLFL = 'Y') in EG, LB, MB, MS, PC and VS domains, except for subjects who failed screening (ARMCD = 'SCRNFAIL') or were not fully assigned to an Arm (ARMCD = 'NOTASSGN') or were not treated (ACTARMCD = 'NOTTRT') in datasets EG, LB, MB, MS, PC, VS
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: find all subjects in DM for which ARMCD is NOT SCRNFAIL, NOT NOTASSGN and NOT NOTTRT :)
(: we need the OID of ARMCD :)
let $armcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: and the OID of the USUBJID variable :)
let $dmusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: and the location of the DM dataset :)
let $dmdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/def:leaf/@xlink:href
let $dmdatasetlocation := concat($base,$dmdatasetname)
(: find all subjects in DM for which ARMCD is NOT SCRNFAIL, NOT NOTASSGN and NOT NOTTRT :)
let $randomizedsubjects := doc($dmdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$armcdoid][not(@Value='SCRNFAIL') and not(@Value='NOTASSGN') and not(@Value=NOTTRT)]]/odm:ItemData[@ItemOID=$dmusubjidoid]/@Value
(: iterate over all applicable DOMAINS, taking splitted datasets into account :)
let $domains := ('EG','LB','MB','MS','PC','VS')
(: there can be more than 1 dataset per domain :)
for $domain in $domains
let $datasets := doc(concat($base,$define))//odm:ItemGroupDef[@Domain=$domain or starts-with(@Name,$domain)] (: provides a list of nodes :)
let $datasetslocationsindomain :=
(concat($base,doc(concat($base,$define))//odm:ItemGroupDef[@Domain=$domain]/def:leaf/@xlink:href))
(: get the name of the BLFL variable :)
let $blflname := concat($domain,'BLFL')
(: and the OID - should be the same for each of the datasets within the single domain :)
let $blfloid := doc(concat($base,$define))//odm:ItemDef[@Name=$blflname]/@OID
let $usubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Domain=$domain][1]/odm:ItemRef/@ItemOID
return $a
)
(: return <test>{data($domain)} - {data($blfloid)}</test> :)
(: iterate over all the randomized subjects and count the number of baseline flag records
over all the datasets within that domain :)
for $subject in $randomizedsubjects
let $count := count(
for $dataset in $datasetslocationsindomain
let $c := doc($dataset)//odm:ItemGroupData[odm:ItemData[@ItemOID=$usubjidoid][@Value=$subject] and odm:ItemData[@ItemOID=$blfloid]]/@data:ItemGroupDataSeq
(: return <test>{data($dataset)} - {data($subject)} - {data($c)}</test> :)
return $c
)
(: $count gives the number of records with a baseline flag for the subject :)
where count($datasets) > 0 and $count = 0 (: no baseline record for this subject found in any of the datasets in this domain :)
return <warning rule="FDAC113" dataset="{data($domain)}" rulelastupdate="2015-02-10">No baseline result in Domain {data($domain)} for subject {data($subject)}</warning>
Missing value for --STRESC, when --DRVFL='Y' - Character Result/Finding in Std Format (--STRESC) value should not be NULL, when Derived Flag (--DRVFL) value is 'Y'
FINDINGS
(: Rule FDAC114 - Missing value for --STRESC, when --DRVFL='Y'
Character Result/Finding in Std Format (--STRESC) value should not be NULL, when Derived Flag (--DRVFL) value is 'Y'
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all the datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Find the OID of the --DRVFL variable :)
let $drvfloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'DRVFL')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: and the name :)
let $drvflname := doc(concat($base,$define))//odm:ItemDef[@OID=$drvfloid]/@Name
(: Find the OID and the name of the --STRESC variable :)
let $strescoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STRESC')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $strescname := doc(concat($base,$define))//odm:ItemDef[@OID=$strescoid]/@Name
(: iterate over all the records that have a DRVFL variable :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData/@ItemOID=$drvfloid]
let $recnum := $record/@data:ItemGroupDataSeq
(: Get the value of the DRVFL variable :)
let $drvflvalue := $record/odm:ItemData[@ItemOID=$drvfloid]/@Value
(: and of the STRESC variable (if any) :)
let $strescvalue := $record/odm:ItemData[@ItemOID=$strescoid]/@Value
(: when DRVFL='Y' ensure there is a STRESC data point :)
where $drvflvalue='Y' and not($strescvalue)
return <warning rule="FDAC114" rulelastupdate="2015-02-10" dataset="{data($name)}" variable="{data($strescname)}" recordnumber="{data($recnum)}">Missing value for {data($strescname)}, when {data($drvflname)}='Y'</warning>
Missing value for --STRESC, when --DRVFL='Y', single dataset or domain - Character Result/Finding in Std Format (--STRESC) value should not be NULL, when Derived Flag (--DRVFL) value is 'Y'
FINDINGS
(: Rule FDAC114 - Missing value for --STRESC, when --DRVFL='Y'
Character Result/Finding in Std Format (--STRESC) value should not be NULL, when Derived Flag (--DRVFL) value is 'Y'
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
declare variable $domain external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all the datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name=$domain or @Domain=$domain]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Find the OID of the --DRVFL variable :)
let $drvfloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'DRVFL')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: and the name :)
let $drvflname := doc(concat($base,$define))//odm:ItemDef[@OID=$drvfloid]/@Name
(: Find the OID and the name of the --STRESC variable :)
let $strescoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STRESC')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $strescname := doc(concat($base,$define))//odm:ItemDef[@OID=$strescoid]/@Name
(: iterate over all the records that have a DRVFL variable :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData/@ItemOID=$drvfloid]
let $recnum := $record/@data:ItemGroupDataSeq
(: Get the value of the DRVFL variable :)
let $drvflvalue := $record/odm:ItemData[@ItemOID=$drvfloid]/@Value
(: and of the STRESC variable (if any) :)
let $strescvalue := $record/odm:ItemData[@ItemOID=$strescoid]/@Value
(: when DRVFL='Y' ensure there is a STRESC data point :)
where $drvflvalue='Y' and not($strescvalue)
return <warning rule="FDAC114" rulelastupdate="2015-02-10" dataset="{data($name)}" variable="{data($strescname)}" recordnumber="{data($recnum)}">Missing value for {data($strescname)}, when {data($drvflname)}='Y'</warning>
Missing TSVAL value - Value for Parameter Value (TSVAL) variable must be populated. TSVAL can only be null when Parameter Null Flavor (TSVALNF) variable value is populated.
TS
(: Rule FDAC115 - Missing TSVAL value
Value for Parameter Value (TSVAL) variable must be populated. TSVAL can only be null when Parameter Null Flavor (TSVALNF) variable value is populated.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: Get the OIDs of TSVAL and TSVALNF :)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TSVAL')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvalnfoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TSVALNF')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: Iterate over all the records in the TS dataset :)
for $record in doc($tsdatasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of TSVAL and TSVALNF (if any) :)
let $tsvalvalue := $record/odm:ItemData[@ItemOID=$tsvaloid]/@Value
let $tsvalnfvalue := $record/odm:ItemData[@ItemOID=$tsvalnfoid]/@Value
(: check whether TSVAL is populated except for when TSVALNF is populated :)
where not($tsvalnfvalue) and not($tsvalvalue)
return <error rule="FDAC115" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">Missing TSVAL value</error>
Missing TSVALNF value - Value for Parameter Null Flavor (TSVALNF) variable must be populated, when Parameter Value (TSVAL) variable value is missing
TS
(: Rule FDAC116 - Missing TSVALNF value
Value for Parameter Null Flavor (TSVALNF) variable must be populated, when Parameter Value (TSVAL) variable value is missing.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: Get the OIDs of TSVAL and TSVALNF :)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TSVAL')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvalnfoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TSVALNF')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: Iterate over all the records in the TS dataset :)
for $record in doc($tsdatasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of TSVAL and TSVALNF (if any) :)
let $tsvalvalue := $record/odm:ItemData[@ItemOID=$tsvaloid]/@Value
let $tsvalnfvalue := $record/odm:ItemData[@ItemOID=$tsvalnfoid]/@Value
(: check whether TSVAL is populated except for when TSVALNF is populated :)
where not($tsvalvalue) and not($tsvalnfvalue)
return <error rule="FDAC116" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">Missing TSVALNF value</error>
Missing End Time-Point value - One of End Time-Point variables values is expected to be populated when an event or an intervention occurred. (E.g., one of End Date/Time of Event or Intervention (--ENDTC), End Relative to Reference Period (--ENRF), and End Relative to Reference Period (--ENRTPT) variables values should not be missing, or Occurrence (--OCCUR) variable value should be 'N')
INTERVENTIONS
EVENTS
(: Rule FDAC117 - Missing End Time-Point value:
One of End Time-Point variables values is expected to be populated when an event or an intervention occurred.
(E.g., one of End Date/Time of Event or Intervention (--ENDTC), End Relative to Reference Period (--ENRF), and End Relative to Reference Period (--ENRTPT) variables values should not be missing, or Occurrence (--OCCUR) variable value should be 'N')
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all Interventions and Events datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[upper-case(@def:Class)='INTERVENTIONS' or upper-case(@def:Class)='EVENTS']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OIDs of ENDTC, ENRF, ENRTPT and OCCUR variables :)
let $endtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ENDTC')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $enrfoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ENRF')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $enrtptoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ENRTPT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $occuroid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'OCCUR')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: variable names, keeping care of splitted domains :)
let $endtcname := concat(substring($name,1,2),'ENDTC')
let $enrfname := concat(substring($name,1,2),'ENRF')
let $enrtptname := concat(substring($name,1,2),'ENRTPT')
let $occurname := concat(substring($name,1,2),'OCCUR')
(: iterate over all the records in the dataset :)
for $record in doc($datasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of ENDTC, ENRF, ENRTPT (if any) and OCCUR :)
let $endtcvalue := $record/odm:ItemData[@ItemOID=$endtcoid]/@Value
let $enrfvalue := $record/odm:ItemData[@ItemOID=$enrfoid]/@Value
let $enrtptvalue := $record/odm:ItemData[@ItemOID=$enrtptoid]/@Value
let $occurvalue := $record/odm:ItemData[@ItemOID=$occuroid]/@Value
(: one of ENDTC, ENRF, ENRTPT must be populated, except when OCCUR='N' :)
where not($occurvalue='N') and not($endtcvalue or $enrfvalue or $enrtptvalue)
return <warning rule="FDAC117" variable="USUBJID" dataset="{data($name)}" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">Missing End Time-Point value in dataset {data($name)} file {data($datasetname)}: One of End Time-Point variables values [{data($endtcname)},{data($enrfname)},{data($enrtptname)}] is expected to be populated except for when {data($occurname)}='N'</warning>
Missing Start Time-Point value - One of Start Time-Point variables values is expected to be populated when an event an intervention occurred. (E.g., one of Start Date/Time of Event or Intervention (--STDTC), Start Relative to Reference Period (--STRF), and Start Relative to Reference Period (--STRTPT) variables values should not be missing, or Occurrence (--OCCUR) variable value should be 'N')
INTERVENTIONS
EVENTS
(: Rule FDAC118 - Missing Start Time-Point value:
One of Start Time-Point variables values is expected to be populated when an event an intervention occurred.
(E.g., one of Start Date/Time of Event or Intervention (--STDTC), Start Relative to Reference Period (--STRF), and Start Relative to Reference Period (--STRTPT) variables values should not be missing, or Occurrence (--OCCUR) variable value should be 'N')
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all Interventions and Events datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[upper-case(@def:Class)='INTERVENTIONS' or upper-case(@def:Class)='EVENTS']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OIDs of STDTC, STRF, STRTPT and OCCUR variables :)
let $stdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STDTC')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $strfoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STRF')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $strtptoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STRTPT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $occuroid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'OCCUR')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $occurname := concat(substring($name,1,2),'OCCUR')
let $stdtcname:= concat(substring($name,1,2),'STDTC')
let $strtptname := concat(substring($name,1,2),'STRTPT')
let $strfname := concat(substring($name,1,2),'STRF')
(: iterate over all the records in the dataset :)
for $record in doc($datasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of ENDTC, ENRF, ENRTPT (if any) and OCCUR :)
let $stdtcvalue := $record/odm:ItemData[@ItemOID=$stdtcoid]/@Value
let $strfvalue := $record/odm:ItemData[@ItemOID=$strfoid]/@Value
let $strtptvalue := $record/odm:ItemData[@ItemOID=$strtptoid]/@Value
let $occurvalue := $record/odm:ItemData[@ItemOID=$occuroid]/@Value
(: one of STDTC, STRF, STRTPT must be populated, except when OCCUR='N' :)
where not($occurvalue='N') and not($stdtcvalue or $strfvalue or $strtptvalue)
return <warning rule="FDAC118" variable="USUBJID" dataset="{data($name)}" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">Missing Start Time-Point value in dataset {data($name)} file {data($datasetname)}: One of Start Time-Point variables values [{data($stdtcname)},{data($strfname)},{data($strtptname)}] is expected to be populated when an event an intervention occurred except for when {data($occurname)}='N'</warning>
Missing value for --DTC, when --ENDTC is provided - Date/Time of Collection (--DTC) should not be NULL, when End Date/Time of Observation (--ENDTC) is not NULL
FINDINGS
(: TODO - not tested yet :)
(: Rule FDAC119 - Missing value for --DTC, when --ENDTC is provided:
Date/Time of Collection (--DTC) should not be NULL, when End Date/Time of Observation (--ENDTC) is not NULL
Findings domains
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all the FINDINGS datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[upper-case(@def:Class)='FINDINGS']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OID of the ENDTC variable :)
let $endtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ENDTC')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $endtcname := doc(concat($base,$define))//odm:ItemDef[@OID=$endtcoid]/@Name
(: and the OID of the DTC variable (5 characters) :)
let $dtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'DTC') and string-length(@Name)=5]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $dtcname := doc(concat($base,$define))//odm:ItemDef[@OID=$dtcoid]/@Name
(: now iterate over all records in the dataset that have an ENDTC that is not null :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData/@ItemOID=$endtcoid]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the values of the ENDTC and DTC variables (if any) :)
let $endtcvalue := $record/odm:ItemData[@ItemOID=$endtcoid]/@Value
let $dtcvalue := $record/odm:ItemData[@ItemOID=$dtcoid]/@Value
(: check whether there is a DTC value when an ENDTC value is present :)
(: where $endtcvalue and not($dtcvalue) :)
return <warning rule="FDAC119" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">Missing value for {data($dtcname)}, when {data($endtcname)} is provided, value={data($endtcvalue)}</warning>
Missing value for --STTPT, when --STRTPT is populated - Start Reference Time Point (--STTPT) must not be NULL, when Start Relative to Reference Time Point (--STRTPT) is provided
INTERVENTIONS
EVENTS
FINDINGS
SV
SE
(: Rule FDAC120 - Missing value for --STTPT, when --STRTPT is populated:
Start Reference Time Point (--STTPT) must not be NULL, when Start Relative to Reference Time Point (--STRTPT) is provided
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all the datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OIDs of the STTPT and STRTPT variables (if any) :)
let $sttptoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STTPT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $sttptname := doc(concat($base,$define))//odm:ItemDef[@OID=$sttptoid]/@Name
let $strtptoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STRTPT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $strtptname := doc(concat($base,$define))//odm:ItemDef[@OID=$strtptoid]/@Name
(: iterate over all the records in the dataset for which there is a STRTPT data point :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData/@ItemOID=$strtptoid]
let $recnum := $record/@data:ItemGroupDataSeq
(: and check whether there is STTPT data point :)
let $sttptvalue := $record/odm:ItemData[@ItemOID=$sttptoid]/@Value
let $strtptvalue := $record/odm:ItemData[@ItemOID=$strtptoid]/@Value
where not($sttptvalue)
return <warning rule="FDAC120" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">Missing value for {data($sttptname)}, when {data($strtptname)} is populated, value = {data($strtptvalue)}</warning>
Missing value for --ENTPT, when --ENRTPT is populated - End Reference Time Point (--ENTPT) must not be NULL, when End Relative to Reference Time Point (--ENRTPT) is provided
ALL
(: Rule FDAC121 - Missing value for --ENTPT, when --ENRTPT is populated:
End Reference Time Point (--ENTPT) must not be NULL, when End Relative to Reference Time Point (--ENRTPT) is provided
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all the datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OIDs of the ENTPT and ENRTPT variables (if any) :)
let $entptoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ENTPT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $entptname := doc(concat($base,$define))//odm:ItemDef[@OID=$entptoid]/@Name
let $enrtptoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ENRTPT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $enrtptname := doc(concat($base,$define))//odm:ItemDef[@OID=$enrtptoid]/@Name
(: iterate over all the records in the dataset for which there is a STRTPT data point :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData/@ItemOID=$enrtptoid]
let $recnum := $record/@data:ItemGroupDataSeq
(: and check whether there is STTPT data point :)
let $entptvalue := $record/odm:ItemData[@ItemOID=$entptoid]/@Value
let $enrtptvalue := $record/odm:ItemData[@ItemOID=$enrtptoid]/@Value
where not($entptvalue)
return <warning rule="FDAC121" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">Missing value for {data($entptname)}, when {data($enrtptname)} is populated, value = {data($enrtptvalue)}</warning>
Missing values for --STDTC, --STRF and --STRTPT, when --ENDTC, --ENRF or --ENRTPT is provided - Start Date/Time of Observation (--STDTC), Start Relative to Reference Period (--STRF) or Start Relative to Reference Time Point (--STRTPT) should not be NULL, when End Date/Time of Observation (--ENDTC), End Relative to Reference Period (--ENRF) or End Relative to Reference Time Period (--ENRTPT) is not NULL
ALL
(: TODO: requires further testing :)
(: Rule FDAC122 - Missing values for --STDTC, --STRF and --STRTPT, when --ENDTC, --ENRF or --ENRTPT is provided
Start Date/Time of Observation (--STDTC), Start Relative to Reference Period (--STRF) or Start Relative to Reference Time Point (--STRTPT) should not be NULL,
when End Date/Time of Observation (--ENDTC), End Relative to Reference Period (--ENRF) or End Relative to Reference Time Period (--ENRTPT) is not NULL
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all the datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OID and Name of the STDTC, STRF, STRTPT variables :)
let $stdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STDTC')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $stdtcname := doc(concat($base,$define))//odm:ItemDef[@OID=$stdtcoid]/@Name
let $strfoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STRF')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $strfname := doc(concat($base,$define))//odm:ItemDef[@OID=$strfoid]/@Name
let $strtptoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STRTPT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $strtptname := doc(concat($base,$define))//odm:ItemDef[@OID=$strtptoid]/@Name
(: and of the ENDTC, ENRF and ENRTPT variables :)
let $endtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ENDTC')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $endtcname := doc(concat($base,$define))//odm:ItemDef[@OID=$endtcoid]/@Name
let $enrfoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ENDTC')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $enrfname := doc(concat($base,$define))//odm:ItemDef[@OID=$enrfoid]/@Name
let $enrtptoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ENRTPT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $enrtptname := doc(concat($base,$define))//odm:ItemDef[@OID=$enrtptoid]/@Name
(: iterate over all records that do have a --ENDTC, --ENRF or --ENRTPT data point :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$endtcoid] or odm:ItemData[@ItemOID=$enrfoid] or odm:ItemData[@ItemOID=$enrtptoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: check whether a value for STDTC, STRF, or STRTPT is present :)
where not($record/odm:ItemData[@ItemOID=$stdtcoid]) and not($record/odm:ItemData[@ItemOID=$strfoid]) and not($record/odm:ItemData[@ItemOID=$strtptoid])
return <warning rule="FDAC122" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">Missing values for {data(concat($name,'STDTC'))}, {data(concat($name,'STRF'))} and {data(concat($name,'STRTPT'))}, when one of {data(concat($name,'ENDTC'))}, {data(concat($name,'ENRF'))} or {data(concat($name,'ENRTPT'))} is provided in dataset {data($name)} </warning>
Missing value for --TPT, when --TPTNUM is provided - Planned Time Point Name (--TPT) should not be NULL, when Planned Time Point Number (--TPTNUM) is populated
ALL
(: Rule FDAC123 - Missing value for --TPT, when --TPTNUM is provided:
Planned Time Point Name (--TPT) should not be NULL, when Planned Time Point Number (--TPTNUM) is populated
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all the datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OIDs of TPT and TPTNUM (if any) :)
let $tptoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TPT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $tptname := doc(concat($base,$define))//odm:ItemDef[@OID=$tptoid]/@Name
(: Get the OIDs of TPT and TPTNUM (if any) :)
let $tptnumoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TPTNUM')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $tptnumname := doc(concat($base,$define))//odm:ItemDef[@OID=$tptnumoid]/@Name
(: iterate over the records in the dataset that do have a TPTNUM :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tptnumoid]]
let $recnum := $record/@data:ItemGroupDataSeq
let $tptnumvalue := $record/odm:ItemData[@ItemOID=$tptnumoid]/@Value
(: where $record/odm:ItemData[@ItemOID=$tptnumoid] :)
where not($record/odm:ItemData[@ItemOID=$tptoid])
return <warning rule="FDAC123" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">Planned Time Point Name {data($tptname)} should not be NULL, when Planned Time Point Number {data($tptnumname)} is populated, value = {data($tptnumvalue)}</warning>
Missing --DY variable, when --DTC variable is present - Collection Study Day (--DY) variable should be included into dataset, when Collection Study Date/Time (--DTC) variable is present
ALL
(: Rule FDAC124: Missing --DY variable, when --DTC variable is present:
Collection Study Day (--DY) variable should be included into dataset, when Collection Study Date/Time (--DTC) variable is present
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all the datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OIDs of the --DY and --DTC variables :)
let $dyoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'DY') and string-length(@Name)=4]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $dyname := doc(concat($base,$define))//odm:ItemDef[@OID=$dyoid]/@Name
let $dtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'DTC') and string-length(@Name)=5]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $dtcname := doc(concat($base,$define))//odm:ItemDef[@OID=$dtcoid]/@Name
(: this rule is about the presence in the dataset - not about whether the records are populated :)
where not($dyoid) and $dtcoid
return <warning rule="FDAC124" rulelastupdate="2015-02-10">Collection Study Day {data(concat($name,'DY'))} variable must be included into dataset, when Collection Study Date/Time {data($dtcname)} variable is present in dataset {data($datasetname)}</warning>
--DY variable value is not populated - Collection Study Day (--DY) variable value should be populated, when Collection Study Date/Time (--DTC) and Subject Reference Start Date/Time (RFSTDTC) variables values are provided, and both of them include complete date part.
ALL
(: Rule FDAC125 - --DY variable value is not populated:
Collection Study Day (--DY) variable value should be populated, when Collection Study Date/Time (--DTC) and Subject Reference Start Date/Time (RFSTDTC) variables values are provided, and both of them include complete date part.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the location of the DM dataset :)
let $dmdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/def:leaf/@xlink:href
let $dmdatasetlocation := concat($base,$dmdataset)
(: get the OID of the RFSTDTC variable :)
let $rfstdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='RFSTDTC']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: get the OID of the USUBJID variable :)
let $dmusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all other datasets, but not the DM dataset itself :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[not(@Name='DM')]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OIDs of the --DY and --DTC variables :)
let $dyoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'DY') and string-length(@Name)=4]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: keeping splitted datasets into account... :)
let $dyname := concat(substring($name,1,2),'DY')
let $dtcname := concat(substring($name,1,2),'DTC')
let $dtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name=$dtcname]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $dtcname := doc(concat($base,$define))//odm:ItemDef[@OID=$dtcoid]/@Name
(: and the OID of the USUBJID variable (might be different from the one in DM) :)
let $usubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$dtcoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the USUBJID value :)
let $usubjidvalue := $record/odm:ItemData[@ItemOID=$usubjidoid]/@Value
(: get the --DTC value :)
let $dtcvalue := $record/odm:ItemData[@ItemOID=$dtcoid]/@Value
(: and check whether it is a complete date - i.e. string-length at least 10 :)
let $iscompletedtcvalue := string-length($dtcvalue) >= 10 (: boolean :)
(: look up the record in the DM dataset and get the RFSTDTC :)
(: keeping worst case scenario into account that there are two records for the same USUBJID in DM - take the first :)
let $rfstdtcvalue := doc($dmdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$dmusubjidoid and @Value=$usubjidvalue]][1]/odm:ItemData[@ItemOID=$rfstdtcoid]/@Value
(: and check whether also RFSTDTC is complete :)
let $iscompleterfstdtcvalue := string-length($rfstdtcvalue) >= 10 (: boolean :)
(: when both RFSTDTC and xxDTC are complete, there MUST be a xxDY value :)
let $dyvalue := $record/odm:ItemData[@ItemOID=$dyoid]/@Value
where $iscompletedtcvalue and $iscompleterfstdtcvalue and not($dyvalue)
return <warning rule="FDAC125" dataset="{data($name)}" variable="{data($dyname)}" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">{data($dyname)} is not populated although both {data($dtcname)} (value={data($dtcvalue)}) and RFSTDTC (value={data($rfstdtcvalue)}) are provided and include a complete date part</warning>
--DY variable value is not populated, single dataset or domain - Collection Study Day (--DY) variable value should be populated, when Collection Study Date/Time (--DTC) and Subject Reference Start Date/Time (RFSTDTC) variables values are provided, and both of them include complete date part.
ALL
(: Rule FDAC125 - --DY variable value is not populated:
Collection Study Day (--DY) variable value should be populated, when Collection Study Date/Time (--DTC) and Subject Reference Start Date/Time (RFSTDTC) variables values are provided, and both of them include complete date part.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
declare variable $domain external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the location of the DM dataset :)
let $dmdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/def:leaf/@xlink:href
let $dmdatasetlocation := concat($base,$dmdataset)
(: get the OID of the RFSTDTC variable :)
let $rfstdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='RFSTDTC']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: get the OID of the USUBJID variable :)
let $dmusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all other datasets, but not the DM dataset itself :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[(@Name=$domain or @Domain=$domain) and not(@Name='DM')]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OIDs of the --DY and --DTC variables :)
let $dyoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'DY') and string-length(@Name)=4]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: keeping splitted datasets into account... :)
let $dyname := concat(substring($name,1,2),'DY')
let $dtcname := concat(substring($name,1,2),'DTC')
let $dtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name=$dtcname]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $dtcname := doc(concat($base,$define))//odm:ItemDef[@OID=$dtcoid]/@Name
(: and the OID of the USUBJID variable (might be different from the one in DM) :)
let $usubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$dtcoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the USUBJID value :)
let $usubjidvalue := $record/odm:ItemData[@ItemOID=$usubjidoid]/@Value
(: get the --DTC value :)
let $dtcvalue := $record/odm:ItemData[@ItemOID=$dtcoid]/@Value
(: and check whether it is a complete date - i.e. string-length at least 10 :)
let $iscompletedtcvalue := string-length($dtcvalue) >= 10 (: boolean :)
(: look up the record in the DM dataset and get the RFSTDTC :)
(: keeping worst case scenario into account that there are two records for the same USUBJID in DM - take the first :)
let $rfstdtcvalue := doc($dmdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$dmusubjidoid and @Value=$usubjidvalue]][1]/odm:ItemData[@ItemOID=$rfstdtcoid]/@Value
(: and check whether also RFSTDTC is complete :)
let $iscompleterfstdtcvalue := string-length($rfstdtcvalue) >= 10 (: boolean :)
(: when both RFSTDTC and xxDTC are complete, there MUST be a xxDY value :)
let $dyvalue := $record/odm:ItemData[@ItemOID=$dyoid]/@Value
where $iscompletedtcvalue and $iscompleterfstdtcvalue and not($dyvalue)
return <warning rule="FDAC125" dataset="{data($name)}" variable="{data($dyname)}" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">{data($dyname)} is not populated although both {data($dtcname)} (value={data($dtcvalue)}) and RFSTDTC (value={data($rfstdtcvalue)}) are provided and include a complete date part</warning>
--DY variable value is imputed - It may be only populated, when both Collection Study Date/Time (--DTC) and Subject Reference Start Date/Time (RFSTDTC) variables values are provided and both of them include complete date part
ALL
(: Rule FDAC126 - --DY variable value is imputed:
Collection Study Day (--DY) variable value should be not be imputed. It may be only populated, when both Collection Study Date/Time (--DTC) and Subject Reference Start Date/Time (RFSTDTC) variables values are provided and both of them include complete date part.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the location of the DM dataset :)
let $dmdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/def:leaf/@xlink:href
let $dmdatasetlocation := concat($base,$dmdataset)
(: get the OID of the RFSTDTC variable :)
let $rfstdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='RFSTDTC']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: get the OID of the USUBJID variable :)
let $dmusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all other datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[not(@Name='DM')]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OIDs of the --DY and --DTC variables :)
let $dyoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'DY') and string-length(@Name)=4]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $dyname := concat($name,'DY')
let $dtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'DTC') and string-length(@Name)=5]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $dtcname := doc(concat($base,$define))//odm:ItemDef[@OID=$dtcoid]/@Name
(: and the OID of the USUBJID variable (might be different from the one in DM) :)
let $usubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$dtcoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the USUBJID value :)
let $usubjidvalue := $record/odm:ItemData[@ItemOID=$usubjidoid]/@Value
(: get the --DTC value :)
let $dtcvalue := $record/odm:ItemData[@ItemOID=$dtcoid]/@Value
(: and check whether it is a complete date - i.e. string-length at least 10 :)
let $iscompletedtcvalue := string-length($dtcvalue) >= 10 (: boolean :)
(: look up the record in the DM dataset and get the RFSTDTC :)
(: keeping worst case scenario into account that there are two records for the same USUBJID in DM - take the first :)
let $rfstdtcvalue := doc($dmdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$dmusubjidoid and @Value=$usubjidvalue]][1]/odm:ItemData[@ItemOID=$rfstdtcoid]/@Value
(: and check whether also RFSTDTC is complete :)
let $iscompleterfstdtcvalue := string-length($rfstdtcvalue) >= 10 (: boolean :)
let $dyvalue := $record/odm:ItemData[@ItemOID=$dyoid]/@Value
(: when one of RFSTDTC and xxDTC is not complete, there may NOT be a xxDY value :)
where (not($iscompletedtcvalue) or not($iscompleterfstdtcvalue)) and $dyvalue
return <warning rule="FDAC126" dataset="{data($name)}" variable="{data($dyname)}" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">{data($dyname)} is imputed (value={data($dyvalue)}) although one of {data($dtcname)} (value={data($dtcvalue)}) or RFSTDTC (value={data($rfstdtcvalue)}) is not a complete date</warning>
--DY variable value is imputed, single dataset or domain - It may be only populated, when both Collection Study Date/Time (--DTC) and Subject Reference Start Date/Time (RFSTDTC) variables values are provided and both of them include complete date part
ALL
(: Rule FDAC126 - --DY variable value is imputed:
Collection Study Day (--DY) variable value should be not be imputed. It may be only populated, when both Collection Study Date/Time (--DTC) and Subject Reference Start Date/Time (RFSTDTC) variables values are provided and both of them include complete date part.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
declare variable $domain external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the location of the DM dataset :)
let $dmdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/def:leaf/@xlink:href
let $dmdatasetlocation := concat($base,$dmdataset)
(: get the OID of the RFSTDTC variable :)
let $rfstdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='RFSTDTC']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: get the OID of the USUBJID variable :)
let $dmusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all other datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[(@Name=$domain or @Domain=$domain) and not(@Name='DM')]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OIDs of the --DY and --DTC variables :)
let $dyoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'DY') and string-length(@Name)=4]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $dyname := concat($name,'DY')
let $dtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'DTC') and string-length(@Name)=5]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $dtcname := doc(concat($base,$define))//odm:ItemDef[@OID=$dtcoid]/@Name
(: and the OID of the USUBJID variable (might be different from the one in DM) :)
let $usubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$dtcoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the USUBJID value :)
let $usubjidvalue := $record/odm:ItemData[@ItemOID=$usubjidoid]/@Value
(: get the --DTC value :)
let $dtcvalue := $record/odm:ItemData[@ItemOID=$dtcoid]/@Value
(: and check whether it is a complete date - i.e. string-length at least 10 :)
let $iscompletedtcvalue := string-length($dtcvalue) >= 10 (: boolean :)
(: look up the record in the DM dataset and get the RFSTDTC :)
(: keeping worst case scenario into account that there are two records for the same USUBJID in DM - take the first :)
let $rfstdtcvalue := doc($dmdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$dmusubjidoid and @Value=$usubjidvalue]][1]/odm:ItemData[@ItemOID=$rfstdtcoid]/@Value
(: and check whether also RFSTDTC is complete :)
let $iscompleterfstdtcvalue := string-length($rfstdtcvalue) >= 10 (: boolean :)
let $dyvalue := $record/odm:ItemData[@ItemOID=$dyoid]/@Value
(: when one of RFSTDTC and xxDTC is not complete, there may NOT be a xxDY value :)
where (not($iscompletedtcvalue) or not($iscompleterfstdtcvalue)) and $dyvalue
return <warning rule="FDAC126" dataset="{data($name)}" variable="{data($dyname)}" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">{data($dyname)} is imputed (value={data($dyvalue)}) although one of {data($dtcname)} (value={data($dtcvalue)}) or RFSTDTC (value={data($rfstdtcvalue)}) is not a complete date</warning>
Incorrect value for --DY variable - Collection Study Day (--DY) variable value should be populated as defined by CDISC standards: --DY = (date portion of --DTC) - (date portion of RFSTDTC) +1 if --DTC is on or after RFSTDTC; --DY = (date portion of --DTC) - (date portion of RFSTDTC) if --DTC precedes RFSTDTC.
ALL
(: Rule FDAC127 - Incorrect value for --DY variable:
Collection Study Day (--DY) variable value should be populated as defined by CDISC standards: --DY = (date portion of --DTC) - (date portion of RFSTDTC) +1 if --DTC is on or after RFSTDTC; --DY = (date portion of --DTC) - (date portion of RFSTDTC) if --DTC precedes RFSTDTC.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the location of the DM dataset :)
let $dmdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/def:leaf/@xlink:href
let $dmdatasetlocation := concat($base,$dmdataset)
(: get the OID of the RFSTDTC variable :)
let $rfstdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='RFSTDTC']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: get the OID of the USUBJID variable :)
let $dmusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all other datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[not(@Name='DM')]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OIDs of the --DY and --DTC variables :)
let $dyoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'DY') and string-length(@Name)=4]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $dyname := concat($name,'DY')
let $dtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'DTC') and string-length(@Name)=5]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $dtcname := doc(concat($base,$define))//odm:ItemDef[@OID=$dtcoid]/@Name
(: and the OID of the USUBJID variable (might be different from the one in DM) :)
let $usubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$dtcoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the USUBJID value :)
let $usubjidvalue := $record/odm:ItemData[@ItemOID=$usubjidoid]/@Value
(: get the --DTC value :)
let $dtcvalue := $record/odm:ItemData[@ItemOID=$dtcoid]/@Value
(: and check whether it is a complete date - i.e. string-length at least 10 :)
let $iscompletedtcvalue := string-length($dtcvalue) >= 10 (: boolean :)
(: look up the record in the DM dataset and get the RFSTDTC :)
(: keeping worst case scenario into account that there are two records for the same USUBJID in DM - take the first :)
let $rfstdtcvalue := doc($dmdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$dmusubjidoid and @Value=$usubjidvalue]][1]/odm:ItemData[@ItemOID=$rfstdtcoid]/@Value
(: and check whether also RFSTDTC is complete :)
let $iscompleterfstdtcvalue := string-length($rfstdtcvalue) >= 10 (: boolean :)
let $dyvalue := $record/odm:ItemData[@ItemOID=$dyoid]/@Value
(: now calculate the DY value but only when RFSTDTC and DTC have a complete date part :)
let $dycalculated := (
if ($iscompleterfstdtcvalue and $iscompletedtcvalue) then
(: if there is one, we must strip off the time part :)
let $dtcvalueshort := substring($dtcvalue,1,10)
let $rfstdtcvalueshort := substring($rfstdtcvalue,1,10)
let $dycalc := (
if($dtcvalueshort castable as xs:date and $rfstdtcvalueshort castable as xs:date) then
days-from-duration(xs:date($dtcvalueshort)-xs:date($rfstdtcvalueshort))
else()
)
return $dycalc
else () (: one or both dates are not complete dates :)
)
(: for the FDA there is no day 0, DY can only be <0 or >0, first day is day 1 :)
let $dycalculatedfda := (
if($dycalculated >= 0) then
$dycalculated + 1
else (
$dycalculated
)
)
(: before comparing, check that the DY value is really an integer :)
where $dyvalue castable as xs:integer and $dycalculatedfda and $dyvalue and not($dycalculatedfda = $dyvalue)
return <warning rule="FDAC127" dataset="{data($name)}" variable="{data($dyname)}" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Invalid value for {data($dyname)}, calculated value={data($dycalculatedfda)}, observed value={data($dyvalue)}, in dataset {data($name)} </warning>
Incorrect value for --DY variable, single dataset or domain - Collection Study Day (--DY) variable value should be populated as defined by CDISC standards: --DY = (date portion of --DTC) - (date portion of RFSTDTC) +1 if --DTC is on or after RFSTDTC; --DY = (date portion of --DTC) - (date portion of RFSTDTC) if --DTC precedes RFSTDTC.
ALL
(: Rule FDAC127 - Incorrect value for --DY variable:
Collection Study Day (--DY) variable value should be populated as defined by CDISC standards: --DY = (date portion of --DTC) - (date portion of RFSTDTC) +1 if --DTC is on or after RFSTDTC; --DY = (date portion of --DTC) - (date portion of RFSTDTC) if --DTC precedes RFSTDTC.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
declare variable $domain external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the location of the DM dataset :)
let $dmdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/def:leaf/@xlink:href
let $dmdatasetlocation := concat($base,$dmdataset)
(: get the OID of the RFSTDTC variable :)
let $rfstdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='RFSTDTC']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: get the OID of the USUBJID variable :)
let $dmusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all other datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[(@Name=$domain or @Domain=$domain) and not(@Name='DM')]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OIDs of the --DY and --DTC variables :)
let $dyoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'DY') and string-length(@Name)=4]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $dyname := concat($name,'DY')
let $dtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'DTC') and string-length(@Name)=5]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $dtcname := doc(concat($base,$define))//odm:ItemDef[@OID=$dtcoid]/@Name
(: and the OID of the USUBJID variable (might be different from the one in DM) :)
let $usubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$dtcoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the USUBJID value :)
let $usubjidvalue := $record/odm:ItemData[@ItemOID=$usubjidoid]/@Value
(: get the --DTC value :)
let $dtcvalue := $record/odm:ItemData[@ItemOID=$dtcoid]/@Value
(: and check whether it is a complete date - i.e. string-length at least 10 :)
let $iscompletedtcvalue := string-length($dtcvalue) >= 10 (: boolean :)
(: look up the record in the DM dataset and get the RFSTDTC :)
(: keeping worst case scenario into account that there are two records for the same USUBJID in DM - take the first :)
let $rfstdtcvalue := doc($dmdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$dmusubjidoid and @Value=$usubjidvalue]][1]/odm:ItemData[@ItemOID=$rfstdtcoid]/@Value
(: and check whether also RFSTDTC is complete :)
let $iscompleterfstdtcvalue := string-length($rfstdtcvalue) >= 10 (: boolean :)
let $dyvalue := $record/odm:ItemData[@ItemOID=$dyoid]/@Value
(: now calculate the DY value but only when RFSTDTC and DTC have a complete date part :)
let $dycalculated := (
if ($iscompleterfstdtcvalue and $iscompletedtcvalue) then
(: if there is one, we must strip off the time part :)
let $dtcvalueshort := substring($dtcvalue,1,10)
let $rfstdtcvalueshort := substring($rfstdtcvalue,1,10)
let $dycalc := (
if($dtcvalueshort castable as xs:date and $rfstdtcvalueshort castable as xs:date) then
days-from-duration(xs:date($dtcvalueshort)-xs:date($rfstdtcvalueshort))
else()
)
return $dycalc
else () (: one or both dates are not complete dates :)
)
(: for the FDA there is no day 0, DY can only be <0 or >0, first day is day 1 :)
let $dycalculatedfda := (
if($dycalculated >= 0) then
$dycalculated + 1
else (
$dycalculated
)
)
(: before comparing, check that the DY value is really an integer :)
where $dyvalue castable as xs:integer and $dycalculatedfda and $dyvalue and not($dycalculatedfda = $dyvalue)
return <warning rule="FDAC127" dataset="{data($name)}" variable="{data($dyname)}" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Invalid value for {data($dyname)}, calculated value={data($dycalculatedfda)}, observed value={data($dyvalue)}, in dataset {data($name)} </warning>
Missing --STDY variable, when --STDTC variable is present - Study Day of Start (--STDY) variable should be included into dataset, when Start Study Date/Time (--STDTC) variable is present
ALL
(: Rule FDAC128 - Missing --STDY variable, when --STDTC variable is present:
Study Day of Start (--STDY) variable should be included into dataset, when Start Study Date/Time (--STDTC) variable is present
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all datasets, but not DM :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[not(@Name='DM')]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OIDs of the SDTY and STDTC variable :)
let $stdyoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STDY')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $stdyname := concat($name,'STDY') (: as in worst case, --SDTY may not be in dataset at all :)
let $stdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STDTC')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $stdtcname := doc(concat($base,$define))//odm:ItemDef[@OID=$stdtcoid]/@Name
(: STDY variable must be present when STDTC is present :)
where $stdtcname and not($stdyoid)
return <error rule="FDAC128" variable="{data($stdyname)}" dataset="{data($name)}" rulelastupdate="2015-02-11">Missing {data($stdyname)} variable in dataset {data($datasetname)}, when {data($stdtcname)} variable is present</error>
--STDY variable value is not populated - Study Day of Start (--STDY) variable value should be populated, when Start Study Date (--STDTC) and Subject Reference Start Date/Time (RFSTDTC) variables values are provided, and both of them include complete date part.
ALL
(: Rule FDAC129 - --STDY variable value is not populated:
Study Day of Start (--STDY) variable value should be populated, when Start Study Date (--STDTC) and Subject Reference Start Date/Time (RFSTDTC) variables values are provided, and both of them include complete date part.
P.S. When variable --STDY not present at all, do not throw an error, is already covered by rule FDAC0128
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the location of the DM dataset :)
let $dmdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/def:leaf/@xlink:href
let $dmdatasetlocation := concat($base,$dmdatasetname)
(: and the OIDs of the USUBJID and RFSTDTC variables :)
let $dmusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
let $rfstdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='RFSTDTC']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[not(@Name='DM')]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OIDs of the SDTY and STDTC variable :)
let $stdyoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STDY')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $stdyname := doc(concat($base,$define))//odm:ItemDef[@OID=$stdyoid]/@Name
let $stdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STDTC')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $stdtcname := doc(concat($base,$define))//odm:ItemDef[@OID=$stdtcoid]/@Name
(: and the OID of USUBJID in this dataset (can be different from in DM) :)
let $usubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records in the dataset that DO have both a STDCT value :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$stdtcoid]]
let $recnum := $record/@data:ItemGroupDataSeq
let $stdtcvalue := $record/odm:ItemData[@ItemOID=$stdtcoid]/@Value
(: check whether it is a complete date :)
let $iscompletestdtcdate := string-length($stdtcvalue) >= 10 (: boolean :)
(: get the USUBJID and get the corresponding RFSTDTC in the DM dataset :)
let $usubjidvalue := $record/odm:ItemData[@ItemOID=$usubjidoid]/@Value
(: keeping the worst case scenario into account that there is more than 1 record for a USUBJID in DM - take the first :)
let $rfstdtcvalue := doc($dmdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$dmusubjidoid and @Value=$usubjidvalue]][1]/odm:ItemData[@ItemOID=$rfstdtcoid]/@Value
(: and check whether RFSTDTC is a complete date :)
let $iscompleterfstdtcdate := string-length($rfstdtcvalue) >= 10
(: Get the value of the STDY variable (if any) :)
let $stdyvalue := $record/odm:ItemData[@ItemOID=$stdyoid]/@Value
(: STDY MUST be populated when the variable is in the dataset and when both RFSTDTC AND STDTC are complete dates :)
where $stdyoid and $iscompletestdtcdate and $iscompleterfstdtcdate and not($stdyvalue)
return <error rule="FDAC0129" dataset="{data($name)}" variable="{data($stdyname)}" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">{data($stdyname)} variable is not populated although both {data($stdtcname)} (value={data($stdtcvalue)}) and RFSTDTC (value={data($rfstdtcvalue)}) are complete dates</error>
--STDY variable value is imputed - Study Day of Start (--STDY) variable value should be not be imputed. It may be only populated, when both Start Study Date/Time (--STDTC) and Subject Reference Start Date/Time (RFSTDTC) variables values are provided, and both of them include complete date part.
ALL
(: Rule FDAC0130 - --STDY variable value is imputed
Study Day of Start (--STDY) variable value should be not be imputed. It may be only populated, when both Start Study Date/Time (--STDTC) and Subject Reference Start Date/Time (RFSTDTC) variables values are provided, and both of them include complete date part.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the location of the DM dataset :)
let $dmdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/def:leaf/@xlink:href
let $dmdatasetlocation := concat($base,$dmdatasetname)
(: and the OIDs of the USUBJID and RFSTDTC variables :)
let $dmusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
let $rfstdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='RFSTDTC']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[not(@Name='DM')]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OIDs of the SDTY and STDTC variable :)
let $stdyoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STDY')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $stdyname := doc(concat($base,$define))//odm:ItemDef[@OID=$stdyoid]/@Name
let $stdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STDTC')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $stdtcname := doc(concat($base,$define))//odm:ItemDef[@OID=$stdtcoid]/@Name
(: and the OID of USUBJID in this dataset (can be different from in DM) :)
let $usubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records in the dataset that DO have both a STDCT value :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$stdtcoid]]
let $recnum := $record/@data:ItemGroupDataSeq
let $stdtcvalue := $record/odm:ItemData[@ItemOID=$stdtcoid]/@Value
(: check whether it is a complete date :)
let $iscompletestdtcdate := string-length($stdtcvalue) >= 10 (: boolean :)
(: get the USUBJID and get the corresponding RFSTDTC in the DM dataset :)
let $usubjidvalue := $record/odm:ItemData[@ItemOID=$usubjidoid]/@Value
(: taking the worst case scenario into account that there is more than one record for a USUBJID in DM - take the first one :)
let $rfstdtcvalue := doc($dmdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$dmusubjidoid and @Value=$usubjidvalue]][1]/odm:ItemData[@ItemOID=$rfstdtcoid]/@Value
(: and check whether RFSTDTC is a complete date :)
let $iscompleterfstdtcdate := string-length($rfstdtcvalue) >= 10
(: Get the value of the STDY variable (if any) :)
let $stdyvalue := $record/odm:ItemData[@ItemOID=$stdyoid]/@Value
(: STDY may NOT be populated when of RFSTDTC or STDTC is an incomplete date :)
where $stdyoid and (not($iscompletestdtcdate) or not($iscompleterfstdtcdate)) and $stdyvalue
return <error rule="FDAC0130" dataset="{data($name)}" variable="{data($stdyname)}" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">{data($stdyname)} variable value {data($stdyvalue)} is imputed although one of {data($stdtcname)} (value={data($stdtcvalue)}) or RFSTDTC (value={data($rfstdtcvalue)}) is not a complete date</error>
--STDY variable value is imputed, single dataset or domain - Study Day of Start (--STDY) variable value should be not be imputed. It may be only populated, when both Start Study Date/Time (--STDTC) and Subject Reference Start Date/Time (RFSTDTC) variables values are provided, and both of them include complete date part.
ALL
(: Rule FDAC0130 - --STDY variable value is imputed
Study Day of Start (--STDY) variable value should be not be imputed. It may be only populated, when both Start Study Date/Time (--STDTC) and Subject Reference Start Date/Time (RFSTDTC) variables values are provided, and both of them include complete date part.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
declare variable $domain external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the location of the DM dataset :)
let $dmdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/def:leaf/@xlink:href
let $dmdatasetlocation := concat($base,$dmdatasetname)
(: and the OIDs of the USUBJID and RFSTDTC variables :)
let $dmusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
let $rfstdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='RFSTDTC']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[not(@Name='DM') and (@Name=$domain or @Domain=$domain)]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OIDs of the SDTY and STDTC variable :)
let $stdyoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STDY')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $stdyname := doc(concat($base,$define))//odm:ItemDef[@OID=$stdyoid]/@Name
let $stdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STDTC')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $stdtcname := doc(concat($base,$define))//odm:ItemDef[@OID=$stdtcoid]/@Name
(: and the OID of USUBJID in this dataset (can be different from in DM) :)
let $usubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records in the dataset that DO have both a STDCT value :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$stdtcoid]]
let $recnum := $record/@data:ItemGroupDataSeq
let $stdtcvalue := $record/odm:ItemData[@ItemOID=$stdtcoid]/@Value
(: check whether it is a complete date :)
let $iscompletestdtcdate := string-length($stdtcvalue) >= 10 (: boolean :)
(: get the USUBJID and get the corresponding RFSTDTC in the DM dataset :)
let $usubjidvalue := $record/odm:ItemData[@ItemOID=$usubjidoid]/@Value
(: taking the worst case scenario into account that there is more than one record for a USUBJID in DM - take the first one :)
let $rfstdtcvalue := doc($dmdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$dmusubjidoid and @Value=$usubjidvalue]][1]/odm:ItemData[@ItemOID=$rfstdtcoid]/@Value
(: and check whether RFSTDTC is a complete date :)
let $iscompleterfstdtcdate := string-length($rfstdtcvalue) >= 10
(: Get the value of the STDY variable (if any) :)
let $stdyvalue := $record/odm:ItemData[@ItemOID=$stdyoid]/@Value
(: STDY may NOT be populated when of RFSTDTC or STDTC is an incomplete date :)
where $stdyoid and (not($iscompletestdtcdate) or not($iscompleterfstdtcdate)) and $stdyvalue
return <error rule="FDAC0130" dataset="{data($name)}" variable="{data($stdyname)}" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">{data($stdyname)} variable value {data($stdyvalue)} is imputed although one of {data($stdtcname)} (value={data($stdtcvalue)}) or RFSTDTC (value={data($rfstdtcvalue)}) is not a complete date</error>
Incorrect value for --STDY variable - Study Day of Start (--STDY) variable value should be populated as defined by CDISC standards: --STDY = (date portion of --STDTC) - (date portion of RFSTDTC) +1 if --STDTC is on or after RFSTDTC; --STDY = (date portion of --STDTC) - (date portion of RFSTDTC) if --STDTC precedes RFSTDTC
ALL
(: Rule FDAC131 - Incorrect value for --STDY variable:
Study Day of Start (--STDY) variable value should be populated as defined by CDISC standards: --STDY = (date portion of --STDTC) - (date portion of RFSTDTC) +1 if --STDTC is on or after RFSTDTC; --STDY = (date portion of --STDTC) - (date portion of RFSTDTC) if --STDTC precedes RFSTDTC.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the location of the DM dataset :)
let $dmdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/def:leaf/@xlink:href
let $dmdatasetlocation := concat($base,$dmdataset)
(: get the OID of the RFSTDTC variable :)
let $rfstdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='RFSTDTC']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: get the OID of the USUBJID variable :)
let $dmusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all other datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[not(@Name='DM')]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OIDs of the --DY and --DTC variables :)
let $stdyoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STDY') and string-length(@Name)=6]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $stdyname := concat($name,'STDY')
let $stdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STDTC') and string-length(@Name)=7]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $stdtcname := doc(concat($base,$define))//odm:ItemDef[@OID=$stdtcoid]/@Name
(: and the OID of the USUBJID variable (might be different from the one in DM) :)
let $usubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$stdtcoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the USUBJID value :)
let $usubjidvalue := $record/odm:ItemData[@ItemOID=$usubjidoid]/@Value
(: get the --DTC value :)
let $stdtcvalue := $record/odm:ItemData[@ItemOID=$stdtcoid]/@Value
(: and check whether it is a complete date - i.e. string-length at least 10 :)
let $iscompletestdtcvalue := string-length($stdtcvalue) >= 10 (: boolean :)
(: look up the record in the DM dataset and get the RFSTDTC :)
(: taking the worst case scenario into account that there is more than one record for a USUBJID in DM - take the first one :)
let $rfstdtcvalue := doc($dmdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$dmusubjidoid and @Value=$usubjidvalue]][1]/odm:ItemData[@ItemOID=$rfstdtcoid]/@Value
(: and check whether also RFSTDTC is complete :)
let $iscompleterfstdtcvalue := string-length($rfstdtcvalue) >= 10 (: boolean :)
let $stdyvalue := $record/odm:ItemData[@ItemOID=$stdyoid]/@Value
(: now calculate the DY value but only when RFSTDTC and STDTC have a complete date part :)
let $stdycalculated := (
if ($iscompleterfstdtcvalue and $iscompletestdtcvalue) then
(: if there is one, we must strip off the time part :)
let $stdtcvalueshort := substring($stdtcvalue,1,10)
let $rfstdtcvalueshort := substring($rfstdtcvalue,1,10)
let $stdycalc := (
if($stdtcvalueshort castable as xs:date and $rfstdtcvalueshort castable as xs:date) then
days-from-duration(xs:date($stdtcvalueshort)-xs:date($rfstdtcvalueshort))
else()
)
return $stdycalc
else () (: one or both dates are not complete dates :)
)
(: for the FDA there is no day 0, DY can only be <0 or >0, first day is day 1 :)
let $stdycalculatedfda := (
if($stdycalculated >= 0) then
$stdycalculated + 1
else (
$stdycalculated
)
)
(: before comparing, also check whether the value is really an integer :)
where $stdyvalue castable as xs:integer and $stdycalculatedfda and $stdyvalue and not($stdycalculatedfda = $stdyvalue)
return <error dataset="{data($name)}" variable="{data($stdyname)}" rule="FDAC131" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Invalid value for {data($stdyname)}, calculated value={data($stdycalculatedfda)}, observed value={data($stdyvalue)}, in dataset {data($name)} </error>
Missing --ENDY variable, when --ENDTC variable is present - Study Day of End (--ENDY) variable should be included into dataset, when End Study Date/Time (--ENDTC) variable is present
ALL
(: Rule FDAC132 - Missing --ENDY variable, when --ENDTC variable is present
Study Day of End (--ENDY) variable should be included into dataset, when End Study Date/Time (--ENDTC) variable is present
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[not(@Name='DM')]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OIDs of the ENTY and STDTC variable :)
let $endyoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ENDY')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $endyname := concat($name,'ENDY') (: as in worst case, --SDTY may not be in dataset at all :)
let $endtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ENDTC')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $endtcname := doc(concat($base,$define))//odm:ItemDef[@OID=$endtcoid]/@Name
(: STDY variable must be present when STDTC is present :)
where $endtcname and not($endyoid)
return <error rule="FDAC132" dataset="{data($name)}" variable="{data($endyname)}" rulelastupdate="2015-02-10">Missing {data($endyname)} variable in dataset {data($datasetname)}, when {data($endtcname)} variable is present</error>
--ENDY variable value is not populated - Study Day of End (--ENDY) variable value should be populated, when End Study Date/Time (--ENDTC) and Subject Reference Start Date/Time (RFSTDTC) variables values are provided, and both of them include complete date part
ALL
(: Rule FDAC133 - --ENDY variable value is not populated:
Study Day of End (--ENDY) variable value should be populated, when End Study Date/Time (--ENDTC) and Subject Reference Start Date/Time (RFSTDTC) variables values are provided, and both of them include complete date part.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the location of the DM dataset :)
let $dmdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/def:leaf/@xlink:href
let $dmdatasetlocation := concat($base,$dmdatasetname)
(: and the OIDs of the USUBJID and RFSTDTC variables :)
let $dmusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
let $rfstdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='RFSTDTC']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[not(@Name='DM')]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OIDs of the ENDY and ENDTC variable :)
let $endyoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ENDY')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $endyname := doc(concat($base,$define))//odm:ItemDef[@OID=$endyoid]/@Name
let $endtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ENDTC')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $endtcname := doc(concat($base,$define))//odm:ItemDef[@OID=$endtcoid]/@Name
(: and the OID of USUBJID in this dataset (can be different from in DM) :)
let $usubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records in the dataset that DO have both an ENDCT value :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$endtcoid]]
let $recnum := $record/@data:ItemGroupDataSeq
let $endtcvalue := $record/odm:ItemData[@ItemOID=$endtcoid]/@Value
(: check whether it is a complete date :)
let $iscompleteendtcdate := string-length($endtcvalue) >= 10 (: boolean :)
(: get the USUBJID and get the corresponding RFSTDTC in the DM dataset :)
let $usubjidvalue := $record/odm:ItemData[@ItemOID=$usubjidoid]/@Value
(: taking the worst case scenario into account that there is more than 1 record for a USUBJID in DM - take the first one :)
let $rfstdtcvalue := doc($dmdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$dmusubjidoid and @Value=$usubjidvalue]][1]/odm:ItemData[@ItemOID=$rfstdtcoid]/@Value
(: and check whether RFSTDTC is a complete date :)
let $iscompleterfstdtcdate := string-length($rfstdtcvalue) >= 10
(: Get the value of the STDY variable (if any) :)
let $endyvalue := $record/odm:ItemData[@ItemOID=$endyoid]/@Value
(: ENDY MUST be populated when the variable is in the dataset and when both ENSTDTC AND ENDTC are complete dates :)
where $endyoid and $iscompleteendtcdate and $iscompleterfstdtcdate and not($endyvalue)
return <error rule="FDAC0133" dataset="{data($name)}" variable="{data($endyname)}" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">{data($endyname)} variable is not populated although both {data($endtcname)} (value={data($endtcvalue)}) and RFSTDTC (value={data($rfstdtcvalue)}) are complete dates</error>
CODTC is populated, when comment is a child record of another domain - The value of Date/Time of Comment (CODTC) should be NULL, when comments are related to a specific parent record or group of parent records in a domain (RDOMAIN, IDVAR and IDVARVAL are populated
CO
(: Rule FDAC134 - CODTC is populated, when comment is a child record of another domain:
The value of Date/Time of Comment (CODTC) should be NULL, when comments are related to a specific parent record or group of parent records in a domain (RDOMAIN, IDVAR and IDVARVAL are populated)
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the CO dataset :)
let $codataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='CO']
let $codatasetname := $codataset/def:leaf/@xlink:href
let $codatasetlocation := concat($base,$codatasetname)
(: we need the OIDs of the CODTC, RDOMAIN, IDVAR and IDVARVAL variables :)
let $codtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='CODTC']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='CO']/odm:ItemRef/@ItemOID
return $a
)
let $rdomainoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='RDOMAIN']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='CO']/odm:ItemRef/@ItemOID
return $a
)
let $idvaroid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='IDVAR']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='CO']/odm:ItemRef/@ItemOID
return $a
)
let $idvarvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='IDVARVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='CO']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all datasets in the CO dataset :)
for $record in doc($codatasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of the CODTC data point, if any :)
let $codtcvalue := $record/odm:ItemData[@ItemOID=$codtcoid]/@Value
(: and those of the RDOMAIN, IDVAR and IDVARVAL data points (if any) :)
let $rdomainvalue := $record/odm:ItemData[@ItemOID=$rdomainoid]/@Value
let $idvarvalue := $record/odm:ItemData[@ItemOID=$idvaroid]/@Value
let $idvarvalvalue := $record/odm:ItemData[@ItemOID=$idvarvaloid]/@Value
(: when there is a value for as wel RDOMAIN, IDVAR and IDVARVAL,
a value for CODTC is NOT allowed :)
where ($rdomainvalue and $idvarvalue and $idvarvalue) and $codtcvalue
return <warning rule="FDAC0134" dataset="CO" variable="CODTC" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">CODTC is populated (value={data($codtcvalue)}), although comment is a child record of another domain, with RDOMAIN={data($rdomainvalue)}, IDVAR={data($idvarvalue)} and IDVARVAL={data($idvarvalue)}</warning>
--ENDY variable value is imputed - Study Day of End (--ENDY) variable value should be not be imputed. It may be only populated, when both End Study Date/Time (--ENDTC) and Subject Reference Start Date/Time (RFSTDTC) variables values are provided, and both of them include complete date part
ALL
(: Rule FDAC0135 - --ENDY variable value is imputed:
Study Day of End (--ENDY) variable value should be not be imputed. It may be only populated, when both End Study Date/Time (--ENDTC) and Subject Reference Start Date/Time (RFSTDTC) variables values are provided, and both of them include complete date part.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the location of the DM dataset :)
let $dmdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/def:leaf/@xlink:href
let $dmdatasetlocation := concat($base,$dmdatasetname)
(: and the OIDs of the USUBJID and RFSTDTC variables :)
let $dmusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
let $rfstdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='RFSTDTC']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[not(@Name='DM')]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OIDs of the SDTY and STDTC variable :)
let $endyoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ENDY')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $endyname := doc(concat($base,$define))//odm:ItemDef[@OID=$endyoid]/@Name
let $endtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ENDTC')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $endtcname := doc(concat($base,$define))//odm:ItemDef[@OID=$endtcoid]/@Name
(: and the OID of USUBJID in this dataset (can be different from in DM) :)
let $usubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records in the dataset that DO have both a ENDCT value :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$endtcoid]]
let $recnum := $record/@data:ItemGroupDataSeq
let $endtcvalue := $record/odm:ItemData[@ItemOID=$endtcoid]/@Value
(: check whether it is a complete date :)
let $iscompletestdtcdate := string-length($endtcvalue) >= 10 (: boolean :)
(: get the USUBJID and get the corresponding RFSTDTC in the DM dataset :)
let $usubjidvalue := $record/odm:ItemData[@ItemOID=$usubjidoid]/@Value
(: taking worst case scenario into account that there is more than 1 record for a USUBJID in DM - take the first one :)
let $rfstdtcvalue := doc($dmdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$dmusubjidoid and @Value=$usubjidvalue]][1]/odm:ItemData[@ItemOID=$rfstdtcoid]/@Value
(: and check whether RFSTDTC is a complete date :)
let $iscompleterfstdtcdate := string-length($rfstdtcvalue) >= 10
(: Get the value of the STDY variable (if any) :)
let $endyvalue := $record/odm:ItemData[@ItemOID=$endyoid]/@Value
(: ENDY may NOT be populated when of RFSTDTC or ENDTC is an incomplete date :)
where $endyoid and (not($iscompletestdtcdate) or not($iscompleterfstdtcdate)) and $endyvalue
return <error rule="FDAC0135" dataset="{data($name)}" variable="{data($endyname)}" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">{data($endyname)} variable value {data($endyvalue)} is imputed although one of {data($endtcname)} (value={data($endtcvalue)}) or RFSTDTC (value={data($rfstdtcvalue)}) is not a complete date</error>
Incorrect value for --ENDY variable - Study Day of End (--ENDY) variable value should be populated as defined by CDISC standards: --ENDY = (date portion of --STDTC) - (date portion of RFSTDTC) +1 if --ENDTC is on or after RFSTDTC; --ENTDY = (date portion of --ENDTC) - (date portion of RFSTDTC) if --ENDTC precedes RFSTDTC
ALL
(: Rule FDAC0136 - Incorrect value for --ENDY variable:
Study Day of End (--ENDY) variable value should be populated as defined by CDISC standards: --ENDY = (date portion of --STDTC) - (date portion of RFSTDTC) +1 if --ENDTC is on or after RFSTDTC; --ENTDY = (date portion of --ENDTC) - (date portion of RFSTDTC) if --ENDTC precedes RFSTDTC.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the location of the DM dataset :)
let $dmdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/def:leaf/@xlink:href
let $dmdatasetlocation := concat($base,$dmdataset)
(: get the OID of the RFSTDTC variable :)
let $rfstdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='RFSTDTC']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: get the OID of the USUBJID variable :)
let $dmusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all other datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[not(@Name='DM')]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OIDs of the ENDY and ENDTC variables :)
let $endyoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ENDY') and string-length(@Name)=6]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $endyname := concat($name,'ENDY') (: as in may not be in the set of variables :)
let $endtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ENDTC') and string-length(@Name)=7]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $endtcname := doc(concat($base,$define))//odm:ItemDef[@OID=$endtcoid]/@Name
(: and the OID of the USUBJID variable (might be different from the one in DM) :)
let $usubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records that have an ENDTC data point :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$endtcoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the USUBJID value :)
let $usubjidvalue := $record/odm:ItemData[@ItemOID=$usubjidoid]/@Value
(: get the --DTC value :)
let $endtcvalue := $record/odm:ItemData[@ItemOID=$endtcoid]/@Value
(: and check whether it is a complete date - i.e. string-length at least 10 :)
let $iscompletestdtcvalue := string-length($endtcvalue) >= 10 (: boolean :)
(: look up the record in the DM dataset and get the RFSTDTC :)
(: taking worst case scenario into account that there is more than 1 record for a USUBJID in DM - take the first one :)
let $rfstdtcvalue := doc($dmdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$dmusubjidoid and @Value=$usubjidvalue]][1]/odm:ItemData[@ItemOID=$rfstdtcoid]/@Value
(: and check whether also RFSTDTC is complete :)
let $iscompleterfstdtcvalue := string-length($rfstdtcvalue) >= 10 (: boolean :)
let $endyvalue := $record/odm:ItemData[@ItemOID=$endyoid]/@Value
(: now calculate the DY value but only when RFSTDTC and ENDTC have a complete date part :)
let $endycalculated := (
if ($iscompleterfstdtcvalue and $iscompletestdtcvalue) then
(: if there is one, we must strip off the time part :)
let $endtcvalueshort := substring($endtcvalue,1,10)
let $rfstdtcvalueshort := substring($rfstdtcvalue,1,10)
let $endycalc := (
if($endtcvalueshort castable as xs:date and $rfstdtcvalueshort castable as xs:date) then
days-from-duration(xs:date($endtcvalueshort)-xs:date($rfstdtcvalueshort))
else()
)
return $endycalc
else () (: one or both dates are not complete dates :)
)
(: for the FDA there is no day 0, DY can only be <0 or >0, first day is day 1 :)
let $endycalculatedfda := (
if($endycalculated >= 0) then
$endycalculated + 1
else (
$endycalculated
)
)
(: before comparing, check that the ENDY value is really an integer :)
where $endyvalue castable as xs:integer $endycalculatedfda and $endyvalue and not($endycalculatedfda = $endyvalue)
return <error rule="FDAC136" dataset="{data($name)}" variable="{data($endyname)}" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Invalid value for {data($endyname)}, calculated value={data($endycalculatedfda)}, observed value={data($endyvalue)}, in dataset {data($datasetname)} </error>
Value for --STRF is populated, when RFSTDTC is NULL - Start Relative to Reference Period (--STRF) should not be populated for subjects with missing value for Reference Start Date/Time (RFSTDTC)
ALL
(: TODO: not tested yet - we need a good test submission :)
(: Rule FDAC0137 - Value for --STRF is populated, when RFSTDTC is NULL
Start Relative to Reference Period (--STRF) should not be populated for subjects with missing value for Reference Start Date/Time (RFSTDTC)
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the location of the DM dataset :)
let $dmdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/def:leaf/@xlink:href
let $dmdatasetlocation := concat($base,$dmdataset)
(: get the OID of the RFSTDTC variable :)
let $rfstdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='RFSTDTC']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: get the OID of the USUBJID variable :)
let $dmusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the datasets except for the DM dataset :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OID of the --STRF variable (if any) :)
let $strfoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STRF')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $strfname := doc(concat($base,$define))//odm:ItemDef[@OID=$strfoid]/@Name
(: get the OID of the USUBJID variable (can be different from within DM) :)
let $usubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$strfoid]]
let $recnum := $record/@data:ItemGroupDataSeq
let $strfvalue := $record/odm:ItemData[@ItemOID=$strfoid]/@Value
(: and get the local USUBJID :)
let $usubjid := $record/odm:ItemData[@ItemOID=$usubjidoid]/@Value
(: look up the record in the DM dataset and get the RFSTDTC value :)
let $rfstdtcvalue := doc(concat($base,$define))//odm:ItemGroupData[odm:ItemData[@ItemOID=$dmusubjidoid and @Value=$usubjid]]/odm:ItemData[@ItemOID=$rfstdtcoid]/@Value
(: in case there is no RFSTDTC value, STRF may not be populated :)
where not($rfstdtcvalue) and $strfvalue
return <warning rule="FDAC0137" dataset="{data($name)}" variable="{data($strfname)}" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Value for {data($strfname)} is populated(value={data($strfvalue)}), when RFSTDTC is NULL in dataset {data($datasetname)}</warning>
Value for --ENRF is populated, when RFENDTC is NULL - End Relative to Reference Period (--ENRF) should not be populated for subjects with missing value for Reference End Date/Time (RFENDTC)
ALL
(: FDAC0138 - Value for --ENRF is populated, when RFENDTC is NULL:
End Relative to Reference Period (--ENRF) should not be populated for subjects with missing value for Reference End Date/Time (RFENDTC)
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the location of the DM dataset :)
let $dmdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/def:leaf/@xlink:href
let $dmdatasetlocation := concat($base,$dmdataset)
(: get the OID of the RFENDTC variable :)
let $rfendtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='RFENDTC']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: get the OID of the USUBJID variable :)
let $dmusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the datasets except for the DM dataset :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OID of the --ENRF variable (if any) :)
let $enrfoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ENRF')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $enrfname := doc(concat($base,$define))//odm:ItemDef[@OID=$enrfoid]/@Name
(: get the OID of the USUBJID variable (can be different from within DM) :)
let $usubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: itertate over all records in the dataset that do have an ENRF data point :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$enrfoid]]
let $recnum := $record/@data:ItemGroupDataSeq
let $enrfvalue := $record/odm:ItemData[@ItemOID=$enrfoid]/@Value
(: and get the local USUBJID :)
let $usubjid := $record/odm:ItemData[@ItemOID=$usubjidoid]/@Value
(: look up the record in the DM dataset and get the RFSTDTC value :)
let $rfendtcvalue := doc(concat($base,$define))//odm:ItemGroupData[odm:ItemData[@ItemOID=$dmusubjidoid and @Value=$usubjid]]/odm:ItemData[@ItemOID=$rfendtcoid]/@Value
(: in case there is no RFSTDTC value, STRF may not be populated :)
where not($rfendtcvalue) and $enrfvalue
return <warning rule="FDAC0138" dataset="{data($name)}" variable="{data($enrfname)}" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Value for {data($enrfname)} is populated(value={data($enrfvalue)}), when RFENDTC is NULL in dataset {data($datasetname)}</warning>
Missing value for --TPTNUM, when --TPT is provided - Planned Time Point Number (--TPTNUM) should not be NULL, when Planned Time Point Name (--TPT) is populated
ALL
(: TODO: not well tested yet :)
(: Rule FDAC139 - Missing value for --TPTNUM, when --TPT is provided
Planned Time Point Number (--TPTNUM) should not be NULL, when Planned Time Point Name (--TPT) is populated
REMARK: this rule is related to rule FDAC0123 (Missing value for --TPT, when --TPTNUM is provided)
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all the datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OIDs of TPT and TPTNUM (if any) :)
let $tptoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TPT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $tptname := doc(concat($base,$define))//odm:ItemDef[@OID=$tptoid]/@Name
(: Get the OIDs of TPT and TPTNUM (if any) :)
let $tptnumoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TPTNUM')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $tptnumname := doc(concat($base,$define))//odm:ItemDef[@OID=$tptnumoid]/@Name
(: iterate over the records in the dataset that do have a TPT data point :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tptoid]]
let $recnum := $record/@data:ItemGroupDataSeq
let $tptvalue := $record/odm:ItemData[@ItemOID=$tptoid]/@Value
(: check whether there is a TPTNUM data point :)
where not($record/odm:ItemData[@ItemOID=$tptnumoid])
return <warning rule="FDAC139" dataset="{data($name)}" variable="{data($tptnumname)}" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">Planned Time Point Number {data($tptnumname)} should not be NULL, when Planned Time Point Name {data($tptname)} is populated, value = {data($tptvalue)}</warning>
Missing values for TEENRL and TEDUR - At least one of Rule for End of Element (TEENRL) or Planned Duration of Element (TEDUR) should be populated in TE
TE
(: Rule FDAC0140 - Missing values for TEENRL and TEDUR
At least one of Rule for End of Element (TEENRL) or Planned Duration of Element (TEDUR) should be populated in TE
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the location of the TE dataset :)
let $tedataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TE']
let $tedatasetname := $tedataset/def:leaf/@xlink:href
let $tedatasetlocation := concat($base,$tedatasetname)
(: and get the OIDs of TEENRL and TEDUR in TE :)
let $teenrloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TEENRL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TE']/odm:ItemRef/@ItemOID
return $a
)
let $teduroid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TEDUR']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TE']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records in the TE dataset :)
for $record in doc($tedatasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the values for TEENRL and TEDUR (if any) :)
let $teenrlvalue := $record/odm:ItemData[@ItemOID=$teenrloid]/@Value
let $tedurvalue := $record/odm:ItemData[@ItemOID=$teduroid]/@Value
(: at least one must be populated :)
where not($teenrlvalue) and not($tedurvalue)
return <warning rule="FDAC0140" dataset="TE" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">Missing values for TEENRL and TEDUR</warning>
Missing value for --TPTREF, when --ELTM is provided - Time Point Reference (--TPTREF) should not be NULL, when Planned Elapsed Time from Time Point Ref (--ELTM) is populated
ALL
(: Rule FDAC141 - Missing value for --TPTREF, when --ELTM is provided
Time Point Reference (--TPTREF) should not be NULL, when Planned Elapsed Time from Time Point Ref (--ELTM) is populated :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all datasets except for DM :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[not(@Name='DM')]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OID of the TPTREF and ELTM variable (when present) :)
let $tptrefoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TPTREF')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: let $tptrefname := doc(concat($base,$define))//odm:ItemDef[@OID=$tptrefoid]/@Name :)
let $tptrefname := concat($name,'TPTREF')
let $eltmoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ELTM')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $eltmname := doc(concat($base,$define))//odm:ItemDef[@OID=$eltmoid]/@Name
(: iterate over all the records that do have an ELTM data point :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$eltmoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of the TPTREF and ELTM data points (if any) :)
let $tptrefvalue := $record/odm:ItemData[@ItemOID=$tptrefoid]/@Value
let $eltmvalue := $record/odm:ItemData[@ItemOID=$eltmoid]/@Value
(: when ELTM is populated, TPTREF must be present :)
where $eltmvalue and not($tptrefvalue)
return <warning rule="FDAC0141" variable="{data($tptrefname)}" dataset="{data($name)}" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Missing value for {data($tptrefname)} when {data($eltmname)} is populated, value={data($eltmvalue)}</warning>
Missing --ENTPT variable, when --ENRTPT variable is present - End Reference Time Point (--ENTPT) variable must be included into the domain, when End Relative to Reference Time Point (--ENRTPT) variable is present
ALL
(: TODO: not well tested yet :)
(: Rule FDAC0142 - Missing --ENTPT variable, when --ENRTPT variable is present:
End Reference Time Point (--ENTPT) variable must be included into the domain, when End Relative to Reference Time Point (--ENRTPT) variable is present
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all datasets except for DM :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[not(@Name='DM')]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OID of the ENRTPT and ENTPT variable (when present) :)
let $enrtptoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ENRTPT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $enrtptname := doc(concat($base,$define))//odm:ItemDef[@OID=$enrtptoid]/@Name
let $entptoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ENTPT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $entptname := concat($name,'ENTPT') (: it might be that is not in the dataset :)
(: when ENRTPT is present, also ENTPT must be present :)
where $enrtptoid and not($entptoid)
return <error rule="FADC142" variable="{data($enrtptname)}" dataset="{data($name)}" rulelastupdate="2015-02-11">Missing {data($entptname)} variable, when {data($enrtptname)} variable is present</error>
Missing --ENRTPT variable, when --ENTPT variable is present - End Reference to Reference Time Point (--ENRTPT) variable must be included into the domain, when End Relative Time Point (--ENTPT) variable is present
ALL
(: TODO: not well tested yet :)
(: Rule FDAC0143 - Missing --ENRTPT variable, when --ENTPT variable is present
End Reference to Reference Time Point (--ENRTPT) variable must be included into the domain, when End Relative Time Point (--ENTPT) variable is present
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all datasets except for DM :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[not(@Name='DM')]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OID of the ENRTPT and ENTPT variable (when present) :)
let $enrtptoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ENRTPT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $enrtptname := concat($name,'ENRTPT')
let $entptoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ENTPT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $entptname := doc(concat($base,$define))//odm:ItemDef[@OID=$entptoid]/@Name
(: when ENTPT is present, also ENRTPT must be present :)
where $entptoid and not($enrtptoid)
return <error rule="FADC143" variable="{data($enrtptname)}" dataset="{data($name)}" rulelastupdate="2015-02-11">Missing {data($enrtptname)} variable, when {data($entptname)} variable is present</error>
Missing --STTPT variable, when --STRTPT variable is present - Start Reference Time Point (--STTPT) variable must be included into the domain, when Start Relative to Reference Time Point (--STRTPT) variable is present
ALL
(: TODO: not well tested yet :)
(: Rule FDAC0144 - Missing --STTPT variable, when --STRTPT variable is present:
Start Reference Time Point (--STTPT) variable must be included into the domain, when Start Relative to Reference Time Point (--STRTPT) variable is present
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all datasets except for DM :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[not(@Name='DM')]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OID of the STTPT and STRTPT variable (when present) :)
let $strtptoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STTPT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $strtptname := doc(concat($base,$define))//odm:ItemDef[@OID=$strtptoid]/@Name
let $strtptname := concat($name,'STRTPT')
let $sttptoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STTPT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $sttptname := concat($name,'STTPT')
(: when STRTPT is present, also STTPT must be present :)
where $strtptoid and not($sttptoid)
return <error rule="FADC144" dataset="{data($name)}" variable="{data($sttptname)}" rulelastupdate="2015-02-11">Missing {data($sttptname)} variable, when {data($strtptname)} variable is present</error>
Missing --STRTPT variable, when --STTPT variable is present - Start Reference to Reference Time Point (--STRTPT) variable must be included into the domain, when Start Relative Time Point (--STTPT) variable is present
ALL
(: TODO: not well tested yet :)
(: Rule FDAC0145 - Missing --STRTPT variable, when --STTPT variable is present:
Start Reference to Reference Time Point (--STRTPT) variable must be included into the domain, when Start Relative Time Point (--STTPT) variable is present
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all datasets except for DM :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[not(@Name='DM')]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OID of the STTPT and STRTPT variable (when present) :)
let $strtptoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STRTPT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $strtptname := concat($name,'STRTPT')
let $sttptoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STTPT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $sttptname := doc(concat($base,$define))//odm:ItemDef[@OID=$sttptoid]/@Name
(: when STTPT is present, also STRTPT must be present :)
where $sttptoid and not($strtptoid)
return <error rule="FADC145" dataset="{data($name)}" variable="{data($strtptname)}" rulelastupdate="2015-02-11">Missing {data($strtptname)} variable, when {data($sttptname)} variable is present</error>
Neither --STDTC nor --STDY are populated in DS - At least one value of two variables Start Date/Time (--STDTC) and Start Study Day (--STDY) should be populated
DS
(: Rule FDAC0146 - Neither --STDTC nor --STDY are populated in DS:
At least one value of two variables Start Date/Time (--STDTC) and Start Study Day (--STDY) should be populated
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the location of the DS dataset :)
let $dsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DS']
let $dsdatasetname := $dsdataset/def:leaf/@xlink:href
let $dsdatasetlocation := concat($base,$dsdatasetname)
(: Get the OID of the DSSTDTC and DSSTDY variables :)
let $dssdttcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='DSSTDTC']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DS']/odm:ItemRef/@ItemOID
return $a
)
let $dsstdyoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='DSSTDY']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DS']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records in the dataset :)
for $record in doc($dsdatasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: and the values of the DSSDTDTC and DSSTDY data points (when present) :)
let $dsstdtcvalue := $record/odm:ItemData[@ItemOID=$dssdttcoid]/@Value
let $dsstdyvalue := $record/odm:ItemData[@ItemOID=$dsstdyoid]/@Value
(: at least one of both must be present :)
where not($dsstdtcvalue) and not($dsstdyvalue)
return <warning rule="FDAC0146" dataset="DS" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Neither DSSDTDTC nor DSSTDY are populated in dataset {data($dsdatasetname)}</warning>
--STRF Time point for non-occurred event or intervention is provided - Value of Start Relative to Reference Period (--STRF) should not be populated, when an event or intervention is marked as not occurred
INTERVENTIONS
EVENTS
(: Rule FDAC0147-A Time point for non-occurred event or intervation is provided:
Value of Start Relative to Reference Period (--STRF) should not be populated, when an event or intervention is marked as not occurred (--OCCUR='N')
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all the datasets , but only the INTERVENTIONS and EVENTS ones :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[upper-case(@def:Class)='INTERVENTIONS' or upper-case(@def:Class)='EVENTS']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OID of the STRF and OCCUR variables :)
let $strfoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STRF')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $strfname := concat($name,'STRF')
let $occuroid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'OCCUR')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $occurname := doc(concat($base,$define))//odm:ItemDef[@OID=$occuroid]/@Name
(: iterate over all the records that have an --OCCUR data point :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$occuroid]]
let $recnum := $record/@data:ItemGroupDataSeq
let $occurvalue := $record/odm:ItemData[@ItemOID=$occuroid]/@Value
(: check whether STRF is populated - if so, get the value :)
let $strfvalue := $record/odm:ItemData[@ItemOID=$strfoid]/@Value
(: STRF amay NOT be present when OCCUR is present :)
where $occurvalue and $strfvalue
return <warning rule="FDAC0147-A" variable="{data($strfname)}" dataset="{data($name)}" rulelastupdate="2016-03-30" recordnumber="{data($recnum)}">Value of Start Relative to Reference Period ({data($strfname)} should not be populated for non-occurred event or intervation is provided, with value of {data($occurname)}={data($occurvalue)}</warning>
--ENRF Time point for non-occurred event or intervention is provided - Value of End Relative to Reference Period (--ENRF) should not be populated, when an event or intervention is marked as not occurred
INTERVENTIONS
EVENTS
(: Rule FDAC0147- Time point for non-occurred event or intervation is provided:
Value of Start Relative to Reference Period (--STRF) or End Relative to Reference Period (--ENRF) should not be populated, when an event or intervention is marked as not occurred (--OCCUR='N')
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all the datasets , but only the INTERVENTIONS and EVENTS ones :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[upper-case(@def:Class)='INTERVENTIONS' or upper-case(@def:Class)='EVENTS']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OID of the ENRF and OCCUR variables :)
let $enrfoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ENRF')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $enrfname := concat($name,'ENRF')
let $occuroid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'OCCUR')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $occurname := doc(concat($base,$define))//odm:ItemDef[@OID=$occuroid]/@Name
(: iterate over all the records that have an --OCCUR data point :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$occuroid]]
let $recnum := $record/@data:ItemGroupDataSeq
let $occurvalue := $record/odm:ItemData[@ItemOID=$occuroid]/@Value
(: check whether ENRF are populated - if so, get the value :)
let $enrfvalue := $record/odm:ItemData[@ItemOID=$enrfoid]/@Value
(: ENRF may NOT be present when OCCUR is present :)
where $occurvalue and $enrfvalue
return <warning rule="FDAC0147-B" dataset="{data($name)}" variable="{data($enrfname)}" rulelastupdate="2016-03-30" recordnumber="{data($recnum)}">Value of End Relative to Reference Period ({data($enrfname)} should not be populated for non-occurred event or intervation is provided, with value of {data($occurname)}={data($occurvalue)}</warning>
Both --DOSE and --DOSTXT values are populated - Only one of Dose (--DOSE) or Dose Description (--DOSTXT) variables must be populated on the same record
INTERVENTIONS
(: Rule FDAC0155 - Both --DOSE and --DOSTXT values are populated:
Only one of Dose (--DOSE) or Dose Description (--DOSTXT) variables must be populated on the same record (Interventions)
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all the datasets , but only the INTERVENTIONS ones :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[upper-case(@def:Class)='INTERVENTIONS']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OID of the --DOSE and --DOSTXT variables :)
let $doseoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'DOSE')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $dosename := doc(concat($base,$define))//odm:ItemDef[@OID=$doseoid]/@Name
let $dostxtoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'DOSTXT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $dostxtname := doc(concat($base,$define))//odm:ItemDef[@OID=$dostxtoid]/@Name
(: iterate over the records in the dataset, but ONLY when --DOSE and --DOSTXT have been defined :)
for $record in doc($datasetlocation)[$doseoid and $dostxtoid]//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: get the values of --DOSE and --DOSTXT (when present) :)
let $dosevalue := $record/odm:ItemData[@ItemOID=$doseoid]/@Value
let $dostxtvalue := $record/odm:ItemData[@ItemOID=$dostxtoid]/@Value
(: DOSE and DOSTXT values should not both be present in the same record :)
where $dosevalue and $dostxtvalue
return <error rule="FDAC0155" dataset="{data($name)}" variable="{data($dosename)}" rulelastupdate="2017-02-11" recordnumber="{data($recnum)}">Both {data($dosename)} and {data($dostxtname)} values are populated</error>
IDVARVAL value is populated, when RELTYPE values is populated - Variable Value (IDVARVAL) variable value should not be populated, when Relationship Type (RELTYPE) variable value is populated
RELREC
(: Rule FDAC157 - IDVARVAL value is populated, when RELTYPE values is populated:
Variable Value (IDVARVAL) variable value should not be populated, when Relationship Type (RELTYPE) variable value is populated
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the location of the RELREC dataset :)
let $relrecdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='RELREC']/def:leaf/@xlink:href
let $relrecdatasetlocation := concat($base,$relrecdatasetname)
(: and get the OIDs of the IDVARVAL and RELTYPE variables :)
let $idvarvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='IDVARVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='RELREC']/odm:ItemRef/@ItemOID
return $a
)
let $reltypeoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='RELTYPE']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='RELREC']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records in the dataset :)
for $record in doc($relrecdatasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the IDVARVAL and RELTYPE data points :)
let $idvarvalvalue := $record/odm:ItemData[@ItemOID=$idvarvaloid]/@Value
let $reltypevalue := $record/odm:ItemData[@ItemOID=$reltypeoid]/@Value
(: Variable Value (IDVARVAL) variable value should not be populated, when Relationship Type (RELTYPE) variable value is populated :)
where $reltypevalue and $idvarvalvalue
return <warning rule="FDAC157" dataset="RELREC" variable="IDVARVAL" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">IDVARVAL value is populated (value={data($idvarvalvalue)}, when RELTYPE values is populated (value={data($reltypevalue)})</warning>
Inappropriate usage of variables in CO domain - In Comments (CO) domain, only following Identifier and Timing variables that are permissible and may be added as appropriate when comments are not related to other domain records (RDOMAIN and IDVAR variables values are not populated): COGRPID, COREFID, COSPID, VISIT, VISITNUM, VISITDY, TAETORD, CODY, COTPT, COTPTNUM, COELTM, COTPTREF, CORFTDTC
ALL
(: Rule FDAC158 - Inappropriate usage of variables in CO domain:
In Comments (CO) domain, only following Identifier and Timing variables that are permissible and may be added as appropriate when comments are not related to other domain records (RDOMAIN and IDVAR variables values are not populated): COGRPID, COREFID, COSPID, VISIT, VISITNUM, VISITDY, TAETORD, CODY, COTPT, COTPTNUM, COELTM, COTPTREF, CORFTDTC.
We will test this on the level of the define.xml
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace functx = "http://www.functx.com";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: function to check whether a value is represented in a sequence (array) :)
declare function functx:is-value-in-sequence
($value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
let $allowedvariables := ('STUDYID','DOMAIN','RDOMAIN','USUBJID','COSEQ','IDVAR','IDVARVAL','COREF','COVAL','COEVAL','CODTC','COGRPID','COREFID','COSPID','VISIT','VISITNUM','VISITDY','TAETORD','CODY','COTPT','COTPTNUM','COELTM','COTPTREF','CORFTDTC')
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
for $varoid in doc(concat($base,$define))//odm:ItemGroupDef[@Name='CO']/odm:ItemRef/@ItemOID
let $varname := doc(concat($base,$define))//odm:ItemDef[@OID=$varoid]/@Name
(: check whether this variable is in the array of allowed variables :)
where not(functx:is-value-in-sequence($varname,$allowedvariables))
return <warning rule="FDAC158" dataset="CO" variable="{data($varname)}" rulelastupdate="2015-02-11">Variable {data($varname)} is not allowed in the CO dataset</warning>
Missing RDOMAIN value in CO, when IDVAR is populated - Value of Related Domain Abbreviation (RDOMAIN) variable must be populated, when value of Identifying Variable (IDVAR) variable is populated
CO
(: Rule FDAC160 - Missing RDOMAIN value in CO, when IDVAR is populated:
Value of Related Domain Abbreviation (RDOMAIN) variable must be populated, when value of Identifying Variable (IDVAR) variable is populated
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the location of the CO dataset :)
let $codataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='CO']/def:leaf/@xlink:href
let $codedatasetlocation := concat($base,$codataset)
(: Get the OIDs of the IDVARVAL and RDOMAIN variables :)
let $idvaroid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='IDVAR']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='CO']/odm:ItemRef/@ItemOID
return $a
)
let $rdomainoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='RDOMAIN']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='CO']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records in the dataset :)
for $record in doc($codedatasetlocation)//odm:ItemGroupData
let $recnum := $record//@data:ItemGroupDateSeq
(: Get the values of the IDVAR en RDOMAIN variables (when present) :)
let $idvarvalue := $record/odm:ItemData[@ItemOID=$idvaroid]/@Value
let $rdomainvalue := $record/odm:ItemData[@ItemOID=$rdomainoid]/@Value
(: When IDVAR is populated, RDOMAIN MUST be populated :)
where $idvarvalue and not($rdomainvalue)
return <error rule="FDAC160" dataset="CO" variable="RDOMAIN" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">RDOMAIN value is missing although IDVAR is populated (value={data($idvarvalue)}) in CO dataset {data($codataset)}</error>
Redundancy in paired variables values - Value of Category (--CAT) should not be identical to that in Domain Abbreviation (DOMAIN); Reported Term (--TERM); Name of Measurement, Test, or Examination (--TESTCD); Name of Treatment (--TRT); Body System or Organ Class (--BODSYS)
ALL
(: Rule FDAC161 - Redundancy in paired variables values:
Value of Category (--CAT) should not be identical to that in Domain Abbreviation (DOMAIN); Reported Term (--TERM); Name of Measurement, Test, or Examination (--TESTCD); Name of Treatment (--TRT); Body System or Organ Class (--BODSYS)
INTERVENTIONS, EVENTS, FINDINGS, TI
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all datasets that have a --CAT variable in the interventions, events findings domains and the TI dataset :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[upper-case(@def:Class)='INTERVENTIONS' or upper-case(@def:Class)='EVENTS' or upper-case(@def:Class)='FINDINGS' or @Domain='TI']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OID of the --CAT variable (if any) :)
let $catoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'CAT') and string-length(@Name)=5]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $catname := concat($name,'CAT')
(: similarly, get the OIDs of DOMAIN, TERM, TESTCD, TRT, BODSYS :)
let $domainoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='DOMAIN']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $termoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TERM') and string-length(@Name)=6]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $testcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TESTCD') and string-length(@Name)=8]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $trtoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TRT') and string-length(@Name)=5]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $bodsysoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'BODSYS') and string-length(@Name)=7]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records that do have a value for --CAT :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$catoid]]
let $recnum := $record/@data:ItemGroupDataSeq
let $catvalue := $record/odm:ItemData[@ItemOID=$catoid]/@Value
(: and get the values of the DOMAIN, TERM, TESTCD, TRT, BODSYS variables (when present) :)
let $domainvalue := $record/odm:ItemData[@ItemOID=$domainoid]/@Value
let $termvalue := $record/odm:ItemData[@ItemOID=$termoid]/@Value
let $testcdvalue := $record/odm:ItemData[@ItemOID=$testcdoid]/@Value
let $trtvalue := $record/odm:ItemData[@ItemOID=$trtoid]/@Value
let $bodsysvalue := $record/odm:ItemData[@ItemOID=$bodsysoid]/@Value
(: we do already have selected on the presence of a value for the CAT variable,
now compare it with the values of the DOMAIN, TERM, TESTCD, TRT, BODSYS variables
(when present) :)
where $catvalue=$domainvalue or $catvalue=$termvalue or $catvalue=$testcdvalue or $catvalue=$trtvalue or $catvalue=$bodsysvalue
return <warning rule="FDAC161" dataset="{data($name)}" variable="{data($catname)}" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Redundancy in paired variables values for {data($catname)} with value={data($catvalue)}.</warning>
Redundancy in paired variables values - Value of Subcategory (--SCAT) should not be identical to that in Domain Abbreviation (DOMAIN); Reported Term (--TERM); Name of Measurement, Test, or Examination (--TESTCD); Name of Treatment (--TRT); Body System or Organ Class (--BODSYS)
ALL
(: Rule FDAC162 - Redundancy in paired variables values:
Value of Subcategory (--SCAT) should not be identical to that in Domain Abbreviation (DOMAIN); Reported Term (--TERM); Name of Measurement, Test, or Examination (--TESTCD); Name of Treatment (--TRT); Body System or Organ Class (--BODSYS)
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all datasets that have a --SCAT variable in the interventions, events findings domains and the TI dataset :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[upper-case(@def:Class)='INTERVENTIONS' or upper-case(@def:Class)='EVENTS' or upper-case(@def:Class)='FINDINGS' or @Name='TI']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OID of the --SCAT variable (if any) :)
let $scatoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'SCAT') and string-length(@Name)=6]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $scatname := concat($name,'SCAT')
(: similarly, get the OIDs of DOMAIN, TERM, TESTCD, TRT, BODSYS :)
let $domainoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='DOMAIN']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $termoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TERM') and string-length(@Name)=6]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $testcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TESTCD') and string-length(@Name)=8]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $trtoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TRT') and string-length(@Name)=5]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $bodsysoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'BODSYS') and string-length(@Name)=7]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records that do have a value for --CAT :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$scatoid]]
let $recnum := $record/@data:ItemGroupDataSeq
let $scatvalue := $record/odm:ItemData[@ItemOID=$scatoid]/@Value
(: and get the values of the DOMAIN, TERM, TESTCD, TRT, BODSYS variables (when present) :)
let $domainvalue := $record/odm:ItemData[@ItemOID=$domainoid]/@Value
let $termvalue := $record/odm:ItemData[@ItemOID=$termoid]/@Value
let $testcdvalue := $record/odm:ItemData[@ItemOID=$testcdoid]/@Value
let $trtvalue := $record/odm:ItemData[@ItemOID=$trtoid]/@Value
let $bodsysvalue := $record/odm:ItemData[@ItemOID=$bodsysoid]/@Value
(: we do already have selected on the presence of a value for the CAT variable,
now compare it with the values of the DOMAIN, TERM, TESTCD, TRT, BODSYS variables
(when present) :)
where $scatvalue=$domainvalue or $scatvalue=$termvalue or $scatvalue=$testcdvalue or $scatvalue=$trtvalue or $scatvalue=$bodsysvalue
return <warning rule="FDAC162" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Redundancy in paired variables values for {data($scatname)} with value={data($scatvalue)}.</warning>
Unexpected value for IDVAR/IDVARVAL - Both Identifying Variable (IDVAR) and Identifying Variable Value (IDVARVAL) should not be populated, when relating information to the Demographics (DM) domain
SUPPQUAL
(: Rule FDAC164 - Unexpected value for IDVAR/IDVARVAL:
Both Identifying Variable (IDVAR) and Identifying Variable Value (IDVARVAL) should not be populated, when relating information to the Demographics (DM) domain
in SUPPxx datasets
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all SUPPxx datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[starts-with(@Name,'SUPP')]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OIDs of the IDVAR and IDVARVAL and RDOMAIN variables :)
let $idvaroid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='IDVAR']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $idvarvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='IDVARVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $rdomainoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='IDVARVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records in the dataset :)
for $record in doc($datasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the values for the IDVAR, IDVARVAL and RDOMAIN variables :)
let $idvarvalue := $record/odm:ItemData[@ItemOID=$idvaroid]/@Value
let $idvarvalvalue := $record/odm:ItemData[@ItemOID=$idvarvaloid]/@Value
let $rdomainvalue := $record/odm:ItemData[@ItemOID=$rdomainoid]/@Value
(: When RDOMAIN=DM IDVAR and IDVARVAL may not have a value :)
where $rdomainvalue='DM' and ($idvarvalue or $idvarvalvalue)
return <warning rule="FDAC164" variable="IDVAR" dataset="{data($name)}" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">Unexpected value for IDVAR/IDVARVAL: IDVAR and/or IDVARVAL are populated although RDOMAIN=DM in dataset {data($datasetname)}</warning>
USUBJID value is populated, when RELTYPE values is populated - Unique Subject Identifier (USUBJID) variable value should not be populated, when Relationship Type (RELTYPE) variable value is populated in RELREC
RELREC
(: Rule FDAC166 - USUBJID value is populated, when RELTYPE values is populated:
Unique Subject Identifier (USUBJID) variable value should not be populated, when Relationship Type (RELTYPE) variable value is populated in RELREC
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the location of the RELREC dataset :)
let $relrecdatasetname := doc(concat($base,$define))//odm:ItemGroupDef[@Name='RELREC']/def:leaf/@xlink:href
let $relrecdatasetlocation := concat($base,$relrecdatasetname)
(: Get the OID of the RELTYPE and USUBJID variable :)
let $reltypeoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='RELTYPE']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='RELREC']/odm:ItemRef/@ItemOID
return $a
)
let $usubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='RELREC']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records in the dataset :)
for $record in doc($relrecdatasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the values of RELTYPE and USUJID (when present) :)
let $reltypevalue := $record/odm:ItemData[@ItemOID=$reltypeoid]/@Value
let $usubjidvalue := $record/odm:ItemData[@ItemOID=$usubjidoid]/@Value
(: Unique Subject Identifier (USUBJID) variable value should not be populated,
when Relationship Type (RELTYPE) variable value is populated in RELREC :)
where $reltypevalue and $usubjidvalue
return <warning rule="FDAC166" dataset="RELREC" variable="USUBJID" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">USUBJID value is populated (value={data($usubjidvalue)}), when RELTYPE values is populated (value={data($reltypevalue)}) in dataset {data($relrecdatasetname)}</warning>
Values for --CAT and --SCAT are identical - Values of Category (--CAT) and Subcategory (--SCAT) variables should not be identical
ALL
(: Rule FDAC167 - Values for --CAT and --SCAT are identical:
Values of Category (--CAT) and Subcategory (--SCAT) variables should not be identical
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all datasets that have a --CAT and --SCAT variable in the interventions, events findings domains and the TI dataset :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[upper-case(@def:Class)='INTERVENTIONS' or upper-case(@def:Class)='EVENTS' or upper-case(@def:Class)='FINDINGS' or @Name='TI']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OID of the --CAT variable (if any) :)
let $catoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'CAT') and string-length(@Name)=5]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $catname := concat($name,'CAT')
(: Get the OID of the --SCAT variable (if any) :)
let $scatoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'SCAT') and string-length(@Name)=6]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $scatname := concat($name,'SCAT')
(: iterate over all records that DO have a CAT AND SCAT value :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$catoid] and odm:ItemData[@ItemOID=$scatoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: and compare the values - they MUST NOT be equal :)
let $catvalue := $record/odm:ItemData[@ItemOID=$catoid]/@Value
let $scatvalue := $record/odm:ItemData[@ItemOID=$scatoid]/@Value
where $catvalue = $scatvalue
return <warning rule="FDAC167" variable="{data($scatname)}" dataset="{$name}" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Values for {data($catname)} and {data($scatname)} are identical in dataset {data($datasetname)}</warning>
Missing value for --ORRES, when --ORRESU is provided - Result or Finding in Original Units (--ORRES) should not be NULL, when Original Units (--ORRESU) is provided
FINDINGS
(: Rule FDAC168 - Missing value for --ORRES, when --ORRESU is provided:
Result or Finding in Original Units (--ORRES) should not be NULL, when Original Units (--ORRESU) is provided
All FINDINGS datasets
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Iterate over all FINDINGS domains :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[upper-case(@def:Class)='FINDINGS']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: and get the OIDs of the ORRES and ORRESU variables :)
let $orresoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ORRES')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $orresname := doc(concat($base,$define))//odm:ItemDef[@OID=$orresoid]/@Name
let $orresuoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ORRESU')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $orresuname := doc(concat($base,$define))//odm:ItemDef[@OID=$orresuoid]/@Name
(: now iterate over all records in the dataset that have an ORRESU :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$orresuoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the values for ORRESU and ORRES :)
let $orresvalue := $record/odm:ItemData[@ItemOID=$orresoid]/@Value
let $orresuvalue := $record/odm:ItemData[@ItemOID=$orresuoid]/@Value
(: we already selected on the presence of ORRESU, check whether there is an ORRES :)
where not($orresvalue)
return <warning rule="FDAC168" variable="{data($orresname)}" dataset="{data($name)}" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Missing value for {data($orresname)}, when {data($orresuname)}, value={data($orresuvalue)} is provided in dataset {data($datasetname)}</warning>
Missing value for --STRESC, when --STRESU is provided - Character Result/Finding in Std Units (--STRESC) should not be NULL, when Standard Units (--STRESU) is provided
FINDINGS
(: Rule FDAC170 - Missing value for --STRESC, when --STRESU is provided:
Character Result/Finding in Std Units (--STRESC) should not be NULL, when Standard Units (--STRESU) is provided
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Iterate over all FINDINGS domains :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[upper-case(@def:Class)='FINDINGS']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: and get the OIDs of the STRESU and STRESC variables :)
let $strescoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STRESC')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $strescname := doc(concat($base,$define))//odm:ItemDef[@OID=$strescoid]/@Name
let $stresuoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STRESU')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $stresuname := doc(concat($base,$define))//odm:ItemDef[@OID=$stresuoid]/@Name
(: now iterate over all records in the dataset that DO have an STRESU :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$stresuoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the values for STRESC and STRESU :)
let $strescvalue := $record/odm:ItemData[@ItemOID=$strescoid]/@Value
let $stresuvalue := $record/odm:ItemData[@ItemOID=$stresuoid]/@Value
(: we already selected on the presence of STRESU, STRESC MUST be populated :)
where not($strescvalue)
return <warning rule="FDAC170" dataset="{data($name)}" variable="{data($strescname)}" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Missing value for {data($strescname)}, when {data($stresuname)} is provided, value={data($stresuvalue)} is provided in dataset {data($datasetname)}</warning>
Missing value for --STRESC, when --ORRES is provided - Character Result/Finding in Std Units (--STRESC) must be populated, when Result or Finding in Original Units (--ORRES) is provided
FINDINGS
(: Rule FDAC171 - Missing value for --STRESC, when --ORRES is provided:
Character Result/Finding in Std Units (--STRESC) must be populated, when Result or Finding in Original Units (--ORRES) is provided
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Iterate over all FINDINGS domains :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[upper-case(@def:Class)='FINDINGS']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: and get the OIDs of the STRESC and ORRES variables :)
let $strescoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STRESC')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $strescname := doc(concat($base,$define))//odm:ItemDef[@OID=$strescoid]/@Name
let $orresoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ORRES')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $orresname := doc(concat($base,$define))//odm:ItemDef[@OID=$orresoid]/@Name
(: now iterate over all records in the dataset that DO have an ORRES :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$orresoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the values for STRESC and ORRES :)
let $strescvalue := $record/odm:ItemData[@ItemOID=$strescoid]/@Value
let $orresvalue := $record/odm:ItemData[@ItemOID=$orresoid]/@Value
(: we already selected on the presence of ORRES, STRESC MUST be populated :)
where not($strescvalue)
return <error rule="FDAC171" dataset="{data($name)}" variable="{data($strescname)}" rulelastupdate="2017-02-19" recordnumber="{data($recnum)}">Missing value for {data($strescname)}, when {data($orresname)} is provided, {data($orresname)}='{data($orresvalue)}' is provided in dataset {data($datasetname)}</error>
Missing value for --STRESN - Standardized Result in Numeric Format (--STRESN) variable value should be populated, when Standardized Result in Character Format (--STRESC) variable value represents a numeric value
FINDINGS
(: Rule FDAC172 - Missing value for --STRESN:
Standardized Result in Numeric Format (--STRESN) variable value should be populated, when Standardized Result in Character Format (--STRESC) variable value represents a numeric value
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Iterate over all FINDINGS domains :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[upper-case(@def:Class)='FINDINGS']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: and get the OIDs of the STRESC and STRESN variables :)
let $strescoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STRESC')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $strescname := doc(concat($base,$define))//odm:ItemDef[@OID=$strescoid]/@Name
let $stresnoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STRESN')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $stresnname := doc(concat($base,$define))//odm:ItemDef[@OID=$stresnoid]/@Name
(: now iterate over all records in the dataset that DO have an STRESC :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$strescoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the values for STRESC and ORRES :)
let $strescvalue := $record/odm:ItemData[@ItemOID=$strescoid]/@Value
let $stresnvalue := $record/odm:ItemData[@ItemOID=$stresnoid]/@Value
(: we already selected on the presence of ORRES, check whether STRESN is present AND represents a numeric value :)
where not($stresnvalue) and $strescvalue castable as xs:double
return <warning rule="FDAC172" dataset="{data($name)}" variable="{data($stresnname)}" rulelastupdate="2016-03-30" recordnumber="{data($recnum)}">Missing value for {data($stresnname)}, when {data($strescname)} value={data($strescvalue)} is provided and represents a numeric value in dataset {data($datasetname)}</warning>
Missing --STRESC value for Baseline record - A Standard Result value (--STRESC) is expected to be populated for Baseline records (--BLFL="Y")
FINDINGS
(: Rule FDAC173 - Missing --STRESC value for Baseline record
A Standard Result value (--STRESC) is expected to be populated for Baseline records (--BLFL="Y")
FINDINGS datasets
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Iterate over all FINDINGS domains :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[upper-case(@def:Class)='FINDINGS']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: and get the OIDs of the STRESC and BLFL variables :)
let $strescoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STRESC')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $strescname := doc(concat($base,$define))//odm:ItemDef[@OID=$strescoid]/@Name
let $blfloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'BLFL')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $blflname := doc(concat($base,$define))//odm:ItemDef[@OID=$blfloid]/@Name
(: now iterate over all records in the dataset that DO have an BLFL with value "Y" :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$blfloid][@Value='Y']]
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the values for STRESC and ORRES :)
let $strescvalue := $record/odm:ItemData[@ItemOID=$strescoid]/@Value
let $blflvalue := $record/odm:ItemData[@ItemOID=$blfloid]/@Value
(: we already selected on the presence of BLFL=Y,check whether STRESC is present :)
where not($strescvalue)
return <warning rule="FDAC173" dataset="{data($name)}" variable="{data($strescname)}" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Missing {data($strescname)}, when {data($blflname)} value={data($blflvalue)} is provided in dataset {data($datasetname)}</warning>
Missing value for --STRESC, when --RESCAT is populated - Character Result/Finding in Std Units (--STRESC) should be provided, when Result Category (--RESCAT) is specified
FINDINGS
(: TODO: Further testing - we did not have a good test sample :)
(: Rule FDAC174 - Missing value for --STRESC, when --RESCAT is populated:
Character Result/Finding in Std Units (--STRESC) should be provided, when Result Category (--RESCAT) is specified
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Iterate over all FINDINGS domains :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[upper-case(@def:Class)='FINDINGS']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: and get the OIDs of the STRESC and RESCAT variables :)
let $strescoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STRESC')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $strescname := doc(concat($base,$define))//odm:ItemDef[@OID=$strescoid]/@Name
let $rescatoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'RESCAT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $rescatname := doc(concat($base,$define))//odm:ItemDef[@OID=$rescatoid]/@Name
(: now iterate over all records in the dataset that DO have an RESCAT data point :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$rescatoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the values for STRESC and ORRES :)
let $strescvalue := $record/odm:ItemData[@ItemOID=$strescoid]/@Value
let $rescatvalue := $record/odm:ItemData[@ItemOID=$rescatoid]/@Value
(: we already selected on the presence of RESCAT,check whether STRESC is present :)
where not($strescvalue)
return <warning rule="FDAC174" dataset="{data($name)}" variable="{data($strescname)}" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">Missing {data($strescname)}, when {data($rescatname)} value={data($rescatvalue)} is provided in dataset {data($datasetname)}</warning>
Missing value for --STAT, when --REASND is provided - Completion Status (--STAT) should be set to 'NOT DONE', when Reason Not Done (--REASND) is populated
ALL
(: Rule FDAC175 - Missing value for --STAT, when --REASND is provided:
Completion Status (--STAT) should be set to 'NOT DONE', when Reason Not Done (--REASND) is populated
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Find all "Findings", "Interventions" and "Events" datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[upper-case(@def:Class)='FINDINGS' or upper-case(@def:Class)='INTERVENTIONS' or upper-case(@def:Class)='EVENTS']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OIDs of the STAT and REASND variables :)
let $statoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STAT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $statname := doc(concat($base,$define))//odm:ItemDef[@OID=$statoid]/@Name
let $reasndoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'REASND')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $reasndname := doc(concat($base,$define))//odm:ItemDef[@OID=$reasndoid]/@Name
(: iterate over each record in the dataset for which there is a REASND data point :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$reasndoid]]
(: get the record number and the value for REASND :)
let $recnum := $record/@data:ItemGroupDataSeq
let $reasndvalue := $record/odm:ItemData[@ItemOID=$reasndoid]/@Value
(: and check whether there is a corresponding xxSTAT :)
let $statvalue := $record/odm:ItemData[@ItemOID=$statoid]/@Value
(: check whether xxSTAT is absent or deviates from 'NOT DONE' :)
where not($statvalue) or not($statvalue='NOT DONE')
return <warning rule="FDAC175" dataset="{data($name)}" variable="{data($statname)}" rulelastupdate="2015-02-10" recordnumber="{$recnum}">Missing or invalid value for {data($statname)} when {data($reasndname)} is provided - {data($reasndname)}={data($reasndvalue)} - {data($statname)}={data($statvalue)} in dataset {data($datasetname)}</warning>
Missing value for --REASND, when --STAT is 'NOT DONE' - Value of Reason Not Done (--REASND) variable should be populated, when Status (--STAT) variable value is 'NOT DONE'
ALL
(: Rule FDAC176 - Missing value for --REASND, when --STAT is 'NOT DONE':
Value of Reason Not Done (--REASND) variable should be populated, when Status (--STAT) variable value is 'NOT DONE'.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Find all "Findings", "Interventions" and "Events" datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[upper-case(@def:Class)='FINDINGS' or upper-case(@def:Class)='INTERVENTIONS' or upper-case(@def:Class)='EVENTS']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OIDs of the STAT and REASND variables :)
let $statoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STAT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $statname := doc(concat($base,$define))//odm:ItemDef[@OID=$statoid]/@Name
let $reasndoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'REASND')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $reasndname := doc(concat($base,$define))//odm:ItemDef[@OID=$reasndoid]/@Name
(: iterate over each record in the dataset for which there is a STAT data point that has 'NOT DONE' as value :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$statoid]/@Value='NOT DONE']
(: get the record number and the value for REASND :)
let $recnum := $record/@data:ItemGroupDataSeq
let $reasndvalue := $record/odm:ItemData[@ItemOID=$reasndoid]/@Value
(: and check whether there is a corresponding STAT :)
let $statvalue := $record/odm:ItemData[@ItemOID=$statoid]/@Value
(: check that REASND is populated :)
where not($reasndvalue)
return <warning rule="FDAC176" dataset="{data($name)}" variable="{data($reasndname)}" rulelastupdate="2015-02-11" recordnumber="{$recnum}">Missing value for {data($reasndname)} when {data($statname)}={data($statvalue)} in dataset {data($datasetname)}</warning>
--STAT does not equal 'NOT DONE', when --PRESP='Y' and --OCCUR is NULL - When no response is provided for Occurrence (--OCCUR) for a pre-specified Intervention or Event (--PRESP = 'Y'), then Status (--STAT) should be set to 'NOT DONE'
INTERVENTIONS
EVENTS
(: TODO: test - did not have a good test dataset :)
(: Rule FDAC177- --STAT does not equal 'NOT DONE', when --PRESP='Y' and --OCCUR is NULL:
When no response is provided for Occurrence (--OCCUR) for a pre-specified Intervention or Event (--PRESP = 'Y'), then Status (--STAT) should be set to 'NOT DONE'
INTERVENTIONS AND EVENTS
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Find all "Findings", "Interventions" and "Events" datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[upper-case(@def:Class)='INTERVENTIONS' or upper-case(@def:Class)='EVENTS']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OIDs of the STAT and PRESP and OCCUR variables :)
let $statoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STAT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $statname := doc(concat($base,$define))//odm:ItemDef[@OID=$statoid]/@Name
let $prespoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'PRESP')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $prespname := doc(concat($base,$define))//odm:ItemDef[@OID=$prespoid]/@Name
let $occuroid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'OCCUR')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $occurname := doc(concat($base,$define))//odm:ItemDef[@OID=$occuroid]/@Name
(: iterate over each record in the dataset for which there is a PRESP data point that has 'Y' as value :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$prespoid]/@Value='Y']
(: get the value for --STAT :)
let $statvalue := $record/odm:ItemData[@ItemOID=$statoid]
(: get the record number and the value for STAT and OCCUR :)
let $recnum := $record/@data:ItemGroupDataSeq
let $prespvalue := $record/odm:ItemData[@ItemOID=$prespoid]/@Value
let $occurvalue := $record/odm:ItemData[@ItemOID=$occuroid]/@Value
(: check that OCCUR is NULL (not populated) and if so, that STAT is populated and has the value 'NOT DONE' :)
where not($occurvalue) and not($statvalue='NOT DONE')
return <warning rule="FDAC177" dataset="{data($name)}" variable="{data($statname)}" rulelastupdate="2015-02-11" recordnumber="{$recnum}" >{data($statname)} does not equal 'NOT DONE', when {data($prespname)}='Y' and {data($occurname)} is NULL in dataset {data($datasetname)}, value found for 'NOT DONE'={data($statvalue)}</warning>
Missing value for --ORRES, when --STAT or --DRVFL is not populated - Status (--STAT) should be set to 'NOT DONE' or Derived Flag (--DRVFL) should have a value of 'Y', when Result or Finding in Original Units (--ORRES) is NULL
FINDINGS
(: TODO: "Message" and "Description" in FDA worksheet have a mismatch :)
(: Rule FDAC178 - Missing value for --ORRES, when --STAT or --DRVFL is not populated:
Status (--STAT) should be set to 'NOT DONE' or Derived Flag (--DRVFL) should have a value of 'Y', when Result or Finding in Original Units (--ORRES) is NULL
FINDINGS DATASETS
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all FINDINGS datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[upper-case(@def:Class)='FINDINGS']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OIDs of the --STAT, --DRVFL and --ORRES variable :)
let $statoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STAT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $statname := doc(concat($base,$define))//odm:ItemDef[@OID=$statoid]/@Name
let $drvfloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'DRVFL')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $drvflname := doc(concat($base,$define))//odm:ItemDef[@OID=$drvfloid]/@Name
let $orresoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ORRES')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $orresname := doc(concat($base,$define))//odm:ItemDef[@OID=$orresoid]/@Name
(: iterate over all records that do NOT have a value for ORRES :)
for $record in doc($datasetlocation)//odm:ItemGroupData[not(odm:ItemData[@ItemOID=$orresoid])]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the values for STAT and DRVFL :)
let $statvalue := $record/odm:ItemData[@ItemOID=$statoid]/@Value
let $drvflvalue := $record/odm:ItemData[@ItemOID=$drvfloid]/@Value
(: Either STAT='NOT DONE', OR, DRVL='Y' :)
where not($statvalue='NOT DONE') and not($drvflvalue='Y')
return <warning rule="FDAC178" dataset="{data($name)}" variable="{data($orresname)}" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Status {data($statname)} should be set to 'NOT DONE' or Derived Flag {data($drvflname)} should have a value of 'Y', when Result or Finding in Original Units {data($orresname)} is NULL</warning>
Status (--STAT) must be NULL, when Result or Finding in Original Units (--ORRES) is provided - Status (--STAT) should be NULL, when Result or Finding in Original Units (--ORRES) is provided
FINDINGS
(: Rule FDAC179 - Value for --ORRES is populated, when --STAT is 'NOT DONE'
Status (--STAT) should be NULL, when Result or Finding in Original Units (--ORRES) is provided
:)
(: ATTENTION: Message and Description in FDA worksheet do not match :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all FINDINGS datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[upper-case(@def:Class)='FINDINGS']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OIDs of the --STAT and --ORRES variable :)
let $statoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STAT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $statname := doc(concat($base,$define))//odm:ItemDef[@OID=$statoid]/@Name
let $orresoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ORRES')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $orresname := doc(concat($base,$define))//odm:ItemDef[@OID=$orresoid]/@Name
(: iterate over all records for which ORRES is populated :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$orresoid]/@Value]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of STAT :)
let $statvalue := $record/odm:ItemData[@ItemOID=$statoid]/@Value
(: STAT must be null :)
where $statvalue
return <warning rule="FADC179" dataset="{data($name)}" variable="{data($statname)}" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Status {data($statname)} should be NULL, when Result or Finding in Original Units ({data($orresname)}) is provided
</warning>
Value for --ORRES is populated, when --STAT is 'NOT DONE' - Value of Original Result (--ORRES) variable is expected to be missing, when observation was not performed (Status (--STAT) is 'NOT DONE')
FINDINGS
(: Rule FDAC180 - Value for --ORRES is populated, when --STAT is 'NOT DONE'
Value of Original Result (--ORRES) variable is expected to be missing, when observation was not performed (Status (--STAT) is 'NOT DONE')
:)
(: ATTENTION: Message and Description do not match :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all FINDINGS datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[upper-case(@def:Class)='FINDINGS'][@Name='VS']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OIDs of the --STAT, --DRVFL and --ORRES variable :)
let $statoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STAT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $statname := doc(concat($base,$define))//odm:ItemDef[@OID=$statoid]/@Name
let $orresoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'ORRES')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $orresname := doc(concat($base,$define))//odm:ItemDef[@OID=$orresoid]/@Name
(: iterate over all records for which STAT has the value 'NOT DONE' :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$statoid][@Value='NOT DONE']]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of ORRES :)
let $orresvalue := $record/odm:ItemData[@ItemOID=$orresoid]/@Value
(: ORRES must be null :)
where $orresvalue
return <warning rule="FADC180" dataset="{data($name)}" variable="{data($orresname)}" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">{data($orresname)} value is populated (value={data($orresvalue)}), when {data($orresname)} is 'NOT DONE' </warning>
Missing value for --TOXGR, when --TOX is populated - Toxicity Grade (--TOXGR) should be provided, when Toxicity (--TOX) is populated
AE
MH
CE
EG
LB
PC
PP
(: Rule FDAC181 - Missing value for --TOXGR, when --TOX is populated:
Toxicity Grade (--TOXGR) should be provided, when Toxicity (--TOX) is populated
Domains: AE, MH, CE, EG, LB, PC, PP
:)
(: TODO: better testing, we did not have a good test dataset :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over the AE, MH, CE, EG, LB, PC, PP datasets :)
for $dataset in doc(concat($base,$define))/odm:ItemGroupDef[starts-with(@Name,'AE') or @Domain='AE' or starts-with(@Name,'MH') or @Domain='MH' or starts-with(@Name,'CE') or @Domain='CE' or starts-with(@Name,'EG') or @Domain='EG' or starts-with(@Name,'LB') or @Domain='LB' or starts-with(@Name,'PC') or @Domain='PC' starts-with(@Name,'PP') or or @Domain='PP']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OIDs of the TOX and TOXGR variables :)
let $toxoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TOX')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $toxname := doc(concat($base,$define))//odm:ItemDef[@OID=$toxoid]/@Name
let $toxgroid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TOXGR')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $toxgrname := doc(concat($base,$define))//odm:ItemDef[@OID=$toxgroid]/@Name
(: get all records for which TOX is populated :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$toxoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: and the value of TOX :)
let $toxvalue := $record/odm:ItemData[@ItemOID=$toxoid]/@Value
(: and check whether TOXGR is populated :)
let $toxgrvalue := $record/odm:ItemData[@ItemOID=$toxgroid]/@Value
where not($toxgrvalue)
return <warning rule="FDAC181" dataset="{data($name)}" variable="{data($toxgrname)}" rulelastupdate="2016-03-30" recordnumber="{$recnum}">Missing value for {data($toxgrname)}, when {data($toxname)} is populated, value={data($toxvalue)}</warning>
Missing value for --TOX, when --TOXGR is populated - A value for a Toxicity (--TOX) variable should be provided, when a Toxicity Grade (--TOXGR) variable value is populated and greater than 0
AE
MH
CE
EG
LB
PC
PP
(: Rule FDAC182 - Missing value for --TOX, when --TOXGR is populated:
A value for a Toxicity (--TOX) variable should be provided, when a Toxicity Grade (--TOXGR) variable value is populated and greater than 0
:)
(: TODO: better testing, we did not have a good dataset for this :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over the AE, MH, CE, EG, LB, PC, PP datasets :)
for $dataset in doc(concat($base,$define))/odm:ItemGroupDef[starts-with(@Name,'AE') or @Domain='AE' or starts-with(@Name,'MH') or @Domain='MH' or starts-with(@Name,'CE') or @Domain='CE' or starts-with(@Name,'EG') or @Domain='EG' or starts-with(@Name,'LB') or @Domain='LB' or starts-with(@Name,'PC') or @Domain='PC' starts-with(@Name,'PP') or or @Domain='PP']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: Get the OIDs of the TOX and TOXGR variables :)
let $toxoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TOX')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $toxname := doc(concat($base,$define))//odm:ItemDef[@OID=$toxoid]/@Name
let $toxgroid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TOXGR')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $toxgrname := doc(concat($base,$define))//odm:ItemDef[@OID=$toxgroid]/@Name
(: get all records for which TOXGR is populated :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$toxgroid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: and the value of TOX :)
let $toxgrvalue := $record/odm:ItemData[@ItemOID=$toxgroid]/@Value
(: and check whether TOX is populated, when TOXGR>0 :)
let $toxvalue := $record/odm:ItemData[@ItemOID=$toxoid]/@Value
where number($toxgrvalue) and not($toxvalue)
return <warning rule="FDAC182"dataset="{data($name)}" variable="{data($toxname)}" rulelastupdate="2015-02-11" recordnumber="{$recnum}">Missing value for {data($toxname)}, when {data($toxgrname)} is populated with a value >0, value={data($toxgrvalue)}</warning>
Missing value for --DOSU, when --DOSE, --DOSTXT or --DOSTOT is provided - Dose Units (--DOSU) must be populated, when Dose per Administration (--DOSE), Dose Description (--DOSTXT) or Total Daily Dose (--DOSTOT) is provided
INTERVENTIONS
(: Rule FDAC183 - Missing value for --DOSU, when --DOSE, --DOSTXT or --DOSTOT is provided:
Dose Units (--DOSU) must be populated, when Dose per Administration (--DOSE), Dose Description (--DOSTXT) or Total Daily Dose (--DOSTOT) is provided
INTERVENTIONS
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all INTERVENTION domains :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[upper-case(@def:Class)='INTERVENTIONS']
let $name := $dataset/@Name
let $domain := $dataset/@Domain
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OIDs of --DOSU, --DOSE, --DOSTXT and --DOSTOT :)
let $dosuoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'DOSU')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $dosuname := doc(concat($base,$define))//odm:ItemDef[@OID=$dosuoid]/@Name
let $doseoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'DOSE')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $dosename := concat($domain,'DOSE') (: for the case there is no OID :)
let $doxtxtoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'DOSTXT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $dostxtname := concat($domain,'DOSTXT') (: for the case there is no OID :)
let $dostotoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'DOSTOT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $dostotname := concat($domain,'DOSTOT') (: for the case there is no OID :)
(: iterate over all records that have either a --DOSE, --DOSTXT or --DOSTOT data point :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$doseoid] or odm:ItemData[@ItemOID=$doxtxtoid] or odm:ItemData[@ItemOID=$dostotoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of --DOSU (if any) :)
let $dosuvalue := $record/odm:ItemData[@ItemOID=$dosuoid]/@Value
(: we did already select those records where either --DOSE, --DOSTXT or --DOSTOT is populated
Now check whether --DOSU is populated :)
where not($dosuvalue)
return <error rule="FDAC183" dataset="{data($name)}" variable="{data($dosuname)}" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Missing value for {data($dosuname)}, when {data($dosename)}, {data($dostxtname)} or {data($dostotname)} is provided</error>
Missing value for --TRTV, when --VAMT is not NULL - Treatment Vehicle (--TRTV) should be provided, when Treatment Vehicle Amount (--VAMT) is specified
INTERVENTIONS
(: TODO: needs further testing, did not have a good test dataset :)
(: Rule FDAC184 - Missing value for --TRTV, when --VAMT is not NULL
Treatment Vehicle (--TRTV) should be provided, when Treatment Vehicle Amount (--VAMT) is specified
INTERVENTIONS
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all INTERVENTION domains :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[upper-case(@def:Class)='INTERVENTIONS']
let $name := $dataset/@Name
let $domain := $dataset/@Domain
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OID of TRTV and VAMT variables :)
let $trtvoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TRTV')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $trtvname := //odm:ItemDef[@OID=$trtvoid]/@Name
let $vamtoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'VAMT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $vamtname := //odm:ItemDef[@OID=$vamtoid]/@Name
(: iterate over all records for which VAMT is populated :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$vamtoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the value of the VAMT variable :)
let $vamtvalue := $record/odm:ItemData[@ItemOID=$vamtoid]/@Value
(: and check whether TRTV is populated :)
let $trtvvalue := $record/odm:ItemData[@ItemOID=$trtvoid]/@Value
where not($trtvvalue)
return <warning rule="FDAC184" dataset="{data($name)}" variable="{data($trtvname)}" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Missing value for {data($trtvname)}, when {data($vamtname)} is not NULL</warning>
Missing value for --VAMTU, when --VAMT is populated - Treatment Vehicle Amount Units (--VAMTU) should not be NULL, when Treatment Vehicle Amount (--VAMT) is populated
INTERVENTIONS
(: TODO: needs further testing, did not have a good test dataset :)
(: Rule FDAC185 - Missing value for --VAMTU, when --VAMT is populated:
Treatment Vehicle Amount Units (--VAMTU) should not be NULL, when Treatment Vehicle Amount (--VAMT) is populated
INTERVENTIONS
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all INTERVENTION domains :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[upper-case(@def:Class)='INTERVENTIONS']
let $name := $dataset/@Name
let $domain := $dataset/@Domain
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OID of VAMTU and VAMT variables :)
let $vamtuoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'VAMTU')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $vamtuname := doc(concat($base,$define))//odm:ItemDef[@OID=$vamtuoid]/@Name
let $vamtoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'VAMT')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $vamtname := doc(concat($base,$define))//odm:ItemDef[@OID=$vamtoid]/@Name
(: iterate over all records for which VAMT is populated :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$vamtoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the value of the VAMT variable :)
let $vamtvalue := $record/odm:ItemData[@ItemOID=$vamtoid]/@Value
(: and check whether VAMTU is populated :)
let $vamtuvalue := $record/odm:ItemData[@ItemOID=$vamtuoid]/@Value
where not($vamtuvalue)
return <warning rule="FDAC185" dataset="{data($name)}" variable="{data($vamtuname)}" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Missing value for {data($vamtuname)}, when {data($vamtname)} is populated</warning>
Missing --CAT value, when --SCAT value is populated - Value for Category (--CAT) variable should be populated, when value for Subcategory (--SCAT) variable is populated
ALL
(: Rule FDAC186 - Missing --CAT value, when --SCAT value is populated:
Value for Category (--CAT) variable should be populated, when value for Subcategory (--SCAT) variable is populated
INTERVENTIONS, EVENTS, FINDINGS :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all INTERVENTIONS, EVENTS and FINDINGS domains :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[upper-case(@def:Class)='INTERVENTIONS' or upper-case(@def:Class)='EVENTS' or upper-case(@def:Class)='FINDINGS']
let $name := $dataset/@Name
let $domain := $dataset/@Domain
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OID of --CAT and --SCAT and VAMT variables :)
let $catoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'CAT') and string-length(@Name)=5]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $catname := //odm:ItemDef[@OID=$catoid]/@Name
let $scatoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'SCAT') and string-length(@Name)=6]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $scatname := //odm:ItemDef[@OID=$scatoid]/@Name
(: iterate over all records for which --SCAT is populated :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$scatoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the value of the --SCAT variable :)
let $scatvalue := $record/odm:ItemData[@ItemOID=$scatoid]/@Value
(: and check whether CAT is populated :)
let $catvalue := $record/odm:ItemData[@ItemOID=$catoid]/@Value
where not($catvalue)
return <error rule="FDAC186" dataset="{data($name)}" variable="{data($catname)}" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Missing {data($catname)} value, when {data($scatname)} value is populated</error>
Missing --CAT variable, when --SCAT variable is present - Category (--CAT) variable should be included into dataset, when Subcategory (--SCAT) variable is present
ALL
(: Rule FDAC187 - Missing --CAT variable, when --SCAT variable is present:
Category (--CAT) variable should be included into dataset, when Subcategory (--SCAT) variable is present.
This is to be tested on the level of define.xml
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all INTERVENTIONS, EVENTS and FINDINGS domains :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[upper-case(@def:Class)='INTERVENTIONS' or upper-case(@def:Class)='EVENTS' or upper-case(@def:Class)='FINDINGS']
let $name := $dataset/@Name
let $domain := $dataset/@Domain
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OID of --CAT and --SCAT variables :)
let $catoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'CAT') and string-length(@Name)=5]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $catname := concat($domain,'CAT')
let $scatoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'SCAT') and string-length(@Name)=6]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $scatname := //odm:ItemDef[@OID=$scatoid]/@Name
(: testing on level of define.xml - we just test whether there is an ItemRef/ItemDef for --CAT :)
where $scatoid and not($catoid)
return <warning rule="FDAC187" dataset="{data($name)}" rulelastupdate="2015-02-11">Missing {data($catname)} variable, when {data($scatname)} variable is present</warning>
Missing value for AGEU, when AGE is provided - Age Units (AGEU) should be provided, when Age (AGE) is populated
DM
(: Rule FDAC188 - Missing value for AGEU, when AGE is provided:
Age Units (AGEU) should be provided, when Age (AGE) is populated (DM)
SDTM 3.1.1 and 3.1.2
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the DM dataset :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OID of the AGE and AGEU variables :)
let $ageoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AGE']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
let $ageuoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AGEU']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all DM records that do have an AGE data point :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$ageoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: and check whether AGEU is present :)
let $ageuvalue := $record/odm:ItemData[@ItemOID=$ageuoid]/@Value
where not($ageuvalue)
return <error rule="FDAC188" dataset="DM" variable="AGEU" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Missing value for AGEU, when AGE is provided</error>
Missing value for AGE, when AGEU is provided - Age (AGE) should be provided, when Age Units (AGEU) are populated
DM
(: Rule FDAC189 - Missing value for AGE, when AGEU is provided:
Age (AGE) should be provided, when Age Units (AGEU) are populated
SDTM 3.1.1 and 3.1.2
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the DM dataset :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OID of the AGE and AGEU variables :)
let $ageoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AGE']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
let $ageuoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AGEU']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records that do have an AGEU data point :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$ageuoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: and check whether AGE is present :)
let $agevalue := $record/odm:ItemData[@ItemOID=$ageoid]/@Value
where not($agevalue)
return <error rule="FDAC189" dataset="DM" variable="AGE" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Missing value for AGE, when AGEU is provided</error>
Neither AGE nor AGETXT variables are present - At least one of Age (AGE) or Age Text (AGETXT) variables should be inculded into Demographics (DM) domain
DM
(: Rule FDAC190 - Neither AGE nor AGETXT variables are present
At least one of Age (AGE) or Age Text (AGETXT) variables should be inculded into Demographics (DM) domain
This is checked on the level of define.xml, as it is NOT about the population (see rule FDAC191)
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the DM dataset :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OID of the AGE and AGETXT variables (when present) :)
let $ageoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AGE']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
let $agetxtoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AGETXT']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
where not($ageoid) and not($agetxtoid)
return <error rule="FDAC190" dataset="DM" rulelastupdate="2015-02-11">Neither AGE nor AGETXT variables are present</error>
Neither of AGE or AGETXT variables values are populated - Value for Age (AGE) of Age Range (AGETXT) variables should be populated for all subjects with only exception for Screen Failures (ARMCD=SCRNFAIL) and Not Assigned (ARMCD=NOTASSGN) subejcts
DM
(: Rule FDAC191 - Neither of AGE or AGETXT variables values are populated:
Value for Age (AGE) of Age Range (AGETXT) variables should be populated for all subjects with only exception for Screen Failures (ARMCD=SCRNFAIL) and Not Assigned (ARMCD=NOTASSGN) subejcts
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the DM dataset :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OID of the AGE and AGETXT variables (when present) :)
let $ageoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AGE']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
let $agetxtoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AGETXT']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: we also need the OID of the ARMCD variable :)
let $armcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records in the DM dataset :)
for $record in doc($datasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the values of AGE, AGETXT and ARMCD (when populated) :)
let $agevalue := $record/odm:ItemData[@ItemOID=$ageoid]/@Value
let $agetxtvalue := $record/odm:ItemData[@ItemOID=$agetxtoid]/@Value
let $armcdvalue := $record/odm:ItemData[@ItemOID=$armcdoid]/@Value
(: AGE or AGETXT must be populated except for ARMCD=SCRNFAIL and ARMCD=NOTASSGN :)
where not($agevalue) and not($agetxtvalue) and not($armcdvalue='SCRNFAIL') and not($armcdvalue='NOTASSGN')
return <warning rule="FDAC191" dataset="DM" variable="AGE" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Neither of AGE or AGETXT variables values are populated</warning>
Invalid value for AGETXT - Age Range (AGETXT) variable values should be populated with 'number-number' format
DM
(: TODO: further testing - we need a good test file :)
(: Rule FDAC192 - Invalid value for AGETXT:
Age Range (AGETXT) variable values should be populated with 'number-number' format
:)
(: Remark: regular expression was tested using: https://regex101.com/ :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the DM dataset :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OID of the AGETXT variable :)
let $agetxtoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AGETXT']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records where AGETXT is populated :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$agetxtoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of AGETXT :)
let $agetxtvalue := $record/odm:ItemData[@ItemOID=$agetxtoid]/@Value
where not(matches($agetxtvalue,'^[\d]*.[\d]*-[\d]*.[\d]*$'))
return <warning rule="FDAC192" dataset="DM" variable="AGETXT" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Invalid value for AGETXT. '{data($agetxtvalue)}' was found</warning>
Both AGE and AGETXT variables values are populated - Age (AGE) and Age Range (AGETXT) variables should never both be populated for the same subject
DM
(: Rule FDAC193 - Both AGE and AGETXT variables values are populated:
Age (AGE) and Age Range (AGETXT) variables should never both be populated for the same subject :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the DM dataset :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OID of the AGE and AGETXT variables (when present) :)
let $ageoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AGE']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
let $agetxtoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AGETXT']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records in the DM dataset :)
for $record in doc($datasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the values of AGE, AGETXT (when populated) :)
let $agevalue := $record/odm:ItemData[@ItemOID=$ageoid]/@Value
let $agetxtvalue := $record/odm:ItemData[@ItemOID=$agetxtoid]/@Value
(: AGE or AGETXT may not both be populated for the same subject :)
where $agevalue and $agetxtvalue
return <warning rule="FDAC193" dataset="DM" variable="AGETXT" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Both AGE and AGETXT variables values are populated</warning>
Missing values for both AGE and AGETXT, when AGEU is provided - Either of Age (AGE) or Age Range (AGETXT) variable values should be provided, when Age Units (AGEU) are populated
DM
(: Rule FDAC194 - Missing values for both AGE and AGETXT, when AGEU is provided:
Either of Age (AGE) or Age Range (AGETXT) variable values should be provided, when Age Units (AGEU) are populated
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the DM dataset :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OID of the AGE, AGETXT and AGEU variables (when present) :)
let $ageoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AGE']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
let $agetxtoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AGETXT']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
let $ageuoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AGEU']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records in the DM dataset that have AGEU populated :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$ageuoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the values of AGE, AGETXT(when populated) :)
let $agevalue := $record/odm:ItemData[@ItemOID=$ageoid]/@Value
let $agetxtvalue := $record/odm:ItemData[@ItemOID=$agetxtoid]/@Value
(: one AGE or AGETXT must be populated :)
where not($agevalue or $agetxtvalue)
return <error rule="FDAC194" dataset="DM" variable="AGE" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Missing values for both AGE and AGETXT, when AGEU is provided</error>
Missing value for AGEU, when AGE or AGETXT is populated - Age Units (AGEU) variable values should be provided, when Age (AGE) or Age Range (AGETXT) variables values are populated
DM
(: Rule FDAC195 - Missing value for AGEU, when AGE or AGETXT is populated:
Age Units (AGEU) variable values should be provided, when Age (AGE) or Age Range (AGETXT) variables values are populated
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the DM dataset :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OID of the AGE, AGETXT and AGEU variables (when present) :)
let $ageoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AGE']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
let $agetxtoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AGETXT']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
let $ageuoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AGEU']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records in the DM dataset that have AGE or AGETXT populated :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$ageoid] or odm:ItemData[@ItemOID=$agetxtoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the values of AGE, AGETXT and AGEU (when populated) :)
let $agevalue := $record/odm:ItemData[@ItemOID=$ageoid]/@Value
let $agetxtvalue := $record/odm:ItemData[@ItemOID=$agetxtoid]/@Value
let $ageuvalue := $record/odm:ItemData[@ItemOID=$ageuoid]/@Value
(: AGEU must be populated :)
where not($ageuvalue)
return <error rule="FDAC195" dataset="DM" variable="AGEU" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Missing value for AGEU, when AGE or AGETXT is populated</error>
AGE is not provided - Age (AGE) variable values should be provided, when Date/Time of Birth (BRTHDTC) variable values are populated
DM
(: Rule FDAC196 - AGE is not provided:
Age (AGE) variable values should be provided, when Date/Time of Birth (BRTHDTC) variable values are populated
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the DM dataset :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OID of the AGE, and BRTHDTC (when present) :)
let $ageoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AGE']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
let $brthdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='BRTHDTC']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records in the DM dataset that have BRTHDTC populated :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$brthdtcoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the values of AGE (when populated) :)
let $agevalue := $record/odm:ItemData[@ItemOID=$ageoid]/@Value
(: AGE must be populated :)
where not($agevalue)
return <error rule="FDAC196" dataset="DM" variable="AGE" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">AGE is not provided</error>
ACTARMCD does not equal ARMCD - A value for an Actual Arm Code (ACTARMCD) variable is expected to be equal to a value of an Arm Code (ARMCD) variable
DM
(: Rule FDAC197 - ACTARMCD does not equal ARMCD:
A value for an Actual Arm Code (ACTARMCD) variable is expected to be equal to a value of an Arm Code (ARMCD) variable.
:)
(: Rule is not 100% clear - is it meant one of ARMCD from TA? We will suppose so.
But in that case, what is the difference with rule FDAC197? :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace functx = "http://www.functx.com";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: function to find out whether a value is in a sequence (array) :)
declare function functx:is-value-in-sequence
( $value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TA dataset and the ARMCD OID in TA :)
let $tadataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TA']
let $tadatasetname := $tadataset/def:leaf/@xlink:href
let $tadatasetlocation := concat($base,$tadatasetname)
let $armcdfromtaoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TA']/odm:ItemRef/@ItemOID
return $a
)
(: make an array/sequence with all TA-ARMCD values, take it from the dataset itself, not from the define.xml codelist :)
let $armcdsequence := distinct-values(
for $itemdata in doc($tadatasetlocation)//odm:ItemGroupData/odm:ItemData[@ItemOID=$armcdfromtaoid]
return $itemdata/@Value
)
(: Get the DM dataset :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OID of the ACTARMCD, and BRTHDTC (when present) :)
let $actarmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ACTARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records in the DM dataset that have ACTARMCD populated :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$actarmcdoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of ACTARMCD :)
let $actarmcdvalue := $record/odm:ItemData[@ItemOID=$actarmcdoid]/@Value
(: and check whether it is one of those from TA/ARMCD :)
where not(functx:is-value-in-sequence($actarmcdvalue,$armcdsequence))
return <warning dataset="DM" variable="ACTARMCD" rule="FDAC197" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">ACTARMCD, value={data($actarmcdvalue)} in dataset {data($tadatasetname)} does not equal ARMCD from TA</warning>
Invalid value for ACTARMCD - The value of Actual Arm Code (ACTARMCD) should be no more than 20 characters in length
DM
(: Rule FDAC198 - Invalid value for ACTARMCD:
The value of Actual Arm Code (ACTARMCD) should be no more than 20 characters in length
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the DM dataset :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OID of the ACTARMCD :)
let $actarmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ACTARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records in the DM dataset that have ACTARMCD populated :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$actarmcdoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of ACTARMCD :)
let $actarmcdvalue := $record/odm:ItemData[@ItemOID=$actarmcdoid]/@Value
(: and check whether it is not longer than 20 characters :)
where string-length($actarmcdvalue) > 20
return <warning rule="FDAC198" dataset="DM" variable="ACTARMCD" ulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Invalid value for ACTARMCD in dataset {data($datasetname)}, it's length is more than 20 characters, value={data($actarmcdvalue)}</warning>
Invalid value for ACTARMCD - Actual Arm Code (ACTARMCD) values should match entries in the Trial Arms (TA) dataset, except for subjects who failed screening ('SCRNFAIL'), or were not fully assigned to an Arm ('NOTASSGN'), or randomized but not treated ('NOTTRT'), or recieved non-planned treatment ('UNPLAN')
DM
(: Rule FDAC199 - Invalid value for ACTARMCD:
Actual Arm Code (ACTARMCD) values should match entries in the Trial Arms (TA) dataset, except for subjects who failed screening ('SCRNFAIL'), or were not fully assigned to an Arm ('NOTASSGN'), or randomized but not treated ('NOTTRT'), or recieved non-planned treatment ('UNPLAN').
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace functx = "http://www.functx.com";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: function to find out whether a value is in a sequence (array) :)
declare function functx:is-value-in-sequence
( $value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TA dataset and the ARMCD OID in TA :)
let $tadataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TA']
let $tadatasetname := $tadataset/def:leaf/@xlink:href
let $tadatasetlocation := concat($base,$tadatasetname)
let $armcdfromtaoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TA']/odm:ItemRef/@ItemOID
return $a
)
(: make an array/sequence with all TA-ARMCD values, take it from the dataset itself, not from the define.xml codelist :)
let $armcdsequence := distinct-values(
for $itemdata in doc($tadatasetlocation)//odm:ItemGroupData/odm:ItemData[@ItemOID=$armcdfromtaoid]
return $itemdata/@Value
)
(: Get the DM dataset :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OID of the ACTARMCD, and BRTHDTC (when present) :)
let $actarmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ACTARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records in the DM dataset that have ACTARMCD populated :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$actarmcdoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of ACTARMCD :)
let $actarmcdvalue := $record/odm:ItemData[@ItemOID=$actarmcdoid]/@Value
(: and check whether it is one of those from TA/ARMCD OR SCRNFAIL, NOTASSGN, NOTTRT, UNPLAN :)
where not(functx:is-value-in-sequence($actarmcdvalue,$armcdsequence)) and not($actarmcdvalue='SCRNFAIL') and not($actarmcdvalue='NOTASSGN') and not($actarmcdvalue='NOTTRT') and not($actarmcdvalue='UNPLAN')
return <error rule="FDAC199" dataset="DM" variable="ACTARMCD" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Invalid value for ACTARMCD, value={data($actarmcdvalue)} in dataset DM</error>
Invalid value for ACTARM - Description of Actual Arm (ACTARM) values should match entries in the Trial Arms (TA) dataset, except for subjects who failed screening ('Screen Failure'), or were not fully assigned to an Arm ('Not Assigned'), or randomized, but not treated ('Not Treated') or recieved non-planned treatment ('Unplanned Treatment')
DM
TA
(: Rule FDAC200 - Invalid value for ACTARM:
Description of Actual Arm (ACTARM) values should match entries in the Trial Arms (TA) dataset, except for subjects who failed screening ('Screen Failure'), or were not fully assigned to an Arm ('Not Assigned'), or randomized, but not treated ('Not Treated') or recieved non-planned treatment ('Unplanned Treatment')
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace functx = "http://www.functx.com";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: function to find out whether a value is in a sequence (array) :)
declare function functx:is-value-in-sequence
( $value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TA dataset and the ARM (Arm Name( OID in TA :)
let $tadataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TA']
let $tadatasetname := $tadataset/def:leaf/@xlink:href
let $tadatasetlocation := concat($base,$tadatasetname)
let $armfromtaoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ARM']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TA']/odm:ItemRef/@ItemOID
return $a
)
(: make an array/sequence with all TA-ARM values, take it from the dataset itself, not from the define.xml codelist :)
let $armsequence := distinct-values(
for $itemdata in doc($tadatasetlocation)//odm:ItemGroupData/odm:ItemData[@ItemOID=$armfromtaoid]
return $itemdata/@Value
)
(: Get the DM dataset :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OID of the ACTARM :)
let $actarmoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ACTARM']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records in the DM dataset that have ACTARM populated :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$actarmoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of ACTARM :)
let $actarmvalue := $record/odm:ItemData[@ItemOID=$actarmoid]/@Value
(: and check whether it is one of those from TA/ARM OR
'Screen Failure' or 'Not Assigned' or 'Not Treated' or 'Unplanned Treatment'
S:)
where not(functx:is-value-in-sequence($actarmvalue,$armsequence)) and not($actarmvalue='Screen Failure') and not($actarmvalue='Not Assigned') and not($actarmvalue='Not Treated') and not($actarmvalue='Unplanned Treatment')
return <error rule="FDAC200" dataset="DM" variable="ACTARM" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Invalid value for ACTARM, value={data($actarmvalue)} in dataset {data($datasetlocation)}</error>
Missing value for DTHFL, when DTHDTC is populated - Subject Death Flag (DTHFL) value must equal 'Y', when Date/Time of Death (DTHDTC) is provided
DM
(: Rule FDAC201 - Missing value for DTHFL, when DTHDTC is populated:
Subject Death Flag (DTHFL) value must equal 'Y', when Date/Time of Death (DTHDTC) is provided
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the DM dataset :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OID of the DTHFL and of DTHDTC :)
let $dthfloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='DTHFL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
let $dhdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='DTHDTC']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records in the DM dataset that have DTHDTC populated :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$dhdtcoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of DTHFL :)
let $dthflvalue := $record/odm:ItemData[@ItemOID=$dthfloid]/@Value
(: and check whether DTHFL=Y :)
where not($dthflvalue='Y')
return <error rule="FDAC201" dataset="DM" variable="DTHFL" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Missing value for DTHFL, when DTHDTC is populated</error>
Missing value for DTHDTC, when DTHFL is populated - Date/Time of Death (DTHDTC) should be provided, when subject died (DTHFL=Y)
DM
(: Rule FDAC202 - Missing value for DTHDTC, when DTHFL is populated:
Date/Time of Death (DTHDTC) should be provided, when subject died (DTHFL=Y)
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the DM dataset :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OID of the DTHFL and of DTHDTC :)
let $dthfloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='DTHFL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
let $dhdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='DTHDTC']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records in the DM dataset that have DTHFL populated :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$dthfloid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of DTHDTC :)
let $dtcdtcvalue := $record/odm:ItemData[@ItemOID=$dhdtcoid]/@Value
(: and check whether DTHDTC is populated :)
where not($dtcdtcvalue)
return <warning rule="FDAC202" dataset="DM" variable="DTHDTC" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Missing value for DTHDTC, when DTHFL is populated</warning>
Missing value for DSCAT - Category for Disposition Event (DSCAT) should be populated
DS
(: Rule FDAC203 - Missing value for DSCAT:
Category for Disposition Event (DSCAT) should be populated
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the DS dataset :)
let $dsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DS']
let $dsdatasetname := $dsdataset/def:leaf/@xlink:href
let $dsdatasetlocation := concat($base,$dsdatasetname)
(: and get the OID of the DSCAT variable :)
let $dscatoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='DSCAT']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DS']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records in the DS dataset :)
for $record in doc($dsdatasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: and check whether DSCAT is populated :)
let $dscatvalue := $record/odm:ItemData[@ItemOID=$dscatoid]/@Value
where not($dscatvalue)
return <warning rule="FDAC203" dataset="DS" variable="DSCAT" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Missing value for DSCAT</warning>
Missing IDVAR value, when RDOMAIN value is provided - Value of Identifying Variable (IDVAR) variable must be populated, when Related Domain Abbreviation (RDOMAIN) variable value is provided, with the only exception of 'DM' value for RDOMAIN
RELREC
SUPPQUAL
(: Rule FDAC204 - Missing IDVAR value, when RDOMAIN value is provided:
Value of Identifying Variable (IDVAR) variable must be populated, when Related Domain Abbreviation (RDOMAIN) variable value is provided, with the only exception of 'DM' value for RDOMAIN
SUPPQUAL, RELREC
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over the RELREC and all SUPP-- datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name='RELREC' or starts-with(@Name,'SUPP')]
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OID of the IDVAR and RDOMAIN variables :)
let $idvaroid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='IDVAR']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $rdomainoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='RDOMAIN']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records that have RDOMAIN populated :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$rdomainoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the value of RDOMAIN and IDVAR (if any) :)
let $idvarvalue := $record/odm:ItemData[@ItemOID=$idvaroid]/@Value
let $rdomainvalue := $record/odm:ItemData[@ItemOID=$rdomainoid]/@Value
(: IDVAR must be populated, unless RDOMAIN=DM :)
where not($rdomainvalue='DM') and not($idvarvalue)
return <error rule="FDAC204" dataset="{data($name)}" variable="IDVAR" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Missing IDVAR value, when RDOMAIN value is provided, RDOMAIN={data($rdomainvalue)}</error>
Missing value for SEUPDES, when ETCD='UNPLAN' - Description of Unplanned Element (SEUPDES) should be populated, when subject's experience for a particular period of time is represented as an unplanned Element, where Element Code (ETCD) is equal to 'UNPLAN'
SE
(: Rule FDAC205 - Missing value for SEUPDES, when ETCD='UNPLAN':
Description of Unplanned Element (SEUPDES) should be populated, when subject's experience for a particular period of time is represented as an unplanned Element, where Element Code (ETCD) is equal to 'UNPLAN'
SE domain :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the SE dataset :)
let $sedataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='SE']
let $sedatasetname := $sedataset/def:leaf/@xlink:href
let $sedatasetlocation := concat($base,$sedatasetname)
(: and get the OID of ETCD and SEUPDES :)
let $etcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ETCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='SE']/odm:ItemRef/@ItemOID
return $a
)
let $seupdesoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='SEUPDES']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='SE']/odm:ItemRef/@ItemOID
return $a
)
(: get all records in the SE dataset that have ETCD=UNPLAN :)
for $record in doc($sedatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$etcdoid and @Value='UNPLAN']]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of SEUPDES and check whether it is populated :)
let $seupdesvalue := $record/odm:ItemData[@ItemOID=$seupdesoid]/@Value
where not($seupdesvalue)
return <warning rule="FDAC205" dataset="SE" variable="SEUPDES" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Missing value for SEUPDES, when ETCD='UNPLAN' in dataset {data($sedatasetname)}</warning>
No qualifiers set to 'Y', when AE is Serious - When Serious Event (AESER) variable value is 'Y', then at least one of seriousness criteria variables is expected to have value 'Y' (Involves Cancer (AESCAN), Congenital Anomaly or Birth Defect (AESCONG), Persist or Signif Disability/Incapacity (AESDISAB), Results in Death (AESDTH), Requires or Prolongs Hospitalization (AESHOSP), Is Life Threatening (AESLIFE), or Other Medicaly Important Serious Event (AESMIE))
AE
(: Rule FDAC206 - No qualifiers set to 'Y', when AE is Serious:
When Serious Event (AESER) variable value is 'Y', then at least one of seriousness criteria variables is expected to have value 'Y' (Involves Cancer (AESCAN), Congenital Anomaly or Birth Defect (AESCONG), Persist or Signif Disability/Incapacity (AESDISAB), Results in Death (AESDTH), Requires or Prolongs Hospitalization (AESHOSP), Is Life Threatening (AESLIFE), or Other Medicaly Important Serious Event (AESMIE))
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over the AE datasets (for the case there is more than 1) :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[@Domain='AE']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: and get the OIDs of AESER, AESCAN, AESCONG, AESDISAB, AESDTH, AESHOSP, AESLIFE and AESMIE :)
let $aeseroid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AESER']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $aescanoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AESCAN']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $aescongoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AESCONG']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $aesdisaboid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AESDISAB']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $aesdthoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AESDTH']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $aeshospoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AESHOSP']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $aeslifeoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AESLIFE']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $aesmieoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AESMIE']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records that have AESER=Y :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$aeseroid and @Value='Y']]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the values of AESCAN, AESCONG, AESDISAB, AESDTH, AESHOSP, AESLIFE and AESMIE (if any) :)
let $aescanvalue := $record/odm:ItemData[@ItemOID=$aescanoid]/@Value
let $aescongvalue := $record/odm:ItemData[@ItemOID=$aescongoid]/@Value
let $aesdisabvalue := $record/odm:ItemData[@ItemOID=$aesdisaboid]/@Value
let $aesdthvalue := $record/odm:ItemData[@ItemOID=$aesdthoid]/@Value
let $aeshospvalue := $record/odm:ItemData[@ItemOID=$aeshospoid]/@Value
let $aeslifevalue := $record/odm:ItemData[@ItemOID=$aeslifeoid]/@Value
let $aesmievalue := $record/odm:ItemData[@ItemOID=$aesmieoid]/@Value
(: at least one of AESCAN, AESCONG, AESDISAB, AESDTH, AESHOSP, AESLIFE and AESMIE must have the value 'Y' :)
where not($aescanvalue='Y' or $aescongvalue='Y' or $aesdisabvalue='Y' or $aesdthvalue='Y' or $aeshospvalue='Y' or $aeslifevalue='Y' or $aesmievalue='Y')
return <error rule="FDAC206" dataset="{data($name)}" variable="AESER" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">No qualifiers set to 'Y', when AE is Serious in dataset {data($datasetname)}</error>
Value for --OCCUR is populated for unsolicited Intervention or Event - Occurrence (--OCCUR) may only be populated, when a given Intervention or Event has been pre-specified (--PRESP = 'Y')
INTERVENTIONS
EVENTS
(: Rule FDAC207 - Value for --OCCUR is populated for unsolicited Intervention or Event:
Occurrence (--OCCUR) may only be populated, when a given Intervention or Event has been pre-specified (--PRESP = 'Y')
EVENTS AND INTERVENTIONS
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all INTERVENTIONS and EVENTS dataset :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[upper-case(@def:Class)='INTERVENTIONS' or upper-case(@def:Class)='EVENTS']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OID of the --OCCUR and --PRESP variables :)
let $occuroid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'OCCUR')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $occurname := doc(concat($base,$define))//odm:ItemDef[@OID=$occuroid]/@Name
let $prespoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'PRESP')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records that have OCCUR populated :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$occuroid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the value of PRESP (if present) :)
let $prespvalue := $record/odm:ItemData[@ItemOID=$prespoid]/@Value
(: Occurrence (--OCCUR) may only be populated, when a given Intervention or Event has been pre-specified (--PRESP = 'Y') :)
(: so PRESP MUST be 'Y' :)
where not($prespvalue) or not($prespvalue='Y')
return <error rule="FDAC207" dataset="{data($name)}" variable="{data($occurname)}" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Value for {data($occurname)} is populated for unsolicited Intervention or Event</error>
AE start date is after the latest Disposition date - Start Date/Time of Adverse Event (AESTDTC) should be less than or equal to the Start Date/Time of the latest Disposition Event (DSSTDTC)
AE
(: Rule FDAC208 - AE start date is after the latest Disposition date:
Start Date/Time of Adverse Event (AESTDTC) should be less than or equal to the Start Date/Time of the latest Disposition Event (DSSTDTC) :)
(: TODO: extensive testing - can we make this faster? DS is queried (too) many times :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the location of the DS dataset and the OID for the DSSTDTC and USUBJID attributes :)
let $dsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='DS']
let $dsdatasetname := $dsdataset/def:leaf/@xlink:href
let $dsdatasetlocation := concat($base,$dsdatasetname)
let $dsstdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='DSSTDTC']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DS']/odm:ItemRef/@ItemOID
return $a
)
let $dsusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DS']/odm:ItemRef/@ItemOID
return $a
)
(: Get the AE dataset(s) :)
for $aedataset in doc(concat($base,$define))//odm:ItemGroupDef[@Domain='AE']
let $aename := $aedataset/@Name
let $aedatasetname := $aedataset/def:leaf/@xlink:href
let $aedatasetlocation := concat($base,$aedatasetname)
(: and get the OID of AESTDC and USUBJID :)
let $aestdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AESTDTC']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$aename]/odm:ItemRef/@ItemOID
return $a
)
let $aeusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$aename]/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records in the AE dataset(s) that have AESTDTC populated :)
for $record in doc($aedatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$aestdtcoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of AESTDTC :)
let $aestdtcvalue := $record/odm:ItemData[@ItemOID=$aestdtcoid]/@Value
let $aeusubjidvalue := $record/odm:ItemData[@ItemOID=$aeusubjidoid]/@Value
(: now get the latest (maximal) value DSSTDTC in the DS dataset for this subject :)
let $dssdtcvalues := doc($dsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$dsusubjidoid and @Value=$aeusubjidvalue]]/odm:ItemData[@ItemOID=$dsstdtcoid]/@Value
(: get the latest DSSTDTC date :)
let $latestdate := max(for $date in $dssdtcvalues return xs:date($date))
(: AESTDTC must be BEFORE the latest DSSTDTC :)
where $aestdtcvalue and xs:date($latestdate) <= xs:date($aestdtcvalue)
return <error rule="FDAC208" dataset="AE" variable="AESTDTC" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">AE start date, value={data($aestdtcvalue)} is after the latest Disposition date, value={data($latestdate)}</error>
AESDTH is not 'Y', when AEOUT='FATAL' - Results in Death (AEDTH) should equal 'Y', when Outcome of Adverse Event (AEOUT) is 'FATAL'
AE
(: Rule FDAC209 - AESDTH is not 'Y', when AEOUT='FATAL':
Results in Death (AEDTH) should equal 'Y', when Outcome of Adverse Event (AEOUT) is 'FATAL'
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the AE dataset(s) :)
for $aedataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name='AE']
let $aename := $aedataset/@Name
let $aedatasetname := $aedataset/def:leaf/@xlink:href
let $aedatasetlocation := concat($base,$aedatasetname)
(: and get the OID of AESDTH and AEOUT :)
let $aesdthoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AESDTH']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$aename]/odm:ItemRef/@ItemOID
return $a
)
let $aeoutoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AEOUT']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$aename]/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records that have AEOUT='FATAL' :)
for $record in doc($aedatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$aeoutoid and @Value='FATAL']]
let $recnum := $record/@data:ItemGroupDataSeq
let $aesdthvalue := $record/odm:ItemData[@ItemOID=$aesdthoid]/@Value
(: AEDTH must be 'Y' :)
let $recnum := $record/@data:ItemGroupDataSeq
where not($aesdthvalue='Y')
return <error rule="FDAC209" dataset="AE" variable="AESDTH" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">AESDTH is not 'Y', when AEOUT='FATAL', value for AESDTH found is '{data($aesdthvalue)}'</error>
AEOUT is not 'FATAL', when AESDTH='Y' - Outcome of Adverse Event should equal 'FATAL', when Results in Death (AEDTH) is 'Y'
AE
(: Rule FDAC210 - AEOUT is not 'FATAL', when AESDTH='Y':
Outcome of Adverse Event should equal 'FATAL', when Results in Death (AEDTH) is 'Y'
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the AE dataset(s) :)
for $aedataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name='AE']
let $aename := $aedataset/@Name
let $aedatasetname := $aedataset/def:leaf/@xlink:href
let $aedatasetlocation := concat($base,$aedatasetname)
(: and get the OID of AESDTH and AEOUT :)
let $aesdthoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AESDTH']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$aename]/odm:ItemRef/@ItemOID
return $a
)
let $aeoutoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AEOUT']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$aename]/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records that have AESDTH=Y :)
for $record in doc($aedatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$aesdthoid and @Value='Y']]
let $recnum := $record/@data:ItemGroupDataSeq
let $aeoutvalue := $record/odm:ItemData[@ItemOID=$aeoutoid]/@Value
(: AEOUT must be 'FATAL' :)
let $recnum := $record/@data:ItemGroupDataSeq
where not($aeoutvalue='FATAL')
return <error rule="FDAC210" dataset="AE" variable="AEOUT" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">AEOUT is not 'FATAL', when AESDTH='Y', '{data($aeoutvalue)}' was found </error>
AESER is not 'Y', when AESOD equals 'Y' - Serious Event (AESER) variable value is expected to be 'Y', when Occurred with Overdose (AESOD) variable value equals 'Y'
AE
(: Rule FDAC211 - AESER is not 'Y', when AESOD equals 'Y':
Serious Event (AESER) variable value is expected to be 'Y', when Occurred with Overdose (AESOD) variable value equals 'Y'
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: Get the AE dataset(s) :)
for $aedataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name='AE']
let $aename := $aedataset/@Name
let $aedatasetname := $aedataset/def:leaf/@xlink:href
let $aedatasetlocation := concat($base,$aedatasetname)
(: and get the OID of the AESER and AESOD variables :)
let $aeseroid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AESER']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$aename]/odm:ItemRef/@ItemOID
return $a
)
let $aesodoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='AESOD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$aename]/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records that have AESOD=Y :)
for $record in doc($aedatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$aesodoid and @Value='Y']]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of AESER (if any) :)
let $aeservalue := $record/odm:ItemData[@ItemOID=$aeseroid]/@Value
(: AESER must have the value 'Y' :)
where not($aeservalue) or not($aeservalue='Y')
return <error rule="FDAC211" dataset="AE" variable="AESER" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">AESER is not 'Y', when AESOD equals 'Y', value found for AESER={data($aeservalue)}</error>
Duplicate records - The structure of Findings class domains should be one records per Finding Result per subject. No Finding Result with the same Test Short Name (--TESTCD) for the same Subject (USUBJID) and the same Collection Date (--DTC) are expected
FINDINGS
(: Rule FDAC212 - Duplicate records:
The structure of Findings class domains should be one records per Finding Result per subject. No Finding Result with the same Test Short Name (--TESTCD) for the same Subject (USUBJID) and the same Collection Date (--DTC) are expected.
:)
(: Identical observations should essentially have a different --DTC - if on the same date, the time part must be different :)
(: TODO? does not yet take 'splitted' datasets into account :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare namespace functx = "http://www.functx.com";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all FINDINGS domains :)
for $findingdomain in doc(concat($base,$define))//odm:ItemGroupDef[upper-case(@def:Class)='FINDINGS']
(: get the name and domain name, we need it for getting the complete name of the --TESTCD and --DTC variables :)
let $name := $findingdomain/@Name
let $domainname := $findingdomain/@Domain
(: get the OID of USUBJID variable :)
let $usubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: get the oid of the --TESTCD and --DTC variables :)
let $testcdname := concat($domainname,'TESTCD')
let $dtcname := concat($domainname,'DTC')
let $testcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name=$testcdname]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $dtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name=$dtcname]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: the hard part - iterate over all records in the dataset and find records with the same combination of USUBJID --TESTCD and --DTC :)
let $datasetname := $findingdomain/def:leaf/@xlink:href
let $dataset := doc(concat($base,$datasetname))
(: start iterating over all records that DO have a --DTC -
USUBJID and TESTCD are mandatory :)
for $record in $dataset//odm:ItemGroupData[odm:ItemData[@ItemOID=$dtcoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of USUBJID, --TESTCD and --DTC :)
let $usubjid := $record/odm:ItemData[@ItemOID=$usubjidoid]/@Value
let $testcd := $record/odm:ItemData[@ItemOID=$testcdoid]/@Value
let $dtc := $record/odm:ItemData[@ItemOID=$dtcoid]/@Value
(: count the number of records with the same combination of USUBJID, TESTCD and DTC
beyond the current record :)
let $count := count($dataset//odm:ItemGroupData[@data:ItemGroupDataSeq > $recnum][odm:ItemData[@ItemOID=$usubjidoid and @Value=$usubjid]][odm:ItemData[@ItemOID=$testcdoid and @Value=$testcd]][odm:ItemData[@ItemOID=$dtcoid and @Value=$dtc]])
where $count > 0
return <warning rule="FDAC212" dataset="{data($name)}" variable="{data($dtc)}" rulelastupdate="2015-08-28" recordnuber="{data($recnum)}">Duplicate Finding Result with the same Test Short Name {data($testcdname)}={data($testcd)} for the same Subject USUBJID={data($usubjid)} and the same Collection Date {data($dtcname)}={data($dtc)} found in dataset {data($datasetname)}. Number of occurrences of this combination is {data($count+1)}</warning>
Duplicate USUBJID/--DECOD/--STDTC record - The structure of Events class domains should be one records per Event per subject. No Events with the same Collected Term (--TERM), Decoded Term (--DECOD), Category (--CAT), Subcategory (--SCAT), Severity (--SEV), and Toxicity Grade (--TOXGR) values for the same Subject (USUBJID) and the same Start Date (--STDTC) are expected
EVENTS
(: Rule FDAC213 - Duplicate USUBJID/--DECOD/--STDTC record:
The structure of Events class domains should be one records per Event per subject. No Events with the same Collected Term (--TERM), Decoded Term (--DECOD), Category (--CAT), Subcategory (--SCAT), Severity (--SEV), and Toxicity Grade (--TOXGR) values for the same Subject (USUBJID) and the same Start Date (--STDTC) are expected.
EVENTS domains
:)
(: TODO? this does not look over splitted datasets for the same domain yet :)
(: tested on CDISCPILOT01 (LZZT) dataset where records number 5 and 7 seems to be equal :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all EVENTS datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[upper-case(@def:Class)='EVENTS']
let $name := $dataset/@Name
let $domain := $dataset/@Domain
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OIDs of the --STDTC, --TERM, --DECOD, --CAT, --SCAT, --SEV, --TOXGR and USUBJID :)
let $stdtcoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STDTC')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $stdtcname := doc(concat($base,$define))//odm:ItemDef[@OID=$stdtcoid]/@Name
let $termoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TERM')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $termname := doc(concat($base,$define))//odm:ItemDef[@OID=$termoid]/@Name
let $decodoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'DECOD')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $decodname := doc(concat($base,$define))//odm:ItemDef[@OID=$decodoid]/@Name
let $catoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'CAT') and string-length(@Name)=5]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $catname := doc(concat($base,$define))//odm:ItemDef[@OID=$catoid]/@Name
let $scatoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'SCAT') and string-length(@Name)=6]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $scatname := doc(concat($base,$define))//odm:ItemDef[@OID=$scatoid]/@Name
let $sevoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'SEV')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $sevname := doc(concat($base,$define))//odm:ItemDef[@OID=$sevoid]/@Name
let $toxgroid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'TOXGR')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $toxgrname := doc(concat($base,$define))//odm:ItemDef[@OID=$toxgroid]/@Name
let $usubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records in the dataset, and collect the values (if any) of --TERM, --DECOD, --CAT, --SCAT, --SEV, --TOXGR and USUBJID :)
for $record in doc($datasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
let $usubjidvalue := $record/odm:ItemData[@ItemOID=$usubjidoid]/@Value
let $catvalue := $record/odm:ItemData[@ItemOID=$catoid]/@Value
let $scatvalue := $record/odm:ItemData[@ItemOID=$scatoid]/@Value
let $termvalue := $record/odm:ItemData[@ItemOID=$termoid]/@Value
let $decodvalue := $record/odm:ItemData[@ItemOID=$decodoid]/@Value
let $sevvalue := $record/odm:ItemData[@ItemOID=$sevoid]/@Value
let $toxgrvalue := $record/odm:ItemData[@ItemOID=$toxgroid]/@Value
let $stdtcvalue := $record/odm:ItemData[@ItemOID=$stdtcoid]/@Value
(: now iterate over all next records for the same USUBJID :)
for $record2 in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$usubjidoid]/@Value=$usubjidvalue and @data:ItemGroupDataSeq > $recnum]
let $recnum2 := $record2/@data:ItemGroupDataSeq
(: and also here, get the values (if any) of --TERM, --DECOD, --CAT, --SCAT, --SEV and --TOXGR :)
let $usubjidvalue2 := $record2/odm:ItemData[@ItemOID=$usubjidoid]/@Value
let $catvalue2 := $record2/odm:ItemData[@ItemOID=$catoid]/@Value
let $scatvalue2 := $record2/odm:ItemData[@ItemOID=$scatoid]/@Value
let $termvalue2 := $record2/odm:ItemData[@ItemOID=$termoid]/@Value
let $decodvalue2 := $record2/odm:ItemData[@ItemOID=$decodoid]/@Value
let $sevvalue2 := $record2/odm:ItemData[@ItemOID=$sevoid]/@Value
let $toxgrvalue2 := $record2/odm:ItemData[@ItemOID=$toxgroid]/@Value
let $stdtcvalue2 := $record2/odm:ItemData[@ItemOID=$stdtcoid]/@Value
(: values of --TERM, --DECOD, --CAT, --SCAT, --SEV and TOXGR may not be equals :)
(: we use 2 variables - one boolean to check whether both variables (from the different records) are populated, and one whether the values are equals :)
let $bothtermvaluespresent := $termvalue and $termvalue2 (: whether both populated - boolean :)
let $termvaluesequal := $termvalue and $termvalue2 and $termvalue=$termvalue2 (: whether both equal - boolean :)
let $bothdecodevaluespresent := $decodvalue and $decodvalue2 (: boolean :)
let $decodvaluesequal := $decodvalue and $decodvalue2 and $decodvalue=$decodvalue2 (: boolean :)
let $bothcatvaluespresent := $catvalue and $catvalue2 (: boolean :)
let $catvaluesequal := $catvalue and $catvalue2 and $catvalue=$catvalue2 (: boolean :)
let $bothscatvaluespresent := $scatvalue and $scatvalue2 (: boolean :)
let $scatvaluesequal := $scatvalue and $scatvalue2 and $scatvalue=$scatvalue2 (: boolean :)
let $bothsevvaluespresent := $sevvalue and $sevvalue2 (: boolean :)
let $sevvaluesequal := $sevvalue and $sevvalue2 and $sevvalue=$sevvalue2 (: boolean :)
let $bothtoxgrvaluespresent := $toxgrvalue and $toxgrvalue2 (: boolean :)
let $toxgrvaluesequal := $toxgrvalue and $toxgrvalue2 and $toxgrvalue=$toxgrvalue2 (: boolean :)
let $bothstdtcvaluespresent := $stdtcvalue and $stdtcvalue2 (: boolean :)
let $stdtcvaluesequal := $stdtcvalue and $stdtcvalue2 and $stdtcvalue=$stdtcvalue2 (: boolean :)
(: check equality :)
let $equality := (not($bothtermvaluespresent) or $termvaluesequal)
and (not($bothdecodevaluespresent) or $decodvaluesequal)
and (not($bothcatvaluespresent) or $catvaluesequal)
and (not($bothscatvaluespresent) or $scatvaluesequal)
and (not($bothsevvaluespresent) or $sevvaluesequal)
and (not($bothtoxgrvaluespresent) or $toxgrvaluesequal)
and (not($bothstdtcvaluespresent) or $stdtcvaluesequal)
where $equality
return <warning rule="FDAC213" dataset="{data($name)}" variable="USUBJID" rulelastupdate="2015-02-11" recordnumber="{data($recnum2)}">Duplicate USUBJID/{data($decodname)}/{data($stdtcname)} record. Combination of values of {data($termname)}, {data($decodname)}, {data($catname)}, {data($scatname)}, {data($sevname)}, {data($toxgrname)}, {data($stdtcname)}, is equal for USUBJID={data($usubjidvalue)}, in records number {data($recnum)} and {data($recnum2)} in dataset {data($datasetname)}</warning>
Value for --STNRHI is less than value for --STNRLO - Reference Range Upper Limit-Std Units (--STNRHI) value must be greater than or equal to Reference Range Lower Limit-Std Units (--STNRLO) value
FINDINGS
(: Rule FDAC215 - Value for --STNRHI is less than value for --STNRLO:
Reference Range Upper Limit-Std Units (--STNRHI) value must be greater than or equal to Reference Range Lower Limit-Std Units (--STNRLO) value
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all FINDINGS datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[upper-case(@def:Class)='FINDINGS']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: get the OID of the STNRHI and STNRLO variables :)
let $stnrhioid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STNRHI')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $stnrihname := doc(concat($base,$define))//odm:ItemDef[@OID=$stnrhioid]/@Name
let $stnrlooid := (
for $a in doc(concat($base,$define))//odm:ItemDef[ends-with(@Name,'STNRLO')]/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $stnrloname := doc(concat($base,$define))//odm:ItemDef[@OID=$stnrlooid]/@Name
(: iterate over all records for which there is as well a populated STNRHI as STNTLO data point :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$stnrlooid] and odm:ItemData[@ItemOID=$stnrhioid]][@data:ItemGroupDataSeq<10]
let $recnum := $record/@data:ItemGroupDataSeq
(: get both the values :)
let $stnrlovalue := $record/odm:ItemData[@ItemOID=$stnrlooid]/@Value
let $stnrhivalue := $record/odm:ItemData[@ItemOID=$stnrhioid]/@Value
(: convert to numeric and compare both values :)
(: --STNRHI must not be smaller than STNRLO :)
where number($stnrhivalue) < number($stnrlovalue)
return <error rule="FDAC215" dataset="{data($name)}" variable="{data(stnrihname)}" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Value for {data($stnrihname)}, value={data($stnrhivalue)} is less than value for {data($stnrloname)}, value={data($stnrlovalue)}</error>
Duplicate ELEMENT value - The value of Element (Description of Element) variable must be unique within Trial Elements (TE) domain
TE
(: Rule FDAC218 - Duplicate ELEMENT value:
The value of Element (Description of Element) variable must be unique within Trial Elements (TE) domain
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TE dataset :)
let $tedataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TE']
let $tedatasetname := $tedataset/def:leaf/@xlink:href
let $tedatasetlocation := concat($base,$tedatasetname)
(: get the OID of the ELEMENT variable :)
let $elementoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ELEMENT']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TE']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records in the TE dataset :)
for $record in doc($tedatasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of ELEMENT :)
let $elementvalue := $record//odm:ItemData[@ItemOID=$elementoid]/@Value
(: iterate over all following records :)
for $record2 in doc($tedatasetlocation)//odm:ItemGroupData[@data:ItemGroupDataSeq > $recnum]
(: and compare the value of ELEMENT in the record with the original one :)
let $recnum2 := $record2/@data:ItemGroupDataSeq
let $elementvalue2 := $record2//odm:ItemData[@ItemOID=$elementoid]/@Value
where $elementvalue=$elementvalue2
return <warning rule="FDAC218" dataset="TE" variable="ELEMENT" rulelastupdate="2015-02-11" recordnumber="{data($recnum2)}">Duplicate ELEMENT value: records {data($recnum)} and {data($recnum2)} have the same value for ELEMENT, value={data($elementvalue)}</warning>
Duplicate ETCD value - The value of Element Code (ETCD) variable must be unique within Trial Elements (TE) domain
TE
(: Rule FDAC219 - Duplicate ELEMENT value:
The value of Element (Description of Element) variable must be unique within Trial Elements (TE) domain
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TE dataset :)
let $tedataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TE']
let $tedatasetname := $tedataset/def:leaf/@xlink:href
let $tedatasetlocation := concat($base,$tedatasetname)
(: get the OID of the ETCD variable :)
let $etcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ETCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TE']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records in the TE dataset :)
for $record in doc($tedatasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of ETCD :)
let $etcdvalue := $record//odm:ItemData[@ItemOID=$etcdoid]/@Value
(: iterate over all following records :)
for $record2 in doc($tedatasetlocation)//odm:ItemGroupData[@data:ItemGroupDataSeq > $recnum]
(: and compare the value of ETCD in the record with the original one :)
let $recnum2 := $record2/@data:ItemGroupDataSeq
let $etcdvalue2 := $record2//odm:ItemData[@ItemOID=$etcdoid]/@Value
where $etcdvalue=$etcdvalue2
return <error rule="FDAC219" dataset="TE" variable="ETCD" rulelastupdate="2015-02-11" recordnumber="{data($recnum2)}">Duplicate ETCD value: records {data($recnum)} and {data($recnum2)} have the same value for ETCD, value={data($etcdvalue)}</error>
ELEMENT value is populated, when ETCD= 'UNPLAN' - Description of Element (ELEMENT) should be NULL, when subject's experience for a particular period of time is represented as an unplanned Element, where Element Code (ETCD) is equal to 'UNPLAN'
SE
(: Rule FDAC220 - ELEMENT value is populated, when ETCD= 'UNPLAN':
Description of Element (ELEMENT) should be NULL, when subject's experience for a particular period of time is represented as an unplanned Element, where Element Code (ETCD) is equal to 'UNPLAN'
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the SE dataset :)
let $sedataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='SE']
let $sedatasetname := $sedataset/def:leaf/@xlink:href
let $sedatasetlocation := concat($base,$sedatasetname)
(: and get the OID of the ELEMENT and ETCD :)
let $etcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ETCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='SE']/odm:ItemRef/@ItemOID
return $a
)
let $elementoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ELEMENT']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='SE']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records in the SE dataset that do have a value for ETCD :)
for $record in doc($sedatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$etcdoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the value of ETCD and ELEMENT :)
let $etcdvalue := $record/odm:ItemData[@ItemOID=$etcdoid]/@Value
let $elementvalue := $record/odm:ItemData[@ItemOID=$elementoid]/@Value
(: when ETCD=UNPLAN then ELEMENT should be empty (null) :)
where $etcdvalue='UNPLAN' and string-length($elementvalue) > 0
return <warning rule="FDAC220" dataset="SE" variable="ELEMENT" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">ELEMENT value is populated, when ETCD='UNPLAN', value found for ELEMENT={data($elementvalue)}</warning>
Non-unique value for ELEMENT within ETCD in SE, TA - Description of Element (ELEMENT) must have a unique value for a given value of Element Code (ETCD) within the domain
SE
TA
(: Rule FDAC221 - Non-unique value for ELEMENT within ETCD in SE, TA:
Description of Element (ELEMENT) must have a unique value for a given value of Element Code (ETCD) within the domain
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the SE and TA datasets :)
for $dataset in doc(concat($base,$define))//odm:ItemGroupDef[@Name='SE' or @Name='TA']
let $name := $dataset/@Name
let $datasetname := $dataset/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: and get the OID of the ELEMENT and ETCD :)
let $etcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ETCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
let $elementoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ELEMENT']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name=$name]/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records that have BOTH ETCD and ELEMENT populated :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$etcdoid] and odm:ItemData[@ItemOID=$elementoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the values of ETCD and ELEMENT :)
let $etcdvalue := $record/odm:ItemData[@ItemOID=$etcdoid]/@Value
let $elementvalue := $record/odm:ItemData[@ItemOID=$elementoid]/@Value
(: iterate over all further records that DO have ETCD and ELEMENT populated :)
for $record2 in doc($datasetlocation)//odm:ItemGroupData[@data:ItemGroupDataSeq > $recnum][odm:ItemData[@ItemOID=$etcdoid] and odm:ItemData[@ItemOID=$elementoid]]
let $recnum2 := $record2/@data:ItemGroupDataSeq
(: and again, get the values of ETCD and ELEMENT :)
let $etcdvalue2 := $record2/odm:ItemData[@ItemOID=$etcdoid]/@Value
let $elementvalue2 := $record2/odm:ItemData[@ItemOID=$elementoid]/@Value
(: get the duplicates :)
where $etcdvalue=$etcdvalue2 and $elementvalue=$elementvalue2
return <error rule="FDAC221" dataset="{data($name)}" variable="ELEMENT" rulelastupdate="2017-02-19" recordnumber="{data($recnum2)}">Non-unique value for ELEMENT within ETCD. Records {data($recnum)} and {data($recnum2)} have the same combination of ETCD={data($etcdvalue)} and ELEMENT={data($elementvalue)} in dataset {data($name)}</error>
TAETORD is populated, ETCD = 'UNPLAN' - Planned Order of Elements within Arm (TAETORD) should be NULL, when subject's experience for a particular period of time is represented as an unplanned Element (ETCD = 'UNPLAN')
SE
(: Rule FDAC223 - TAETORD is populated, ETCD = 'UNPLAN':
Planned Order of Elements within Arm (TAETORD) should be NULL, when subject's experience for a particular period of time is represented as an unplanned Element (ETCD = 'UNPLAN')
SE dataset :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the SE dataset :)
let $sedataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='SE']
let $sedatasetname := $sedataset/def:leaf/@xlink:href
let $sedatasetlocation := concat($base,$sedatasetname)
(: and get the OID of the TAETORD and ETCD variables :)
let $taetordoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TAETORD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='SE']/odm:ItemRef/@ItemOID
return $a
)
let $etcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='ETCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='SE']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records in the SE dataset that have ETCD=UNPLAN :)
for $record in doc($sedatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$etcdoid and @Value='UNPLAN']]
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the value of TAETORD - if any :)
let $taetordvalue := $record/odm:ItemData[@ItemOID=$taetordoid]/@Value
(: TAETORD must be null :)
where string-length($taetordvalue) > 0
return <warning rule="FDAC223" dataset="SE" variable="TAETORD" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">TAETORD is populated, value={data($taetordvalue)} with ETCD='UNPLAN' in dataset SE</warning>
VISITDY is populated for unplanned visit - Planned Study Day of Visit (VISITDY) should equal NULL for unplanned visits, where Description of Unplanned Visit (SVUPDES) is populated
SV
(: Rule FDAC224 - VISITDY is populated for unplanned visit:
Planned Study Day of Visit (VISITDY) should equal NULL for unplanned visits, where Description of Unplanned Visit (SVUPDES) is populated
SV dataset
:)
(: TODO: testing - we did not have a good testing dataset :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the SV dataset :)
let $svdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='SV']
let $svdatasetname := $svdataset/def:leaf/@xlink:href
let $svdatasetlocation := concat($base,$svdatasetname)
(: and get the OID of the VISITDY and SVUPDES variables :)
let $visitdyoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='VISITDY']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='SV']/odm:ItemRef/@ItemOID
return $a
)
let $svsupdesoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='SVUPDES']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='SV']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records in the SV dataset that have SVUPDES populated :)
for $record in doc($svdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$svsupdesoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the value of VISITDY - if any :)
let $visitdyvalue := $record/odm:ItemData[@ItemOID=$visitdyoid]/@Value
(: VISITDY must be null :)
return <warning rule="FDAC224" dataset="SV" variable="VISITDY" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">VISITDY is populated for unplanned visit, value for VISITDY={data($visitdyvalue)} in dataset SE</warning>
VISITNUM value does not match TV domain data - Visit Number (VISITNUM) values should match entries in the Trial Visits (TV) dataset, when they are planned visits (SVUPDES = NULL)
SV
(: Rule FDAC225 - VISITNUM value does not match TV domain data:
Visit Number (VISITNUM) values should match entries in the Trial Visits (TV) dataset, when they are planned visits (SVUPDES = NULL)
SV dataset
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare namespace functx = "http://www.functx.com";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
declare function functx:is-value-in-sequence
($value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TV dataset :)
let $tvdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TV']
let $tvdatasetname := $tvdataset/def:leaf/@xlink:href
let $tvdatasetlocation := concat($base,$tvdatasetname)
(: and the OID of VISITNUM in TV :)
let $tvvisitnumoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='VISITNUM']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TV']/odm:ItemRef/@ItemOID
return $a
)
(: get all VISITNUM values as a sequence from the TV dataset :)
let $visitnumsequence := distinct-values(
for $itemdata in doc($tvdatasetlocation)//odm:ItemGroupData/odm:ItemData[@ItemOID=$tvvisitnumoid]
return $itemdata/@Value
)
(: get the SV dataset :)
let $svdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='SV']
let $svdatasetname := $svdataset/def:leaf/@xlink:href
let $svdatasetlocation := concat($base,$svdatasetname)
(: and get the OID of the VISITNUM and SVUPDES in SV :)
let $svvisitnumoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='VISITNUM']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='SV']/odm:ItemRef/@ItemOID
return $a
)
let $svupdesoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='SVUPDES']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='SV']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records in SV where there is a value for VISITNUM and SVUPDES is null :)
for $record in doc($svdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$svvisitnumoid] and not(odm:ItemData[@ItemOID=$svupdesoid])]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of VISITNUM :)
let $svvisitnumvalue := $record/odm:ItemData[@ItemOID=$svvisitnumoid]/@Value
(: and check whether in the list of VISITNUMs in TV :)
where not(functx:is-value-in-sequence($svvisitnumvalue,$visitnumsequence))
return <warning rule="FDAC225" dataset="SV" variable="VISITNUM" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">VISITNUM value={data($svvisitnumvalue)} in SV does not match TV domain data</warning>
VISITNUM/VISIT/VISITDY values do not match TV domain data - The combination of Visit Number (VISITNUM), Visit Name (VISIT), and Planned Study Day of Visit (VISITDY) values should match entries in the Trial Visits (TV) dataset, when they are planned visits (SVUPDES = NULL)
SV
(: Rule FDAC226 - VISITNUM/VISIT/VISITDY values do not match TV domain data:
The combination of Visit Number (VISITNUM), Visit Name (VISIT), and Planned Study Day of Visit (VISITDY) values should match entries in the Trial Visits (TV) dataset, when they are planned visits (SVUPDES = NULL)
SV dataset
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare namespace functx = "http://www.functx.com";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
declare function functx:is-value-in-sequence
($value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TV dataset :)
let $tvdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TV']
let $tvdatasetname := $tvdataset/def:leaf/@xlink:href
let $tvdatasetlocation := concat($base,$tvdatasetname)
(: get the OID of the VISITNUM, VISIT and VISITDY in the TV daatset :)
let $tvvisitnumoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='VISITNUM']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TV']/odm:ItemRef/@ItemOID
return $a
)
let $tvvisitoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='VISIT']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TV']/odm:ItemRef/@ItemOID
return $a
)
let $tvvisitdyoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='VISITDY']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TV']/odm:ItemRef/@ItemOID
return $a
)
(: get the SV dataset :)
let $svdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='SV']
let $svdatasetname := $svdataset/def:leaf/@xlink:href
let $svdatasetlocation := concat($base,$svdatasetname)
(: get the OID of ISITNUM, VISIT and VISITDY and SVUPDES in the SV dataset
(these may be different from within TV) :)
(: iterate over all the records in the SV dataset :)
let $svvisitnumoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='VISITNUM']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='SV']/odm:ItemRef/@ItemOID
return $a
)
let $svvisitoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='VISIT']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='SV']/odm:ItemRef/@ItemOID
return $a
)
let $svvisitdyoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='VISITDY']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='SV']/odm:ItemRef/@ItemOID
return $a
)
let $svupdesoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='SVUPDES']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='SV']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all the records in the SV dataset that have SVUPDES=null :)
for $record in doc($svdatasetlocation)//odm:ItemGroupData[not(odm:ItemData[@ItemOID=$svupdesoid])]
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the value of VISITNUM, VISIT and VISITDY :)
let $svvisitnumvalue := $record/odm:ItemData[@ItemOID=$svvisitnumoid]/@Value
let $svvisitvalue := $record/odm:ItemData[@ItemOID=$svvisitoid]/@Value
let $svvisitdyvalue := $record/odm:ItemData[@ItemOID=$svvisitdyoid]/@Value
(: now find the record in the TV dataset that has the same VISITNUM :)
let $tvrecord := doc($tvdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tvvisitnumoid and @Value=$svvisitnumvalue]]
(: and get the VISIT and VISITDY values :)
let $tvvisitvalue := $tvrecord/odm:ItemData[@ItemOID=$tvvisitoid]/@Value
let $tvvisitdyvalue := $tvrecord/odm:ItemData[@ItemOID=$tvvisitdyoid]/@Value
(: there must be a 1:1 match :)
where not($tvrecord) or not($svvisitvalue=$tvvisitvalue) or not($svvisitdyvalue=$tvvisitdyvalue)
return <warning rule="FDAC226" dataset="SV" variable="VISITNUM" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">VISITNUM/VISIT/VISITDY values in SV do not match TV domain data, SV VISITNUM={data($svvisitnumvalue)}, VISIT={data($svvisitvalue)}, VISITDY={data($svvisitdyvalue)}</warning>
Missing ADDON Trial Summary Parameter - Added on to Existing Treatments' (ADDON) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions
TS
(: Rule FDAC234 - Missing ADDON Trial Summary Parameter
'Added on to Existing Treatments' (ADDON) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of records in the TS dataset that have TSPARMCD=ADDON :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData/odm:ItemData[@ItemOID=$tsparmcdoid and @Value='ADDON'])
(: there must be more than 0 such records :)
where $count = 0
return <error rule="FDAC234" dataset="TS" variable="TSPARMCD" rulelastupdate="2015-09-05">Missing ADDON Trial Summary Parameter in dataset TS</error>
Multiple ADDON records - Trial Summary (TS) domain must contain only one record for 'ADDON' Parameter
TS
(: Rule FDAC235 - Multiple ADDON records:
Trial Summary (TS) domain must contain only one record for 'ADDON' Parameter
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of records in the TS dataset that have TSPARMCD=ADDON :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData/odm:ItemData[@ItemOID=$tsparmcdoid and @Value='ADDON'])
(: there must be not more than 1 such records :)
where $count > 1
return <error rule="FDAC235" dataset="TS" variable="TSPARMCD" rulelastupdate="2015-02-11">Multiple ADDON records in dataset TS, number of ADDON records found ={data($count)}</error>
Missing AGEMAX Trial Summary Parameter - 'Planned Maximum Age of Subjects' (AGEMAX) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions
TS
(: Rule FDAC236 - Missing AGEMAX Trial Summary Parameter:
'Planned Maximum Age of Subjects' (AGEMAX) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of records in the TS dataset that have TSPARMCD=AGEMAX :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData/odm:ItemData[@ItemOID=$tsparmcdoid and @Value='AGEMAX'])
(: there must be more at least 1 such record :)
where $count = 0
return <error rule="FDAC236" dataset="TS" variable="TSPARMCD" rulelastupdate="2015-02-11">Missing AGEMAX Trial Summary Parameter in dataset TS</error>
Invalid TSVAL value for AGEMAX - TSVAL value must be either ISO 8601 format for time period (e.g. P80Y) or null, when TSPARMCD='AGEMAX'
TS
(: Rule FDAC237 - Invalid TSVAL value for AGEMAX:
TSVAL value must be either ISO 8601 format for time period (e.g. P80Y) or null, when TSPARMCD='AGEMAX'
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable and of the TSVAL variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get the record in the TS dataset that has TSPARMCD=AGEMAX :)
let $tsagemaxrecord := doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='AGEMAX']]
(: and get the TSVAL value :)
let $tsvalvalue := $tsagemaxrecord/odm:ItemData[@ItemOID=$tsvaloid]/@Value
(: TSVAL must be either null or in ISO-8601 "duration" format :)
where $tsvalvalue and not($tsvalvalue castable as xs:duration)
return <error rule="FDAC237" dataset="TS" variable="TSVAL" rulelastupdate="2015-02-11" recordnumber="{data($tsagemaxrecord)}">Invalid (non-ISO8601) TSVAL value={data($tsvalvalue)} for AGEMAX in dataset TS</error>
Multiple AGEMAX records - Trial Summary (TS) domain must contain only one record for 'AGEMAX' Parameter
TS
(: Rule FDAC238 - Multiple AGEMAX records:
Trial Summary (TS) domain must contain only one record for 'AGEMAX' Parameter
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of records for which TSPARMCD=AGEMAX :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='AGEMAX']])
(: The number of AGEMAX records may not be larger than 1 :)
where $count > 1
return <error rule="FDAC238" dataset="TS" variable="TSPARMCD" rulelastupdate="2015-02-11">Multiple AGEMAX records in TS: number of AGEMAX records found={data($count)}</error>
Missing AGEMIN Trial Summary Parameter - 'Planned Minimum Age of Subject' (AGEMIN) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions
TS
(: Rule FDAC239 - Missing AGEMIN Trial Summary Parameter:
'Planned Minimum Age of Subject' (AGEMIN) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of records for which TSPARMCD=AGEMIN :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='AGEMIN']])
(: The number of AGEMIN records may not be 0 :)
where $count = 0
return <error rule="FDAC239" dataset="TS" variable="TSPARMCD" rulelastupdate="2015-02-11">Missing AGEMIN Trial Summary Parameter in dataset TS</error>
Invalid TSVAL value for AGEMIN - TSVAL value must be either ISO 8601 format for time period (e.g. P80Y) or null, when TSPARMCD='AGEMIN'
TS
(: Rule FDAC240 - Invalid TSVAL value for AGEMIN:
TSVAL value must be either ISO 8601 format for time period (e.g. P80Y) or null, when TSPARMCD='AGEMIN'
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable and of the TSVAL variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get the record in the TS dataset that has TSPARMCD=AGEMIN :)
let $tsageminrecord := doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='AGEMIN']]
let $tsageminrecordnumber := $tsageminrecord/@data:ItemGroupDataSeq
(: and get the TSVAL value :)
let $tsvalvalue := $tsageminrecord/odm:ItemData[@ItemOID=$tsvaloid]/@Value
(: TSVAL must be either null or in ISO-8601 "duration" format :)
where $tsvalvalue and not($tsvalvalue castable as xs:duration)
return <error rule="FDAC240" dataset="TS" variable="TSVAL" rulelastupdate="2015-02-11" recordnumber="{data($tsageminrecordnumber)}">Invalid (non-ISO8601) TSVAL value={data($tsvalvalue)} for AGEMIN in dataset TS</error>
Multiple AGEMIN records - Trial Summary (TS) domain must contain only one record for 'AGEMIN' Parameter
TS
(: Rule FDAC241 - Multiple AGEMIN records:
Trial Summary (TS) domain must contain only one record for 'AGEMIN' Parameter
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of records for which TSPARMCD=AGEMIN :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='AGEMIN']])
(: The number of AGEMIN records may not be larger than 1 :)
where $count > 1
return <error rule="FDAC241" dataset="TS" variable="AGEMIN" rulelastupdate="2015-02-11">Multiple AGEMIN records in dataset TS: number of AGEMIN records found={data($count)}</error>
Missing LENGTH Trial Summary Parameter - 'Trial Length' (LENGTH) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions
TS
(: Rule FDAC242 - Missing LENGTH Trial Summary Parameter:
'Trial Length' (LENGTH) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of records for which TSPARMCD=LENGTH :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='LENGTH']])
(: The number of LENGTH records may not be 0 :)
where $count = 0
return <error rule="FDAC242" dataset="TS" variable="TSPARMCD" rulelastupdate="2015-02-11">Missing LENGTH Trial Summary Parameter in dataset TS</error>
Invalid TSVAL value for LENGTH - TSVAL value must be either ISO 8601 format for time period (e.g. P80Y) or null, when TSPARMCD='LENGTH'
TS
(: Rule FDAC243 - Invalid TSVAL value for LENGTH:
TSVAL value must be either ISO 8601 format for time period (e.g. P80Y) or null, when TSPARMCD='LENGTH'
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable and of the TSVAL variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get the record in the TS dataset that has TSPARMCD=LENGTH :)
let $lengthrecord := doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='LENGTH']]
let $lengthrecordnumber := $lengthrecord/@data:ItemGroupDataSeq
(: and get the TSVAL value :)
let $tsvalvalue := $lengthrecord/odm:ItemData[@ItemOID=$tsvaloid]/@Value
(: TSVAL must be either null or in ISO-8601 "duration" format :)
where $tsvalvalue and not($tsvalvalue castable as xs:duration)
return <error rule="FDAC243" dataset="TS" variable="TSVAL" rulelastupdate="2015-02-11" recordnumber="{data($lengthrecordnumber)}">Invalid (non-ISO8601) TSVAL value={data($tsvalvalue)} for LENGTH in dataset TS</error>
Multiple LENGTH records - Trial Summary (TS) domain must contain only one record for 'LENGTH' Parameter
TS
(: Rule FDAC244 - Multiple LENGTH records:
Trial Summary (TS) domain must contain only one record for 'LENGTH' Parameter
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of records for which TSPARMCD=LENGTH :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='LENGTH']])
(: The number of LENGTH records may not be larger than 1 :)
where $count > 1
return <error rule="FDAC244" dataset="TS" rulelastupdate="2015-02-11">Multiple LENGTH records in dataset TS: number of LENGTH records found={data($count)}</error>
Missing PLANSUB Trial Summary Parameter - 'Planned Number of Subjects' (PLANSUB) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions
TS
(: Rule FDAC245 - Missing PLANSUB Trial Summary Parameter:
'Planned Number of Subjects' (PLANSUB) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of records for which TSPARMCD=PLANSUB :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='PLANSUB']])
(: The number of PLANSUB records may not be 0 :)
where $count = 0
return <error rule="FDAC245" dataset="TS" variable="TSPARMCD" rulelastupdate="2015-02-11">Missing PLANSUB Trial Summary Parameter in dataset TS</error>
Invalid TSVAL value for PLANSUB - TSVAL for PLANSUB record must be numeric
TS
(: Rule FDAC246 - Invalid TSVAL value for PLANSUB:
TSVAL for PLANSUB record must be numeric
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable and of the TSVAL variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get the record in the TS dataset that has TSPARMCD=PLANSUB :)
let $tsageminrecord := doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='PLANSUB']]
let $tsageminrecordnumber := $tsageminrecord/@data:ItemGroupDataSeq
(: and get the TSVAL value :)
let $tsvalvalue := $tsageminrecord/odm:ItemData[@ItemOID=$tsvaloid]/@Value
(: TSVAL must be an integer :)
where $tsvalvalue and not($tsvalvalue castable as xs:integer)
return <error rule="FDAC246" rulelastupdate="2015-02-11" dataset="TS" variable="TSVAL" recordnumber="{data($tsageminrecordnumber)}">Invalid TSVAL value for PLANSUB, value={data($tsvalvalue)} in dataset TS</error>
Multiple PLANSUB records - Trial Summary (TS) domain must contain only one record for 'PLANSUB' Parameter
TS
(: Rule FDAC247 - Multiple PLANSUB records:
Trial Summary (TS) domain must contain only one record for 'PLANSUB' Parameter
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of records for which TSPARMCD=PLANSUB :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='PLANSUB']])
(: The number of PLANSUB records may not be larger than 1 :)
where $count > 1
return <error rule="FDAC247" dataset="TS" rulelastupdate="2015-02-11">Multiple PLANSUB Records in dataset TS: number of PLANSUB records found={data($count)}</error>
Missing RANDOM Trial Summary Parameter - 'Trial is Randomized' (RANDOM) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions
TS
(: Rule FDAC248 - Missing RANDOM Trial Summary Parameter:
'Trial is Randomized' (RANDOM) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of records for which TSPARMCD=RANDOM :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='RANDOM']])
(: The number of PLANSUB records may not be 0 :)
where $count = 0
return <error rule="FDAC248" dataset="TS" rulelastupdate="2015-02-11">Missing RANDOM Trial Summary Parameter in dataset TS</error>
Multiple RANDOM records - Trial Summary (TS) domain must contain only one record for 'RANDOM' Parameter
TS
(: Rule FDAC249 - Multiple RANDOM records:
Trial Summary (TS) domain must contain only one record for 'RANDOM' Parameter
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of records for which TSPARMCD=RANDOM :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='RANDOM']])
(: The number of RANDOM records may not be larger than 1 :)
where $count > 1
return <error rule="FDAC249" dataset="TS" rulelastupdate="2015-02-11">Multiple RANDOM Records in dataset TS: number of RANDOM records found={data($count)}</error>
Missing SEXPOP Trial Summary Parameter - 'Sex of Participants' (SEXPOP) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions
TS
(: Rule FDAC250 - Missing SEXPOP Trial Summary Parameter:
'Sex of Participants' (SEXPOP) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of records for which TSPARMCD=SEXPOP :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='SEXPOP']])
(: The number of SEXPOP records may not be 0 :)
where $count = 0
return <error rule="FDAC250" dataset="TS" rulelastupdate="2015-02-11">Missing SEXPOP Trial Summary Parameter in dataset TS</error>
Multiple SEXPOP records - Trial Summary (TS) domain must contain only one record for 'SEXPOP' Parameter
TS
(: Rule FDAC251 - Multiple SEXPOP records:
Trial Summary (TS) domain must contain only one record for 'SEXPOP' Parameter
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of records for which TSPARMCD=SEXPOP :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='SEXPOP']])
(: The number of SEXPOP records may not be larger than 1 :)
where $count > 1
return <error rule="FDAC251" dataset="TS" variable="SEXPOP" rulelastupdate="2015-02-11">Multiple SEXPOP Records: number of SEXPOP records found={data($count)}</error>
Missing STOPRULE Trial Summary Parameter - 'Study Stop Rules' (STOPRULE) record may be populated in Trial Summay (TS) domain. It is permissible for SDTM IG v3.1.2 data and in all more recent SDTM versions
TS
(: Rule FDAC252 - Missing STOPRULE Trial Summary Parameter:
'Study Stop Rules' (STOPRULE) record may be populated in Trial Summay (TS) domain. It is permissible for SDTM IG v3.1.2 data and in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of records for which TSPARMCD=STOPRULE :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='STOPRULE']])
(: The number of STOPRULE records may not be 0 :)
where $count = 0
return <error rule="FDAC252" dataset="TS" rulelastupdate="2015-02-11">Missing STOPRULE Trial Summary Parameter in dataset TS</error>
Missing TBLIND Trial Summary Parameter - 'Trial Blinding Schema' (TBLIND) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions
TS
(: Rule FDAC253 - Missing TBLIND Trial Summary Parameter:
'Trial Blinding Schema' (TBLIND) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of records for which TSPARMCD=TBLIND :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='TBLIND']])
(: The number of TBLIND records may not be 0 :)
where $count = 0
return <error rule="FDAC253" rulelastupdate="2015-02-11">Missing TBLIND Trial Summary Parameter in dataset {data($tsdatasetname)}</error>
Missing TCNTRL Trial Summary Parameter - 'Control Type' (TCNTRL) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions
TS
(: Rule FDAC254 - Missing TCNTRL Trial Summary Parameter:
'Control Type' (TCNTRL) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of records for which TSPARMCD=TCNTRL :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='TCNTRL']])
(: The number of TCNTRL records may not be 0 :)
where $count = 0
return <error rule="FDAC254" dataset="TS" rulelastupdate="2015-02-11">Missing TCNTRL Trial Summary Parameter in dataset TS</error>
Missing TDIGRP Trial Summary Parameter - 'Diagnosis Group' (TDIGRP) record must be populated in Trial Summay (TS) domain, when study population is unhealthy subjects (HLTSUBJI = 'N'). It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions
TS
(: Rule FDAC255 - Missing TDIGRP Trial Summary Parameter:
'Diagnosis Group' (TDIGRP) record must be populated in Trial Summay (TS) domain, when study population is unhealthy subjects (HLTSUBJI = 'N'). It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of records for which TSPARMCD=TDIGRP :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='TDIGRP']])
(: The number of TDIGRP records may not be 0 :)
where $count = 0
return <error rule="FDAC255" dataset="TS" rulelastupdate="2015-02-11">Missing TDIGRP Trial Summary Parameter in dataset TS</error>
Missing TINDTP Trial Summary Parameter - 'Trial Indication Type' (TINDTP) record must be populated in Trial Summay (TS) domain, when study type is 'INTERVENTIONAL'. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions
TS
(: Rule FDAC256 - Missing TINDTP Trial Summary Parameter
'Trial Indication Type' (TINDTP) record must be populated in Trial Summay (TS) domain, when study type is 'INTERVENTIONAL'. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of records for which TSPARMCD=TINDTP :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='TINDTP']])
(: The number of TINDTP records may not be 0 :)
where $count = 0
return <error rule="FDAC256" dataset="TS" rulelastupdate="2015-02-11">Missing TINDTP Trial Summary Parameter in dataset TS</error>
Missing TITLE Trial Summary Parameter - 'Trial Title' (TITLE) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions
TS
(: Rule FDAC257 - Missing TITLE Trial Summary Parameter:
'Trial Title' (TITLE) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of records for which TSPARMCD=TITLE :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='TITLE']])
(: The number of TITLE records may not be 0 :)
where $count = 0
return <error rule="FDAC257" dataset="TS" rulelastupdate="2015-02-11">Missing TITLE Trial Summary Parameter in dataset TS</error>
Missing TPHASE Trial Summary Parameter - 'Trial Phase Classification' (TPHASE) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions
TS
(: Rule FDAC258 - Missing TPHASE Trial Summary Parameter:
'Trial Phase Classification' (TPHASE) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of records for which TSPARMCD=TPHASE :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='TPHASE']])
(: The number of TPHASE records may not be 0 :)
where $count = 0
return <error rule="FDAC258" dataset="TS" rulelastupdate="2015-02-11">Missing TPHASE Trial Summary Parameter in dataset TS</error>
Missing TTYPE Trial Summary Parameter - 'Trial Type (TTYPE) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions
TS
(: Rule FDAC259 - Missing TTYPE Trial Summary Parameter:
'Trial Type (TTYPE) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of records for which TSPARMCD=TTYPE :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='TTYPE']])
(: The number of TTYPE records may not be 0 :)
where $count = 0
return <error rule="FDAC259" dataset="TS" rulelastupdate="2015-02-11">Missing TTYPE Trial Summary Parameter in dataset TS</error>
Missing CURTRT Trial Summary Parameter - 'Current Therapy or Treatment' (CURTRT) record must be populated in Trial Summay (TS) domain, when ADDON is 'Y'. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions
TS
(: Rule FDAC260 - Missing CURTRT Trial Summary Parameter:
'Current Therapy or Treatment' (CURTRT) record must be populated in Trial Summay (TS) domain, when ADDON is 'Y'. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of records for which TSPARMCD=CURTRT :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='CURTRT']])
(: The number of CURTRT records may not be 0 :)
where $count = 0
return <error rule="FDAC260" dataset="TS" rulelastupdate="2015-02-11">Missing CURTRT Trial Summary Parameter in dataset {data($tsdatasetname)}</error>
Invalid TSVAL value for CURTRT - TSVAL for CURTRT record must be a valid preferred term from FDA Substance Registration System (SRS)
TS
(: Rule FDAC261 - Invalid TSVAL value for CURTRT:
TSVAL for CURTRT record must be a valid preferred term from FDA Substance Registration System (SRS)
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD and TSVAL variables :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get all the records that have TSPARMCD=CURTRT :)
for $record in doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='CURTRT']]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of the TSVAL variable :)
let $tsvalvalue := $record/odm:ItemData[@ItemOID=$tsvaloid]/@Value
(: invoke the NLM webservice to check whether this is a valid preferred term :)
let $webservice := concat('https://dailymed.nlm.nih.gov/dailymed/services/v2/uniis.xml?active_moeity=',$tsvalvalue)
(: the webservice returns an XML document with the structure /uniis/unii - count the number of unii elements :)
let $webserviceresult := doc($webservice)
let $uniicount := count($webserviceresult/uniis/unii)
(: the preferred term is invalid when the count=0 :)
(: TODO: the web service also gives uniis even when the preferred term is invalid, e.g.:
https://dailymed.nlm.nih.gov/dailymed/services/v2/uniis.xml?active_moeity=nothing
TODO: ask the authors of the webservice
:)
where $uniicount=0
return <error rule="FDAC261" dataset="TS" variable="TSVAL" rulelastupdate="2017-03-23" recordnumber="{data($recnum)}">Invalid TSVAL value={data($tsvalvalue)} for CURTRT in dataset TS</error>
Invalid TSVALCD value for CURTRT - TSVALCD for CURTRT record must be a valid unique ingredient identifier from FDA Substance Registration System (SRS)
TS
(: Rule FDAC262 - Invalid TSVALCD value for CURTRT:
TSVALCD for CURTRT record must be a valid unique ingredient identifier from FDA Substance Registration System (SRS)
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD and TSVALCD variables :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvalcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVALCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get all the records that have TSPARMCD=CURTRT :)
for $record in doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='CURTRT']]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of the TSVALCD variable :)
let $tsvalcdvalue := $record/odm:ItemData[@ItemOID=$tsvalcdoid]/@Value
(: invoke the NLM webservice to check whether this is a valid preferred term :)
let $webservice := concat('https://dailymed.nlm.nih.gov/dailymed/services/v2/uniis.xml?unii_code=',$tsvalcdvalue)
(: the webservice returns an XML document with the structure /uniis/unii - count the number of unii elements :)
let $webserviceresult := doc($webservice)
let $uniicount := count($webserviceresult/uniis/unii/unii_code)
(: the preferred term is invalid when the count=0 :)
where $uniicount=0
return <error rule="FDAC262" dataset="TS" variable="TSVALCD" rulelastupdate="2017-03-22" recordnumber="{data($recnum)}">Invalid TSVALCD value={data($tsvalcdvalue)} for CURTRT</error>
TSVAL/TSVALCD value mismatch for CURTRT - TSVAL and TSVALCD values must be populated from the same name record in FDA Substance Registration System (SRS)
TS
(: Rule FDAC263 - TSVAL/TSVALCD value mismatch for CURTRT:
TSVAL and TSVALCD values must be populated from the same name record in FDA Substance Registration System (SRS)
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD, TSVAL and TSVALCD variables :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvalcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVALCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get all the records that have TSPARMCD=CURTRT :)
for $record in doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='CURTRT']]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of the TSVAL and TSVALCD variable :)
let $tsvalcdvalue := $record/odm:ItemData[@ItemOID=$tsvalcdoid]/@Value
let $tsvalvalue := $record/odm:ItemData[@ItemOID=$tsvaloid]/@Value
(: invoke the NLM webservice to check whether this is a valid preferred term :)
let $webservice := concat('https://dailymed.nlm.nih.gov/dailymed/services/v2/uniis.xml?unii_code=',$tsvalcdvalue)
(: the webservice returns an XML document with the structure /uniis/unii/unii_code and /uniis/unii/active_moiety :)
let $webserviceresult := doc($webservice)
let $activemoiety := $webserviceresult/uniis/unii/active_moiety
(: the value of "active_moiety" must correspond to the value of TSVAL :)
where not($activemoiety=$tsvalvalue)
return <error rule="FDAC263" dataset="TS" variable="TSVALCD" rulelastupdate="2017-03-22" recordnumber="{data($recnum)}">TSVAL/TSVALCD value mismatch for CURTRT, TSVALCD={data($tsvalcdvalue)}, TSVAL={data($tsvalvalue)} - NLM webservice provides active moeity={data($activemoiety)}</error>
Invalid TSVCDREF value for CURTRT - TSVCDREF variable value must be 'UNII', when TSPARMCD='CURTRT'
TS
(: Rule FDAC264 - Invalid TSVCDREF value for CURTRT:
TSVCDREF variable value must be 'UNII', when TSPARMCD='CURTRT'
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: and the OID of the TSVCDREF variable :)
let $tsvcdrefoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVCDREF']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records that have TSPARMCD=CURTRT - essentially there should be only one(?) :)
for $record in doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='CURTRT']]
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the value of TSVCDREF :)
let $tsvcdrefvalue := $record/odm:ItemData[@ItemOID=$tsvcdrefoid]/@Value
(: the value of TSVCDREF MUST be 'UNII' :)
where not($tsvcdrefvalue='UNII')
return <error rule="FDAC264" dataset="TS" variable="TSVCDREF" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Invalid TSVCDREF value={data($tsvcdrefvalue)} for CURTRT in dataset TS. The value must be 'UNII'</error>
Missing OBJPRIM Trial Summary Parameter - 'Trial Primary Objective' (OBJPRIM) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions
TS
(: Rule FDAC265 - Missing OBJPRIM Trial Summary Parameter:
'Trial Primary Objective' (OBJPRIM) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of records for which TSPARMCD=OBJPRIM :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='OBJPRIM']])
(: The number of OBJPRIM records may not be 0 :)
where $count = 0
return <error rule="FDAC265" dataset="TS" rulelastupdate="2015-02-11">Missing OBJPRIM Trial Summary Parameter in dataset {data($tsdatasetname)}</error>
Missing SPONSOR Trial Summary Parameter - 'Clinical Study Sponsor' (SPONSOR) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions
TS
(: Rule FDAC266 - Missing SPONSOR Trial Summary Parameter:
'Clinical Study Sponsor' (SPONSOR) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of records for which TSPARMCD=SPONSOR :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='SPONSOR']])
(: The number of SPONSOR records may not be 0 :)
where $count = 0
return <error rule="FDAC266" dataset="TS" rulelastupdate="2015-02-11">Missing SPONSOR Trial Summary Parameter in dataset {data($tsdatasetname)}</error>
Invalid TSVAL value for COMPTRT - TSVAL for COMPTRT record must be a valid preferred term from FDA Substance Registration System (SRS)
TS
(: Rule FDAC267 - Invalid TSVAL value for COMPTRT:
TSVAL for COMPTRT record must be a valid preferred term from FDA Substance Registration System (SRS)
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD and TSVAL variables :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get all the records that have TSPARMCD=COMPTRT :)
for $record in doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='COMPTRT']]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of the TSVAL variable :)
let $tsvalvalue := $record/odm:ItemData[@ItemOID=$tsvaloid]/@Value
(: invoke the NLM webservice to check whether this is a valid preferred term :)
let $webservice := concat('https://dailymed.nlm.nih.gov/dailymed/services/v2/uniis.xml?active_moeity=',$tsvalvalue)
(: the webservice returns an XML document with the structure /uniis/unii - count the number of unii elements :)
let $webserviceresult := doc($webservice)
let $uniicount := count($webserviceresult/uniis/unii)
(: the preferred term is invalid when the count=0 :)
(: TODO: the web service also gives uniis even when the preferred term is invalid, e.g.:
https://dailymed.nlm.nih.gov/dailymed/services/v2/uniis.xml?active_moeity=nothing
TODO: ask the authors of the webservice
:)
where $uniicount=0
return <error rule="FDAC267" dataset="TS" variable="TSVAL" rulelastupdate="2017-03-23" recordnumber="{data($recnum)}">Invalid TSVAL value={data($tsvalvalue)} for COMPTRT in dataset TS</error>
Invalid TSVALCD value for COMPTRT - TSVALCD for COMPTRT record must be a valid unique ingredient identifier from FDA Substance Registration System (SRS)
TS
(: Rule FDAC268 - Invalid TSVALCD value for COMPTRT:
TSVALCD for COMPTRT record must be a valid unique ingredient identifier from FDA Substance Registration System (SRS)
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD and TSVALCD variables :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvalcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVALCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get all the records that have TSPARMCD=COMPTRT :)
for $record in doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='COMPTRT']]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of the TSVAL variable :)
let $tsvalcdvalues := $record/odm:ItemData[@ItemOID=$tsvalcdoid]/@Value
(: there should be either 0 or 1 TSVALCD values,
we don'T want to call the web service when there is no TSVALCD value:)
for $tsvalcdvalue in $tsvalcdvalues
(: invoke the NLM webservice to check whether this is a valid preferred term :)
let $webservice := concat('https://dailymed.nlm.nih.gov/dailymed/services/v2/uniis.xml?unii_code=',$tsvalcdvalue)
(: the webservice returns an XML document with the structure /uniis/unii - count the number of unii elements :)
let $webserviceresult := doc($webservice)
let $uniicount := count($webserviceresult/uniis/unii)
(: count the number of active moeities for this code - when 0, the code is invalid :)
where $uniicount=0
return <error rule="FDAC268" dataset="TS" variable="TSVALCD" rulelastupdate="2017-03-23" recordnumber="{data($recnum)}">Invalid TSVALCD value={data($tsvalcdvalue)} for COMPTRT in dataset TS</error>
TSVAL/TSVALCD value mismatch for COMPTRT - TSVAL and TSVALCD values must be populated from the same name record in FDA Substance Registration System (SRS)
TS
(: Rule FDAC269 - TSVAL/TSVALCD value mismatch for COMPTRT:
TSVAL and TSVALCD values must be populated from the same name record in FDA Substance Registration System (SRS)
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD, TSVAL and TSVALCD variables :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvalcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVALCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get all the records that have TSPARMCD=COMPTRT :)
for $record in doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='COMPTRT']]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of the TSVAL and TSVALCD variable :)
let $tsvalcdvalue := $record/odm:ItemData[@ItemOID=$tsvalcdoid]/@Value
let $tsvalvalue := $record/odm:ItemData[@ItemOID=$tsvaloid]/@Value
(: invoke the NLM webservice to check whether this is a valid preferred term :)
let $webservice := concat('https://dailymed.nlm.nih.gov/dailymed/services/v2/uniis.xml?unii_code=',$tsvalcdvalue)
(: the webservice returns an XML document with the structure /uniis/unii/unii_code and /uniis/unii/active_moiety :)
let $webserviceresult := doc($webservice)
let $activemoiety := $webserviceresult/uniis/unii/active_moiety
(: the value of "active_moiety" must correspond to the value of TSVAL :)
where not($activemoiety=$tsvalvalue)
return <error rule="FDAC269" dataset="TS" variable="TSVALCD" rulelastupdate="2017-03-23" recordnumber="{data($recnum)}">TSVAL/TSVALCD value mismatch for COMPTRT, TSVALCD={data($tsvalcdvalue)}, TSVAL={data($tsvalvalue)} - NLM webservice provides active moeity={data($activemoiety)}</error>
Invalid TSVCDREF value for COMPTRT - TSVCDREF variable value must be 'UNII', when TSPARMCD='COMPTRT'
TS
(: Rule FDAC270 - Invalid TSVCDREF value for COMPTRT:
TSVCDREF variable value must be 'UNII', when TSPARMCD='COMPTRT'
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: and the OID of the TSVCDREF variable :)
let $tsvcdrefoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVCDREF']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records that have TSPARMCD=COMPTRT :)
for $record in doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='COMPTRT']]
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the value of TSVCDREF :)
let $tsvcdrefvalue := $record/odm:ItemData[@ItemOID=$tsvcdrefoid]/@Value
(: the value of TSVCDREF MUST be 'UNII' :)
where not($tsvcdrefvalue='UNII')
return <error rule="FDAC270" dataset="TS" variable="TSVCDREF" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Invalid TSVCDREF value={data($tsvcdrefvalue)} for COMPTRT. The value must be 'UNII'</error>
Missing INDIC Trial Summary Parameter - 'Trial Indication' (INDIC) record must be populated in Trial Summary (TS) domain, when study type is 'INTERVENTIONAL'. It is required for SDTM IG v3.1.2 data and all more recent SDTM versions
TS
(: Rule FDAC271 - Missing INDIC Trial Summary Parameter
'Trial Indication' (INDIC) record must be populated in Trial Summary (TS) domain, when study type is 'INTERVENTIONAL'. It is required for SDTM IG v3.1.2 data and all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD and TSVAL :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get the record with TSPARMCD=STYPE and TSVAL=INTERVENTIONAL (if any) :)
let $stypeinterventionalrecord := doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='STYPE']][odm:ItemData[@ItemOID=$tsvaloid and @Value='INTERVENTIONAL']]
(: get the record with TSPARMCD=INDIC :)
let $indicrecord := doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='INDIC']]
(: it is not sufficient that there is a record with TSPARMCD=INDIC , TSVAL MUST also be populated :)
let $indicvalue := $indicrecord/odm:ItemData[@ItemOID=$tsvaloid]/@Value
(: when STYPE=INTERVENTIONAL, there MUST be an INDIC record with a TSVAL populated :)
where $stypeinterventionalrecord and (not($indicrecord) or not($indicvalue))
return <error rule="FDAC271" dataset="TS" rulelastupdate="2015-02-11">Missing INDIC Trial Summary Parameter in dataset TS: No populated TSPARMCD=INDIC record was found although a record with TSPARMCD=STYPE and TSVAL=INTERVENTIONAL is present</error>
Invalid TSVALCD value for INDIC - TSVALCD for INDIC record must be a valid concept id from SNOMED CT
TS
(: Rule FDAC273 - Invalid TSVALCD value for INDIC:
TSVALCD for INDIC record must be a valid concept id from SNOMED CT
Remark: uses NLM Web Service: http://rxnav.nlm.nih.gov/SnomedCTAPI.html, e.g. http://rxnav.nlm.nih.gov/REST/SnomedCT/status?id=10532003
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdiscpilot01/' :)
(: let $define := 'define_2_0.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD and TSVALCD variables :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvalcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVALCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get all the records that have TSPARMCD=INDIC :)
for $record in doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='INDIC']]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of the TSVAL variable :)
let $tsvalcdvalues := $record/odm:ItemData[@ItemOID=$tsvalcdoid]/@Value
(: TESTING ONLY let $tsvalcdvalue := '12345678' :)
(: There should be zero or one such value, but we don't want to call the web service when there is none :)
for $tsvalcdvalue in $tsvalcdvalues
(: invoke the NLM webservice to check whether this is a valid preferred term :)
let $webservice := concat('https://rxnav.nlm.nih.gov/REST/SnomedCT/status?id=',$tsvalcdvalue)
(: the webservice returns an XML document with the structure /snomedctStatus/status - the value should be '1' - '-1' means an invalid satus :)
let $webserviceresult := doc($webservice)
let $status := $webserviceresult/snomedctStatus/status
where $status != 1
return <error rule="FDAC273" dataset="TS" variable="TSVALCD" rulelastupdate="2017-03-24" recordnumber="{data($recnum)}">Invalid TSVALCD, value={data($tsvalcdvalue)} for INDIC is not a valid SNOMED-CT code in dataset TS</error>
Invalid TSVCDREF value for INDIC - TSVCDREF variable value must be "SNOMED", when TSPARAMCD='INDIC'
TS
(: Rule FDA275 - Invalid TSVCDREF value for INDIC
TSVCDREF variable value must be "SNOMED", when TSPARAMCD='INDIC'
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: and the OID of the TSVCDREF variable :)
let $tsvcdrefoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVCDREF']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records that have TSPARMCD=INDIC :)
for $record in doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='INDIC']]
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the value of TSVCDREF :)
let $tsvcdrefvalue := $record/odm:ItemData[@ItemOID=$tsvcdrefoid]/@Value
(: the value of TSVCDREF MUST be 'SNOMED' :)
where not($tsvcdrefvalue='SNOMED')
return <error rule="FDAC275" dataset="TS" variable="TSVCDREF" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Invalid TSVCDREF value={data($tsvcdrefvalue)} for INDIC. The value must be 'SNOMED'</error>
Missing REGID Trial Summary Parameter - 'Registry Identifier' (REGID) record may be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and all more recent SDTM versions
TS
(: Rule FDAC276 - Missing REGID Trial Summary Parameter:
'Registry Identifier' (REGID) record may be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/xxx/Study09/' :)
(: let $define := 'define_DS-XML.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD and TSVAL and TSVALNF :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvalnfoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVALNF']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get the record with TSPARMCD=REGID where TSVALNF is not populated :)
let $regidrecord := doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='REGID']]
(: it is not sufficient that there is a record with TSPARMCD=REGID , TSVAL MUST also be populated :)
(: we also retrieve TSVALNF so that the rule can easily be changed for the case that either TSVAL or TSVALNF must be populated :)
let $tsregidvalue := $regidrecord/odm:ItemData[@ItemOID=$tsvaloid]/@Value
let $tsvalnfvalue := $regidrecord/odm:ItemData[@ItemOID=$tsvalnfoid]/@Value
where not($tsvalnfvalue) and (not($regidrecord) or not($tsregidvalue))
return <error rule="FDAC276" dataset="TS" rulelastupdate="2015-02-11">Missing REGID Trial Summary Parameter in dataset TS</error>
Invalid TSVAL value for TRT - TSVAL for TRT record must be a valid preferred term from FDA Substance Registration System (SRS)
TS
(: Rule FDAC277: Invalid TSVALCD value for TRT: TSVALCD for TRT record must be a valid preferred term from FDA Substance Registration System (SRS) :)
(: This query uses the DailyMed NLM web service - see https://dailymed.nlm.nih.gov/dailymed/webservices-help/v2/uniis_api.cfm
e.g.: http://dailymed.nlm.nih.gov/dailymed/services/v2/uniis.xml?active_moiety=NAFARELIN :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdiscpilot01/' :)
(: let $define := 'define_2_0.xml' :)
(: Get the TS dataset :)
let $tsitemgroupdef := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsitemgroupdef/def:leaf/@xlink:href
let $tsdataset := doc(concat($base,$tsdatasetname))
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get the OID of the TSVAL variable :)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: now get the records TSPARMCD=TRT, but only when there also IS a TSVALCD variable value present :)
for $record in $tsdataset//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='TRT'] and odm:ItemData[@ItemOID=$tsvaloid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the ItemData point for TSVAL :)
(: REMARK that we are forgiving regarding case-sensitiveness :)
let $tsval := upper-case($record/odm:ItemData[@ItemOID=$tsvaloid]/@Value)
(: return <test>{data($tsval)}</test> :)
(: now invoke the web service to check whether it is a valid UNII, e.g.:
https://dailymed.nlm.nih.gov/dailymed/services/v2/uniis.xml?active_moiety=NAFARELIN
:)
(: ONLY FOR TESTING :)
(: let $tsval := 'NAFARELINx' :)
let $webservice := concat('https://dailymed.nlm.nih.gov/dailymed/services/v2/uniis.xml?active_moiety=',$tsval)
let $webserviceresult := doc($webservice)
(: this is a document with the structure /uniis/unii/unii_code - it is an invalid code when there is no such an unii element :)
let $count := count($webserviceresult/uniis/unii/unii_code)
where $count = 0
return <error rule="FDAC277" dataset="TS" variable="TSVAL" rulelastupdate="2017-03-23" recordnumber="{data($recnum)}">Invalid TSVAL value for TRT in dataset {data($tsdatasetname)}: TSVAL for TRT record must be a valid preferred term from FDA Substance Registration System (SRS): value '{data($tsval)}' is not a valid preferred term identifier from SRS</error>
Invalid TSVALCD value for TRT - TSVALCD for TRT record must be a valid unique ingredient identifier from FDA Substance Registration System (SRS)
TS
(: Rule FDAC278: Invalid TSVALCD value for TRT: TSVALCD for TRT record must be a valid unique ingredient identifier from FDA Substance Registration System (SRS) :)
(: This query uses the DailyMed NLM web service - see https://dailymed.nlm.nih.gov/dailymed/webservices-help/v2/uniis_api.cfm
e.g.: https://dailymed.nlm.nih.gov/dailymed/services/v2/uniis.xml?unii_code=1X0094V6JV :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdiscpilot01/' :)
(: let $define := 'define_2_0.xml' :)
(: Get the TS dataset :)
let $tsitemgroupdef := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsitemgroupdef/def:leaf/@xlink:href
let $tsdataset := doc(concat($base,$tsdatasetname))
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get the OID of the TSVALCD variable :)
let $tsvalcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVALCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: now get the records TSPARMCD=TRT, but only when there also IS a TSVALCD variable value present :)
for $record in $tsdataset//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='TRT'] and odm:ItemData[@ItemOID=$tsvalcdoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the ItemData point for TSVAL :)
let $tsval := $record/odm:ItemData[@ItemOID=$tsvalcdoid]/@Value
(: return <test>{data($tsval)}</test> :)
(: now invoke the web service to check whether it is a valid UNII, e.g.:
https://dailymed.nlm.nih.gov/dailymed/services/v2/uniis.xml?unii_code=1X0094V6JV
:)
(: ONLY FOR TESTING let $tsval := '1X0094V6JVx' :)
let $webservice := concat('https://dailymed.nlm.nih.gov/dailymed/services/v2/uniis.xml?unii_code=',$tsval)
let $webserviceresult := doc($webservice)
(: this is a document with the structure /uniis/unii/unii_code - it is an invalid code when there is no such an unii element :)
let $count := count($webserviceresult/uniis/unii/unii_code)
where $count = 0
return <error rule="FDAC278" dataset="TS" variable="TSVALCD" rulelastupdate="2017-03-23" recordnumber="{data($recnum)}">Invalid TSVALCD value for TRT in dataset {data($tsdatasetname)}: TSVALCD for TRT record must be a valid unique ingredient identifier from FDA Substance Registration System (SRS): value '{data($tsval)}' is not a valid unique ingredient identifier from SRS</error>
TSVAL/TSVALCD value mismatch for TRT - TSVAL and TSVALCD values must be populated from the same name record in FDA Substance Registration System (SRS)
TS
(: Rule FDAC279: TSVAL/TSVALCD value mismatch for TRT: TSVAL and TSVALCD values must be populated from the same name record in FDA Substance Registration System (SRS) :)
(: This query uses the DailyMed NLM web service - see https://dailymed.nlm.nih.gov/dailymed/webservices-help/v2/uniis_api.cfm
e.g.: https://dailymed.nlm.nih.gov/dailymed/services/v2/uniis.xml?unii_code=1X0094V6JV :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdiscpilot01/' :)
(: let $define := 'define_2_0.xml' :)
(: Get the TS dataset :)
let $tsitemgroupdef := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsitemgroupdef/def:leaf/@xlink:href
let $tsdataset := doc(concat($base,$tsdatasetname))
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get the OID of the TSVALCD variable :)
let $tsvalcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVALCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get the OID of the TSVAL variable :)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: now get the records TSPARMCD=TRT, but only when there also IS a TSVALCD AND a TSVAL variable value present :)
for $record in $tsdataset//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='TRT'] and odm:ItemData[@ItemOID=$tsvaloid] and odm:ItemData[@ItemOID=$tsvalcdoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the ItemData point for TSVAL :)
let $tsvalcd := $record/odm:ItemData[@ItemOID=$tsvalcdoid]/@Value
let $tsval := $record/odm:ItemData[@ItemOID=$tsvaloid]/@Value
(: return <test>{data($tsval)}</test> :)
(: now invoke the web service to check whether it is a valid UNII, e.g.:
https://dailymed.nlm.nih.gov/dailymed/services/v2/uniis.xml?unii_code=1X0094V6JV
:)
(: ONLY FOR TESTING :)
(: let $tsvalcd := '1X0094V6JV'
let $tsval := 'NAFARELINx' :)
(: call the web service :)
let $webservice := concat('https://dailymed.nlm.nih.gov/dailymed/services/v2/uniis.xml?unii_code=',$tsvalcd)
let $webserviceresult := doc($webservice)
(: this is a document with the structure /uniis/unii/unii_code and /uniis/unii/active_moiety - it these must match TSVALCD and TSVAL :)
let $srscode := $webserviceresult/uniis/unii/unii_code
let $srsname := $webserviceresult/uniis/unii/active_moiety
where not($tsvalcd = $srscode and $tsval = $srsname)
return <error rule="FDAC279" dataset="TS" variable="TSVALCD" rulelastupdate="2017-03-23" recordnumber="{data($recnum)}">TSVAL/TSVALCD value mismatch for TRT in dataset {data($tsdatasetname)}: TSVAL and TSVALCD values must be populated from the same name record in FDA Substance Registration System (SRS): values '{data($tsvalcd)}' and '{data($tsval)}' do not belong to the same SRS record</error>
Invalid TSVCDREF value for TRT - TSVCDREF variable value must be 'UNII', when TSPARMCD='TRT'
TS
(: Rule FDAC280: Invalid TSVCDREF value for TRT: TSVCDREF variable value must be 'UNII', when TSPARMCD='TRT' :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdiscpilot01/' :)
(: let $define := 'define_2_0.xml' :)
(: Get the TS dataset :)
let $tsitemgroupdef := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsitemgroupdef/def:leaf/@xlink:href
let $tsdataset := doc(concat($base,$tsdatasetname))
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get the OID of the TSVCDREF variable :)
let $tsvcdrefoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVCDREF']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: Now iterate over all records in the TS dataset for which TSPARMCD='TRT' :)
for $record in $tsdataset//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='TRT']]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of TSVCDREF :)
let $tsvcdref := $record/odm:ItemData[@ItemOID=$tsvcdrefoid]/@Value
(: The value must be UNII :)
where not($tsvcdref='UNII')
(: TODO: what if TSVCDREF is absent? This currently also gives an error :)
return <error rule="FDAC280" dataset="TS" variable="TSVCDREF" rulelastupdate="2015-08-28" recordnumber="{data($recnum)}">Invalid TSVCDREF value for TRT: TSVCDREF variable value must be 'UNII', when TSPARMCD='TRT', value found is '{data($tsvcdref)}'</error>
Missing REGID Trial Summary Parameter - Registry Identifier (REGID) record may be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and all more recent SDTM versions.
TS
(: Rule FDAC281: Missing REGID Trial Summary Parameter: Registry Identifier (REGID) record may be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and all more recent SDTM versions. :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdiscpilot01/' :)
(: let $define := 'define_2_0.xml' :)
(: Get the TS dataset :)
let $tsitemgroupdef := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsitemgroupdef/def:leaf/@xlink:href
let $tsdataset := doc(concat($base,$tsdatasetname))
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get the OID of the TSVAL variable :)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count all the records that have TSPARMCD=REGID and have a value for TSVAL,
there should be at least 1 :)
let $count := count($tsdataset//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='REGID'] and odm:ItemData[@ItemOID=$tsvaloid and @Value!='']])
where $count < 1
return <warning rule="FDAC281" dataset="TS" rulelastupdate="2015-08-28">Missing REGID Trial Summary Parameter: Registry Identifier (REGID) record may be populated in Trial Summay (TS) domain</warning>
Missing OUTMSPRI Trial Summary Parameter - 'Primary Outcome Measure' (OUTMSPRI) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions
TS
(: Rule FDAC282 - Missing OUTMSPRI Trial Summary Parameter:
'Primary Outcome Measure' (OUTMSPRI) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD and TSVAL :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get the record with TSPARMCD=OUTMSPRI :)
let $outmsprirecord := doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='OUTMSPRI']]
(: it is not sufficient that there is a record with TSPARMCD=OUTMSPRI , TSVAL MUST also be populated :)
let $outmsprivalue := $outmsprirecord/odm:ItemData[@ItemOID=$tsvaloid]/@Value
where not($outmsprivalue) or not($outmsprivalue)
return <error rule="FDAC282" dataset="TS" rulelastupdate="2015-02-11">Missing OUTMSPRI Trial Summary Parameter</error>
Missing PCLAS Trial Summary Parameter - Pharmacological Class of Investigational Therapy' (PCLAS) record must be populated in Trial Summay (TS) domain, when study type is 'INTERVENTIONAL' and if Intervention Type (INTTYPE) is one for which pharmacological class is applicable. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
TS
(: TODO: this is incomplete, it is unclear what exactly
"if Intervention Type (INTTYPE) is one for which pharmacological class is applicable" means :)
(: Rule FDAC283 - Missing PCLAS Trial Summary Parameter:
'Pharmacological Class of Investigational Therapy' (PCLAS) record must be populated in Trial Summay (TS) domain, when study type is 'INTERVENTIONAL' and if Intervention Type (INTTYPE) is one for which pharmacological class is applicable. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD and TSVAL :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get the record with TSPARMCD=STYPE :)
let $styperecord := doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='STYPE']]
(: and the value for TSVAL of the record with TSPARMCD=STYPE :)
let $stypevalue := $styperecord/odm:ItemData[@ItemOID=$tsvaloid]/@Value
(: get the record for which TSPARMCD=PCLASS :)
let $pclassrecord := doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='PCLASS']]
(: and the value :)
let $pclassvalue := $pclassrecord/odm:ItemData[@ItemOID=$tsvaloid]/@Value
(: when STYPE=INTERVENTIONAL, there MUST be a TSVAL for TSPARMCD=PCLASS :)
(: TODO: this is incomplete, it is unclear what exactly
"if Intervention Type (INTTYPE) is one for which pharmacological class is applicable" means :)
where $stypevalue='INTERVENTIONAL' and (not($pclassrecord) or not($pclassvalue))
return <error rule="FDAC283" dataset="TS" rulelastupdate="2015-02-11">Missing PCLAS Trial Summary Parameter, although there is a record with TSPARMCD=STYPE and TSVAL=INTERVENTIONAL</error>
Invalid TSVAL value for PCLAS - TSVAL for PCLAS record must be a valid term from NDF-RT
TS
(: Rule FDAC284 - Invalid TSVAL value for PCLAS - TSVAL for PCLAS record must be a valid term from NDF-RT :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdiscpilot01/' :)
(: let $define := 'define_2_0.xml' :)
let $definedoc := doc(concat($base,$define))
(: Get the TS dataset :)
let $tsitemgroupdef := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsitemgroupdef/def:leaf/@xlink:href
let $tsdataset := doc(concat($base,$tsdatasetname))
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in $definedoc//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = $definedoc//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get the OID of the TSVAL variable :)
let $tsvaloid := (
for $a in $definedoc//odm:ItemDef[@Name='TSVAL']/@OID
where $a = $definedoc//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: now get the records TSPARMCD=PCLAS, but only when there also IS a TSVAL variable value present :)
for $record in $tsdataset//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='PCLAS']][odm:ItemData[@ItemOID=$tsvaloid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the ItemData point for TSVAL :)
let $tsval := $record/odm:ItemData[@ItemOID=$tsvaloid]/@Value
(: now invoke the web service to check whether it is a valid NDF-RT, e.g.:
https://rxnav.nlm.nih.gov/REST/Ndfrt/search?conceptName=Anti-epileptic%20Agent
:)
(: ONLY FOR TESTING: let $tsval := 'Anti-epileptic Agenxt' :)
let $webservice := concat('https://rxnav.nlm.nih.gov/REST/Ndfrt/search?conceptName=',$tsval)
let $webserviceresult := doc($webservice)
(: this is a document with the structure /ndfrtdata/groupConcepts/concept/conceptName - it is an invalid code when there is no such an conceptName element :)
let $count := count($webserviceresult/ndfrtdata/groupConcepts/concept[conceptName=$tsval])
where $count = 0
return <error rule="FDAC284" dataset="TS" variable="TSVALCD" rulelastupdate="2017-03-24" recordnumber="{data($recnum)}">Invalid TSVAL value for PCLASS in dataset {data($tsdatasetname)}: TSVAL for TSPARMCD=PCLAS record must be a valid a valid term from NDF-RT: value '{data($tsval)}' was found</error>
Invalid TSVALCD value for PCLAS - TSVALCD for PCLAS record must be a valid code from NDF-RT
TS
(: Rule FDAC285 - Invalid TSVALCD value for PCLAS:
TSVALCD for PCLAS record must be a valid code from NDF-RT
:)
(: uses NLM webservice - see http://rxnav.nlm.nih.gov/NdfrtAPIREST.html
E.g. http://rxnav.nlm.nih.gov/REST/Ndfrt/parentConcepts.xml?nui=N0000153235 :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD and TSVALCD :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvalcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVALCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get the records with TSPARMCD=PCLAS :)
for $pclassrecord in doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='PCLAS']]
let $recnum := $pclassrecord/@data:ItemGroupDataSeq
(: and get the value of TSVALCD :)
let $tsvalcdvalues := $pclassrecord/odm:ItemData[@ItemOID=$tsvalcdoid]/@Value
(: just for testing: let $tsvalcdvalue := 'N0000175565' :)
(: There should be 0 or 1 TSVALCD values, but we don't want to call the web service when there is none :)
for $tsvalcdvalue in $tsvalcdvalues
(: check it using the NLM webservice :)
let $webserviceresult := doc(concat('http://rxnav.nlm.nih.gov/REST/Ndfrt/parentConcepts.xml?nui=',$tsvalcdvalue))
(: This rerturns an XML document with the structure /ndfrtdata/groupConcepts/concept
with child elements conceptName, conceptNui, conceptKind
If the code is invalid, no "concept" element will be present :)
where not($webserviceresult/ndfrtdata/groupConcepts/concept)
return <error rule="FDAC285" dataset="TS" variable="TSVALCD" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Invalid TSVALCD value={data($tsvalcdvalue)} for PCLAS</error>
TSVAL/TSVALCD value mismatch for PCLAS - TSVAL and TSVALCD values must be populated from the same record in NDF-RT
TS
(: Rule FDAC286 - TSVAL/TSVALCD value mismatch for PCLAS:
TSVAL and TSVALCD values must be populated from the same record in NDF-RT
:)
(: uses NLM web service - see http://rxnav.nlm.nih.gov/NdfrtAPIREST.html
e.g. http://rxnav.nlm.nih.gov/REST/Ndfrt/allInfo.xml?nui=N0000175565
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD, TSVAL and TSVALCD variables :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvalcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVALCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get the records with TSPARMCD=PCLAS :)
for $pclassrecord in doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='PCLAS']]
let $recnum := $pclassrecord/@data:ItemGroupDataSeq
(: and get the value of TSVAL and TSVALCD :)
let $tsvalvalue := $pclassrecord/odm:ItemData[@ItemOID=$tsvaloid]/@Value
let $tsvalcdvalue := $pclassrecord/odm:ItemData[@ItemOID=$tsvalcdoid]/@Value
(: just for testing: let $tsvalcdvalue := 'N0000175565' :)
(: exclude the case that the value of TSVALCD is not a valid NDF-RT value :)
(: check it using the NLM webservice :)
let $webserviceresult := doc(concat('http://rxnav.nlm.nih.gov/REST/Ndfrt/allInfo.xml?nui=',$tsvalcdvalue))
(: This returns an XML document with the structure /ndfrtdata/fullConcept/conceptName
The latter text content must match the value of TSVAL :)
let $conceptName := $webserviceresult/ndfrtdata/fullConcept/conceptName
(: where not($tsvalvalue = $conceptName ) :)
return <error rule="FDAC286" variable="TSVAL" dataset="TS" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Invalid TSVAL value='{data($tsvalvalue)}' for PCLAS with TSVALCD={data($tsvalcdvalue)} - value from NLM web service found='{data($conceptName)}'</error>
Invalid TSVCDREF value for PCLAS - TSVCDREF variable value must be 'NDF-RT', when TSPARMCD='PCLAS'
TS
(: Rule FDAC287 - Invalid TSVCDREF value for PCLAS:
TSVCDREF variable value must be 'NDF-RT', when TSPARMCD='PCLAS'
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: and the OID of the TSVCDREF variable :)
let $tsvcdrefoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVCDREF']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records that have TSPARMCD=PCLAS :)
for $record in doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='PCLAS']]
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the value of TSVCDREF :)
let $tsvcdrefvalue := $record/odm:ItemData[@ItemOID=$tsvcdrefoid]/@Value
(: the value of TSVCDREF MUST be 'NDF-RT' :)
where not($tsvcdrefvalue='NDF-RT')
return <error rule="FDAC287" dataset="TS" variable="TSVCDREF" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Invalid TSVCDREF value={data($tsvcdrefvalue)} for PCLAS. The value must be 'NDF-RT'</error>
Missing FCNTRY Trial Summary Parameter - 'Planned Country of Investigational Sites' (FCNTRY) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions
TS
(: Rule FDAC288 - Missing FCNTRY Trial Summary Parameter
'Planned Country of Investigational Sites' (FCNTRY) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of records for which TSPARMCD=FCNTRY :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='FCNTRY']])
(: The number of FCNTRY records may not be 0 :)
where $count = 0
return <error rule="FDAC288" dataset="TS" rulelastupdate="2015-02-11">Missing FCNTRY Trial Summary Parameter in dataset {data($tsdatasetname)}</error>
Invalid TSVCDREF value for FCNTRY - TSVCDREF variable value must be "ISO 3166", when TSPARMCD='FCNTRY'
TS
(: Rule FDAC289 - Invalid TSVCDREF value for FCNTRY
TSVCDREF variable value must be "ISO 3166", when TSPARMCD='FCNTRY'
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: and the OID of the TSVCDREF variable :)
let $tsvcdrefoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVCDREF']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: iterate over all records that have TSPARMCD=FCNTRY :)
for $record in doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='FCNTRY']]
let $recnum := $record/@data:ItemGroupDataSeq
(: and get the value of TSVCDREF :)
let $tsvcdrefvalue := $record/odm:ItemData[@ItemOID=$tsvcdrefoid]/@Value
(: the value of TSVCDREF MUST be 'ISO 3166' :)
where not($tsvcdrefvalue='ISO 3166')
return <error rule="FDAC289" dataset="TS" variable="TSVCDREF" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Invalid TSVCDREF value={data($tsvcdrefvalue)} for FCNTRY. The value must be 'ISO 3166'</error>
Missing ADAPT Trial Summary Parameter - 'Adaptive Design' (ADAPT) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions
TS
(: Rule FDAC290 - Missing ADAPT Trial Summary Parameter:
'Adaptive Design' (ADAPT) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of records for which TSPARMCD=ADAPT :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='ADAPT']])
(: The number of ADAPT records may not be 0 :)
where $count = 0
return <error rule="FDAC290" dataset="TS" rulelastupdate="2015-02-11">Missing ADAPT Trial Summary Parameter in dataset {data($tsdatasetname)}</error>
Missing DCUTDTC Trial Summary Parameter - 'Data Cutoff Date' (DCUTDTC) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions
TS
(: Rule FDAC291 - Missing DCUTDTC Trial Summary Parameter:
'Data Cutoff Date' (DCUTDTC) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD variable :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of records for which TSPARMCD=DCUTDTC :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='DCUTDTC']])
(: The number of DCUTDTC records may not be 0 :)
where $count = 0
return <error rule="FDAC291" dataset="TS" rulelastupdate="2015-02-11">Missing DCUTDTC Trial Summary Parameter in dataset {data($tsdatasetname)}</error>
Invalid TSVAL value for DCUTDTC - TSVAL variable value must be in ISO 8601 format, when TSPARMCD='DCUTDTC'
TS
(: TODO: test on real dataset :)
(: Rule FDAC292 - Invalid TSVAL value for DCUTDTC:
TSVAL variable value must be in ISO 8601 format, when TSPARMCD='DCUTDTC'
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD and TSVAL variables :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get the records with TSPARMCD=DCUTDTC :)
for $dcutdtcrecord in doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='DCUTDTC']]
let $recnum := $dcutdtcrecord/@data:ItemGroupDataSeq
(: get the value of TSVAL :)
let $tsvalvalue := $dcutdtcrecord/odm:ItemData[@ItemOID=$tsvaloid]/@Value
(: the TSVAL value must be a valid date :)
where not($tsvalvalue castable as xs:date)
return <error rule="FDAC292" dataset="TS" variable="TSVAL" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Invalid TSVAL value for DCUTDTC: value={data($tsvalvalue)} is not a valid ISO-8601 date</error>
Missing DCUTDESC Trial Summary Parameter - 'Data Cutoff Description' (DCUTDESC) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions
TS
(: Rule FDAC293 - Missing DCUTDESC Trial Summary Parameter:
'Data Cutoff Description' (DCUTDESC) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD and TSVAL :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of the records with TSPARMCD=DCUTDESC :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='DCUTDESC']])
(: the number of DCUTDESC records may not be 0 :)
where $count=0
return <error rule="FDAC293" dataset="TS" rulelastupdate="2015-02-11">Missing DCUTDESC Trial Summary Parameter in dataset {data($tsdatasetname)}</error>
Missing INTMODEL Trial Summary Parameter - 'Intervention Model' (INTMODEL) record must be populated in Trial Summay (TS) domain, when study type is 'INTERVENTIONAL'. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions
TS
(: TODO: testing :)
(: Rule FDAC294 - Missing INTMODEL Trial Summary Parameter:
'Intervention Model' (INTMODEL) record must be populated in Trial Summay (TS) domain, when study type is 'INTERVENTIONAL'. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD and TSVAL :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get the record with TSPARMCD=STYPE and TSVAL=INTERVENTIONAL (if any) :)
let $stypeinterventionalrecord := doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='STYPE']][odm:ItemData[@ItemOID=$tsvaloid and @Value='INTERVENTIONAL']]
(: get the record with TSPARMCD=INTMODEL :)
let $intmodelrecord := doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='INTMODEL']]
(: it is not sufficient that there is a record with TSPARMCD=INTMODEL , TSVAL MUST also be populated :)
let $intmodelvalue := $intmodelrecord/odm:ItemData[@ItemOID=$tsvaloid]/@Value
(: when STYPE=INTERVENTIONAL, there MUST be an INDIC record with a TSVAL populated :)
where $stypeinterventionalrecord and (not($intmodelrecord) or not($intmodelvalue))
return <error rule="FDAC294" dataset="TS" rulelastupdate="2015-02-11">Missing INTMODEL Trial Summary Parameter: No populated TSPARMCD=INTMODEL record was found although a record with TSPARMCD=STYPE and TSVAL=INTERVENTIONAL is present</error>
Missing NARMS Trial Summary Parameter - 'Planned Number of Arms' (NARMS) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions
TS
(: Rule FDAC295 - Missing NARMS Trial Summary Parameter:
'Planned Number of Arms' (NARMS) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD and TSVAL :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of the records with TSPARMCD=NARMS :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='NARMS']])
(: the number of NARMS records may not be 0 :)
where $count=0
return <error rule="FDAC295" dataset="TS" rulelastupdate="2015-02-11">Missing NARMS Trial Summary Parameter in dataset {data($tsdatasetname)}</error>
Invalid TSVAL value for NARMS - TSVAL variable value must be numeric, when TSPARMCD='NARMS'
TS
(: Rule FDAC296 - Invalid TSVAL value for NARMS:
TSVAL variable value must be numeric, when TSPARMCD='NARMS'
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD and TSVAL :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get the records with TSPARMCD=NARMS (if any) :)
for $narmsrecord in doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='NARMS']]
let $recnum := $narmsrecord/@data:ItemGroupDataSeq
(: get the value of TSVAL :)
let $tsvalvalue := $narmsrecord/odm:ItemData[@ItemOID=$tsvaloid]/@Value
(: it must be numeric - we however translate this as that it must be a non-negative integer :)
where not($tsvalvalue castable as xs:integer) or not(number($tsvalvalue) > -1)
return <error rule="FDAC296" dataset="TS" variable="TSVAL" rulelastupdate="2017-03-24" recordnumber="{data($recnum)}">Invalid TSVAL value for NARMS. A non-negative integer is expected, value found={data($tsvalvalue)}</error>
Multiple NARMS records - Trial Summary (TS) domain must contain only one record for 'NARMS' Parameter
TS
(: Rule FDAC297 - Multiple NARMS records:
Trial Summary (TS) domain must contain only one record for 'NARMS' Parameter
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD and TSVAL :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of the records with TSPARMCD=NARMS :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='NARMS']])
(: the number of NARMS records may not be more than 1 :)
where $count > 1
return <error rule="FDAC297" dataset="TS" rulelastupdate="2015-02-11">Multiple NARMS records in dataset {data($tsdatasetname)}, number of NARMS records found={data($count)}</error>
Missing STYPE Trial Summary Parameter - 'Study Type' (STYPE) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions
TS
(: Rule FDAC298 - Missing STYPE Trial Summary Parameter:
'Study Type' (STYPE) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD and TSVAL :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of the records with TSPARMCD=STYPE :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='STYPE']])
(: the number of STYPE records may not be 0 :)
where $count=0
return <error rule="FDAC298" dataset="TS" rulelastupdate="2015-02-11">Missing STYPE Trial Summary Parameter in dataset {data($tsdatasetname)}</error>
Missing INTTYPE Trial Summary Parameter - 'Intervention Type' (INTTYPE) record must be populated in Trial Summay (TS) domain, when study type is 'INTERVENTIONAL'. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
TS
(: Rule FDAC299 - Missing INTTYPE Trial Summary Parameter:
'Intervention Type' (INTTYPE) record must be populated in Trial Summay (TS) domain, when study type is 'INTERVENTIONAL'. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD and TSVAL :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get the record with TSPARMCD=STYPE and TSVAL=INTERVENTIONAL (if any) :)
let $stypeinterventionalrecord := doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='STYPE']][odm:ItemData[@ItemOID=$tsvaloid and @Value='INTERVENTIONAL']]
(: get the record with TSPARMCD=INTTYPE :)
let $inttyperecord := doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='INTTYPE']]
(: it is not sufficient that there is a record with TSPARMCD=INTTYPE , TSVAL MUST also be populated :)
let $inttypevalue := $inttyperecord/odm:ItemData[@ItemOID=$tsvaloid]/@Value
(: when STYPE=INTERVENTIONAL, there MUST be an INTTYPE record with a TSVAL populated :)
where $stypeinterventionalrecord and (not($inttyperecord) or not($inttypevalue))
return <error rule="FDAC294" dataset="TS" rulelastupdate="2015-02-11">Missing INTTYPE Trial Summary Parameter: No populated TSPARMCD=INTTYPE record was found although a record with TSPARMCD=STYPE and TSVAL=INTERVENTIONAL is present</error>
Missing SSTDTC Trial Summary Parameter - 'Study Start Date' (SSTDTC) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
TS
(: Rule FDAC300 - Missing SSTDTC Trial Summary Parameter:
'Study Start Date' (SSTDTC) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD and TSVAL :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of the records with TSPARMCD=SSTDTC :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='SSTDTC']])
(: the number of SSTDTC records may not be 0 :)
where $count=0
return <error rule="FDAC300" dataset="TS" rulelastupdate="2015-02-11">Missing SSTDTC Trial Summary Parameter in dataset {data($tsdatasetname)}</error>
Invalid TSVAL value for SSTDTC - TSVAL variable value must be in ISO 8601 format, when TSPARMCD='SSTDTC'
TS
(: Rule FDAC301 - Invalid TSVAL value for SSTDTC:
TSVAL variable value must be in ISO 8601 format, when TSPARMCD='SSTDTC' :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD and TSVAL :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get the record with TSPARMCD=SSTDTC and get the value :)
let $sstdtcrecord := doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='SSTDTC']]
let $recnum := $sstdtcrecord/@data:ItemGroupDataSeq
(: and get the value for TSVAL :)
let $ssdtcval := $sstdtcrecord/odm:ItemData[@ItemOID=$tsvaloid]/@Value
(: and get whether it is an ISO-8601 date :)
where $sstdtcrecord and not($ssdtcval castable as xs:date)
(: if it is present but not an ISO-8601 date, report an error :)
return <error rule="FDAC301" dataset="TS" variable="TSVAL" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Invalid TSVAL value {data($ssdtcval)} for Trial Summary Parameter SSTDTC Trial Summary Parameter TS</error>
Missing SENDTC Trial Summary Parameter - 'Study End Date' (SENDTC) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
TS
(: Rule FDAC302 - Missing SENDTC Trial Summary Parameter:
'Study End Date' (SENDTC) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD and TSVAL :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of the records with TSPARMCD=SENDTC :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='SENDTC']])
(: the number of SSTDTC records may not be 0 :)
where $count=0
return <error rule="FDAC302" dataset="TS" rulelastupdate="2015-02-11">Missing SENDTC Trial Summary Parameter in dataset TS</error>
Invalid TSVAL value for SENDTC - TSVAL variable value must be in ISO 8601 format, when TSPARMCD='SETDTC'
TS
(: Rule FDAC303 - Invalid TSVAL value for SENDTC:
TSVAL variable value must be in ISO 8601 format, when TSPARMCD='SETDTC' :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD and TSVAL :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get the record with TSPARMCD=SETDTC and get the value :)
let $setdtcrecord := doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='SETDTC']]
let $recnum := $setdtcrecord/@data:ItemGroupDataSeq
(: and get the value for TSVAL :)
let $sedtcval := $setdtcrecord/odm:ItemData[@ItemOID=$tsvaloid]/@Value
(: and get whether it is an ISO-8601 date :)
where $setdtcrecord and not($sedtcval castable as xs:date)
(: if it is present but not an ISO-8601 date, report an error :)
return <error rule="FDAC303" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">Invalid TSVAL value {data($sedtcval)} for Trial Summary Parameter SETDTC in dataset TS</error>
Missing ACTSUB Trial Summary Parameter - 'Actual Number of Subjects' (ACTSUB) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
TS
(: Rule FDAC304 - Missing ACTSUB Trial Summary Parameter:
'Actual Number of Subjects' (ACTSUB) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD and TSVAL :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of the records with TSPARMCD=ACTSUB :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='ACTSUB']])
(: the number of ACTSUB records may not be 0 :)
where $count=0
return <error rule="FDAC304" dataset="TS" rulelastupdate="2015-02-11">Missing ACTSUB Trial Summary Parameter in dataset TS</error>
Invalid TSVAL value for ACTSUB - TSVAL variable value must be numeric, when TSPARMCD='ACTSUB'
TS
(: Rule FDAC305 - Invalid TSVAL value for ACTSUB:
TSVAL variable value must be numeric, when TSPARMCD='ACTSUB' :)
(: we suppose there cannot be 'fractional' subjects, so we implement as 'integer' :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD and TSVAL :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: get the record with TSPARMCD=ACTSUB and get the value :)
let $actsubrecord := doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='ACTSUB']]
let $recnum := $actsubrecord/@data:ItemGroupDataSeq
(: and get the value for TSVAL :)
let $actsubval := $actsubrecord/odm:ItemData[@ItemOID=$tsvaloid]/@Value
(: and get whether it is an integer - we do NOT allow fractions of subjects :)
where $actsubrecord and not($actsubval castable as xs:integer)
return <error rule="FDAC305" dataset="TS" variable="TSVAL" rulelastupdate="2017-03-24" recordnumber="{data($recnum)}">Invalid TSVAL value {data($actsubval)} for Trial Summary Parameter ACTSUB in dataset {data($tsdatasetname)}</error>
Missing HLTSUBJI Trial Summary Parameter - 'Healthy Subject Indicator' (HLTSUBJI) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
TS
(: Rule FDAC306 - Missing HLTSUBJI Trial Summary Parameter:
'Healthy Subject Indicator' (HLTSUBJI) record must be populated in Trial Summay (TS) domain. It is expected for SDTM IG v3.1.2 data and required for data in all more recent SDTM versions.
:)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: get the TS dataset :)
let $tsdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']
let $tsdatasetname := $tsdataset/def:leaf/@xlink:href
let $tsdatasetlocation := concat($base,$tsdatasetname)
(: get the OID of the TSPARMCD and TSVAL :)
let $tsparmcdoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSPARMCD']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
let $tsvaloid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='TSVAL']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='TS']/odm:ItemRef/@ItemOID
return $a
)
(: count the number of the records with TSPARMCD=HLTSUBJI :)
let $count := count(doc($tsdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$tsparmcdoid and @Value='HLTSUBJI']])
(: the number of HLTSUBJI records may not be 0 :)
where $count=0
return <error rule="FDAC306" dataset="TS" rulelastupdate="2015-02-11">Missing HLTSUBJI Trial Summary Parameter in dataset TS</error>
<Domain>TEST and <Domain>TESTCD values do not have the same NCI Code in CDISC CT - In <Domain Description> (<Domain Name>) domain values for <Variable Label "Short Name"> (--TESTCD) and <Variable Label "Test Name"> (--TEST) variables must be populated using terms with the same Codelist Code value in CDISC control terminology. There is one-to-one relationship between --TESTCD and --TEST values defined in CDISC control terminology by Codelist NCI Code value
ALL
(: Rule FDAC342 - <Domain>TEST and <Domain>TESTCD values do not have the same Code in CDISC CT:
In <Domain Description> (<Domain Name>) domain values for <Variable Label "Short Name"> (--TESTCD) and <Variable Label "Test Name"> (--TEST) variables must be populated using terms with the same Codelist Code value in CDISC control terminology. There is one-to-one relationship between --TESTCD and --TEST values defined in CDISC control terminology by Codelist Code value.
:)
(: This rule can only be implemented for CDISC define.xml 2.0 - it requires the presence of Alias[@Context='nci:ExtCodeID'] :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
(: "declare variable ... external" allows to pass $base and $define from an external programm :)
declare variable $base external;
declare variable $define external;
(: the define.xml file :)
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: iterate over all datasets for which there is as well a --TESTCD as a --TEST variable :)
for $datasetdef in doc(concat($base,$define))//odm:ItemGroupDef
let $datasetname := $datasetdef/@Name
(: get the OID and Name of --TESTCD and of --TEST (if any) :)
let $testcdoid := (
for $a in $datasetdef/../odm:ItemDef[ends-with(@Name,'TESTCD')]/@OID
where $a = $datasetdef/odm:ItemRef/@ItemOID
return $a
)
let $testcdname := $datasetdef/../odm:ItemDef[@OID=$testcdoid]/@Name
let $testoid := (
for $a in $datasetdef/../odm:ItemDef[ends-with(@Name,'TEST')]/@OID
where $a = $datasetdef/odm:ItemRef/@ItemOID
return $a
)
let $testname := $datasetdef/../odm:ItemDef[@OID=$testoid]/@Name
(: get the associated codelist for TESTCD
and store the allowed values in a sequence - take into account that this can be coded either as EnumeratedItem as well as as CodeListItem :)
let $testcdcodelistoid := doc(concat($base,$define))//odm:ItemDef[@OID=$testcdoid]/odm:CodeListRef/@CodeListOID
let $testcdallowedvalues := (
for $codelistitem in doc(concat($base,$define))//odm:CodeList[@OID=$testcdcodelistoid]/*[name()='EnumeratedItem' or name()='CodeListItem']
return $codelistitem/@CodedValue
)
(: get the associated codelist for TEST
and store the allowed values in a sequence :)
let $testcodelistoid := doc(concat($base,$define))//odm:ItemDef[@OID=$testoid]/odm:CodeListRef/@CodeListOID
let $testallowedvalues := (
for $codelistitem in doc(concat($base,$define))//odm:CodeList[@OID=$testcodelistoid]/*[name()='EnumeratedItem' or name()='CodeListItem']
return $codelistitem/@CodedValue
)
(: get the dataset location :)
let $datasetname := $datasetdef/def:leaf/@xlink:href
let $datasetlocation := concat($base,$datasetname)
(: now iterate over all records in the dataset for which there is as well a TESTCD as a TEST :)
(: return <test>{data($datasetname)} - {data($testcdoid)} - {data($testoid)}</test> :)
for $record in doc($datasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$testcdoid] and odm:ItemData[@ItemOID=$testoid]]
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of TESTCD and TEST :)
let $testcdvalue := $record/odm:ItemData[@ItemOID=$testcdoid]/@Value
let $testvalue := $record/odm:ItemData[@ItemOID=$testoid]/@Value
(: and get the NCI code for as well the test code as the test value from the define.xml :)
let $ncicodetestcdvalue := doc(concat($base,$define))//odm:CodeList[@OID=$testcdcodelistoid]/*[(name()='CodeListItem' or name()='EnumeratedItem') and @CodedValue=$testcdvalue]/odm:Alias[@Context='nci:ExtCodeID']/@Name
let $ncicodetestvalue := doc(concat($base,$define))//odm:CodeList[@OID=$testcodelistoid]/*[(name()='CodeListItem' or name()='EnumeratedItem') and @CodedValue=$testvalue]/odm:Alias[@Context='nci:ExtCodeID']/@Name
(: we only report an error when both the NCI codes were found, but are different :)
where $ncicodetestcdvalue and $ncicodetestvalue and not($ncicodetestcdvalue=$ncicodetestvalue)
return <error rule="FDAC342" dataset="{data($datasetname)}" variable="{data($testname)}" rulelastupdate="2015-02-11" recordnumber="{data($recnum)}">
{data($testcdname)} and {data($testname)} do not have the same NCI code in CDISC CT. '{data($testcdvalue)}' in codelist {data($testcdcodelistoid)} has NCI code {data($ncicodetestcdvalue)} whereas '{data($testvalue)}' in codelist {data($testcodelistoid)} has NCI code {data($ncicodetestvalue)}</error>
Value for -DECOD not found in MedDRA dictionary - Value for the Dictionary-Derived Term (-DECOD) variable must be populated using a Preferred Term of the MedDRA dictionary of a version specified in the define.xml (Case-insensitive)
AE
MH
CE
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare namespace functx = "http://www.functx.com";
(: function to find out whether a value is in a sequence (array) :)
declare function functx:is-value-in-sequence
( $value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
declare variable $base external;
declare variable $define external;
declare variable $meddrabase external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: let $meddrabase := 'file:///e:/Validation_Rules_XQuery/meddra_17_1_english/MedAscii/' :)
let $meddrafile := 'pt.asc'
let $meddralocation := concat($meddrabase,$meddrafile)
(: read the meddra file line by line :)
let $lines := unparsed-text-lines($meddralocation)
(: get the preferred term, which is the second fied - field separator is the $ character :)
let $ptterms := (
for $line in $lines
return upper-case(tokenize($line,'\$')[2])
)
(: $ptterms know contains all the MedDRA PT terms in UPPERCASE :)
(: iterate over all AE, MH and CE dataset definitions :)
let $definedoc := doc(concat($base,$define))
for $itemgroup in $definedoc//odm:ItemGroupDef[@Name='AE' or @Name='MH' or @Name='CE' or @Domain='AE' or @Domain='MH' or @Domain='CE']
let $name := $itemgroup/@Name
(: get the OID of the --DECOD variable :)
let $decodoid := (
for $a in $definedoc//odm:ItemDef[ends-with(@Name,'DECOD')]/@OID
where $a = $itemgroup/odm:ItemRef/@ItemOID
return $a
)
let $decodname := $definedoc//odm:ItemDef[@OID=$decodoid]/@Name
(: get the dataset location :)
let $datasetlocation := $itemgroup/def:leaf/@xlink:href
let $datasetdoc := doc(concat($base,$datasetlocation))
(: iterate over all the records in the dataset :)
for $record in $datasetdoc//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of --DECOD :)
let $decodvalue := $record/odm:ItemData[@ItemOID=$decodoid]/@Value
(: give an error when the DECOD value is not one of the PT terms of MedDRA - case-insensitive :)
where $decodvalue and not(functx:is-value-in-sequence(upper-case($decodvalue),$ptterms))
return <error rule="FDAC346" dataset="{data($name)}" variable="{data($decodname)}" recordnumber="{data($recnum)}" rulelastupdate="2016-06-03">Value '{data($decodvalue)}' for {data($decodname)} was not found in the MedDRA dictionary</error>
Value for --DECOD is in incorrect case - Case for the Dictionary-Derived Term (--DECOD) variable must be sentence case using a Preferred Term of the MedDRA dictionary of a version specified in the define.xml (Case-sensitive).
AE
MH
CE
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare namespace functx = "http://www.functx.com";
(: function to find out whether a value is in a sequence (array) :)
declare function functx:is-value-in-sequence
( $value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
declare variable $base external;
declare variable $define external;
declare variable $meddrabase external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: let $meddrabase := 'file:///e:/Validation_Rules_XQuery/meddra_17_1_english/MedAscii/' :)
let $meddrafile := 'pt.asc'
let $meddralocation := concat($meddrabase,$meddrafile)
(: read the meddra file line by line :)
let $lines := unparsed-text-lines($meddralocation)
(: get the preferred term, which is the second fied - field separator is the $ character :)
let $ptterms := (
for $line in $lines
return tokenize($line,'\$')[2]
)
(: $ptterms know contains all the MedDRA PT terms in ORIGINAL CASE :)
(: we also keep a list of the uppercase ones :)
let $pttermsuppercase := (
for $ptterm in $ptterms
return upper-case($ptterm)
)
(: iterate over all AE, MH and CE dataset definitions :)
let $definedoc := doc(concat($base,$define))
for $itemgroup in $definedoc//odm:ItemGroupDef[@Name='AE' or @Name='MH' or @Name='CE' or @Domain='AE' or @Domain='MH' or @Domain='CE']
let $name := $itemgroup/@Name
(: get the OID of the --DECOD variable :)
let $decodoid := (
for $a in $definedoc//odm:ItemDef[ends-with(@Name,'DECOD')]/@OID
where $a = $itemgroup/odm:ItemRef/@ItemOID
return $a
)
let $decodname := $definedoc//odm:ItemDef[@OID=$decodoid]/@Name
(: get the dataset location :)
let $datasetlocation := $itemgroup/def:leaf/@xlink:href
let $datasetdoc := doc(concat($base,$datasetlocation))
(: iterate over all the records in the dataset :)
for $record in $datasetdoc//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of --DECOD :)
let $decodvalue := $record/odm:ItemData[@ItemOID=$decodoid]/@Value
(: give an error when the DECOD value is one of the PT terms of MedDRA (case-insensitive),
but not in the list of the PT terms in original case :)
where $decodvalue and functx:is-value-in-sequence(upper-case($decodvalue),$pttermsuppercase) and not(functx:is-value-in-sequence($decodvalue,$ptterms))
return <error rule="FDAC347" dataset="{data($name)}" variable="{data($decodname)}" recordnumber="{data($recnum)}" rulelastupdate="2016-06-03">Value '{data($decodvalue)}' for {data($decodname)} is in incorrect case from the MedDRA dictionary</error>
Value for --BODSYS not found in MedDRA dictionary - Value for Body System or Organ Class (--BODSYS) variable must be populated using a System Organ Class of the MedDRA dictionary of a version specified in the define.xml (Case-insensitive).
AE
MH
CE
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare namespace functx = "http://www.functx.com";
(: function to find out whether a value is in a sequence (array) :)
declare function functx:is-value-in-sequence
( $value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
declare variable $base external;
declare variable $define external;
declare variable $meddrabase external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: let $meddrabase := 'file:///e:/Validation_Rules_XQuery/meddra_17_1_english/MedAscii/' :)
let $meddrafile := 'soc.asc' (: :)
let $meddralocation := concat($meddrabase,$meddrafile)
(: read the meddra file line by line :)
let $lines := unparsed-text-lines($meddralocation)
(: get the SOC term, which is the second fied - field separator is the $ character :)
let $socterms := (
for $line in $lines
return upper-case(tokenize($line,'\$')[2])
)
(: $socterms know contains all the MedDRA SOC terms in UPPERCASE :)
(: iterate over all AE, MH and CE dataset definitions :)
let $definedoc := doc(concat($base,$define))
for $itemgroup in $definedoc//odm:ItemGroupDef[@Name='AE' or @Name='MH' or @Name='CE' or @Domain='AE' or @Domain='MH' or @Domain='CE']
let $name := $itemgroup/@Name
(: get the OID of the --BODSYS variable :)
let $bodsysoid := (
for $a in $definedoc//odm:ItemDef[ends-with(@Name,'BODSYS')]/@OID
where $a = $itemgroup/odm:ItemRef/@ItemOID
return $a
)
let $bodsysname := $definedoc//odm:ItemDef[@OID=$bodsysoid]/@Name
(: get the dataset location :)
let $datasetlocation := $itemgroup/def:leaf/@xlink:href
let $datasetdoc := doc(concat($base,$datasetlocation))
(: iterate over all the records in the dataset :)
for $record in $datasetdoc//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of --BODSYS :)
let $bodsysvalue := $record/odm:ItemData[@ItemOID=$bodsysoid]/@Value
(: give an error when the BODSYS value is not one of the SOC terms of MedDRA - case-insensitive :)
where $bodsysvalue and not(functx:is-value-in-sequence(upper-case($bodsysvalue),$socterms))
return <error rule="FDAC348" dataset="{data($name)}" variable="{data($bodsysname)}" recordnumber="{data($recnum)}" rulelastupdate="2016-06-03">Value '{data($bodsysvalue)}' for {data($bodsysname)} was not found in the MedDRA dictionary</error>
Case for --BODSYS is in incorrect case - Case for Body System or Organ Class (--BODSYS) variable must follow MedDRA sentence case and be populated using a System Organ Class of the MedDRA dictionary of a version specified in the define.xml (Case-sensitive).
AE
MH
CE
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare namespace functx = "http://www.functx.com";
(: function to find out whether a value is in a sequence (array) :)
declare function functx:is-value-in-sequence
( $value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
declare variable $base external;
declare variable $define external;
declare variable $meddrabase external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: let $meddrabase := 'file:///e:/Validation_Rules_XQuery/meddra_17_1_english/MedAscii/' :)
let $meddrafile := 'soc.asc' (: :)
let $meddralocation := concat($meddrabase,$meddrafile)
(: read the meddra file line by line :)
let $lines := unparsed-text-lines($meddralocation)
(: get the SOC term, which is the second fied - field separator is the $ character :)
let $socterms := (
for $line in $lines
return tokenize($line,'\$')[2]
)
(: $socterms know contains all the MedDRA SOC terms in ORIGINAL CASE :)
(: we also make the list in UPPERCASE :)
let $soctermsuppercase := (
for $socterm in $socterms
return upper-case($socterm)
)
(: iterate over all AE, MH and CE dataset definitions :)
let $definedoc := doc(concat($base,$define))
for $itemgroup in $definedoc//odm:ItemGroupDef[@Name='AE' or @Name='MH' or @Name='CE' or @Domain='AE' or @Domain='MH' or @Domain='CE']
let $name := $itemgroup/@Name
(: get the OID of the --BODSYS variable :)
let $bodsysoid := (
for $a in $definedoc//odm:ItemDef[ends-with(@Name,'BODSYS')]/@OID
where $a = $itemgroup/odm:ItemRef/@ItemOID
return $a
)
let $bodsysname := $definedoc//odm:ItemDef[@OID=$bodsysoid]/@Name
(: get the dataset location :)
let $datasetlocation := $itemgroup/def:leaf/@xlink:href
let $datasetdoc := doc(concat($base,$datasetlocation))
(: iterate over all the records in the dataset :)
for $record in $datasetdoc//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of --BODSYS :)
let $bodsysvalue := $record/odm:ItemData[@ItemOID=$bodsysoid]/@Value
(: give an error when the BODSYS value is one of the SOC terms of MedDRA - case-insensitive,
but not in the list of case-sensitive SOC values :)
where $bodsysvalue and functx:is-value-in-sequence(upper-case($bodsysvalue),$soctermsuppercase) and not(functx:is-value-in-sequence($bodsysvalue,$socterms))
return <error rule="FDAC349" dataset="{data($name)}" variable="{data($bodsysname)}" recordnumber="{data($recnum)}" rulelastupdate="2016-06-03">Value '{data($bodsysvalue)}' for {data($bodsysname)} is in incorrect case from the MedDRA dictionary</error>
Value for --PTCD not found in MedDRA dictionary - Value for Preferred Term Code (--PTCD) variable must be populated using a Preferred Term Code of the MedDRA dictionary of a version specified in the define.xml.
AE
MH
CE
(: Attention: this is about the preferred term CODE, not the name - e.g. 10000002 :)
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare namespace functx = "http://www.functx.com";
(: function to find out whether a value is in a sequence (array) :)
declare function functx:is-value-in-sequence
( $value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
declare variable $base external;
declare variable $define external;
declare variable $meddrabase external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: let $meddrabase := 'file:///e:/Validation_Rules_XQuery/meddra_17_1_english/MedAscii/' :)
let $meddrafile := 'pt.asc'
let $meddralocation := concat($meddrabase,$meddrafile)
(: read the meddra file line by line :)
let $lines := unparsed-text-lines($meddralocation)
(: get the preferred term codes, which is the first fied - field separator is the $ character :)
let $ptcodes := (
for $line in $lines
return tokenize($line,'\$')[1]
)
(: $ptcodes know contains all the MedDRA PT codes :)
(: iterate over all AE, MH and CE dataset definitions :)
let $definedoc := doc(concat($base,$define))
for $itemgroup in $definedoc//odm:ItemGroupDef[@Name='AE' or @Name='MH' or @Name='CE' or @Domain='AE' or @Domain='MH' or @Domain='CE']
let $name := $itemgroup/@Name
(: get the OID of the --PTCD variable :)
let $ptcdoid := (
for $a in $definedoc//odm:ItemDef[ends-with(@Name,'PTCD')]/@OID
where $a = $itemgroup/odm:ItemRef/@ItemOID
return $a
)
let $ptcdname := $definedoc//odm:ItemDef[@OID=$ptcdoid]/@Name
(: get the dataset location :)
let $datasetlocation := $itemgroup/def:leaf/@xlink:href
let $datasetdoc := doc(concat($base,$datasetlocation))
(: iterate over all the records in the dataset :)
for $record in $datasetdoc//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of --PTCD :)
let $ptcdvalue := $record/odm:ItemData[@ItemOID=$ptcdoid]/@Value
(: give an error when the PTCD value is not one of the PT codes of MedDRA :)
where $ptcdvalue and not(functx:is-value-in-sequence($ptcdvalue,$ptcodes))
return <error rule="FDAC350" dataset="{data($name)}" variable="{data($ptcdname)}" recordnumber="{data($recnum)}" rulelastupdate="2016-06-03">Value '{data($ptcdvalue)}' for {data($ptcdname)} was not found in the MedDRA dictionary</error>
Value for --LLT not found in MedDRA dictionary - Value for Lowest Level Term (--LLT) variable must be populated using a Lowest Level Term of the MedDRA dictionary of a version specified in the define.xml (Case-insensitive).
AE
MH
CE
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare namespace functx = "http://www.functx.com";
(: function to find out whether a value is in a sequence (array) :)
declare function functx:is-value-in-sequence
( $value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
declare variable $base external;
declare variable $define external;
declare variable $meddrabase external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: let $meddrabase := 'file:///e:/Validation_Rules_XQuery/meddra_17_1_english/MedAscii/' :)
let $meddrafile := 'llt.asc' (: :)
let $meddralocation := concat($meddrabase,$meddrafile)
(: read the meddra file line by line :)
let $lines := unparsed-text-lines($meddralocation)
(: get the LLT term, which is the second fied - field separator is the $ character :)
let $lltterms := (
for $line in $lines
return upper-case(tokenize($line,'\$')[2])
)
(: $lltterms know contains all the MedDRA LLT terms in UPPERCASE :)
(: iterate over all AE, MH and CE dataset definitions :)
let $definedoc := doc(concat($base,$define))
for $itemgroup in $definedoc//odm:ItemGroupDef[@Name='AE' or @Name='MH' or @Name='CE' or @Domain='AE' or @Domain='MH' or @Domain='CE']
let $name := $itemgroup/@Name
(: get the OID of the --LLT variable :)
let $lltoid := (
for $a in $definedoc//odm:ItemDef[ends-with(@Name,'LLT') and string-length(@Name)=5]/@OID
where $a = $itemgroup/odm:ItemRef/@ItemOID
return $a
)
let $lltname := $definedoc//odm:ItemDef[@OID=$lltoid]/@Name
(: get the dataset location :)
let $datasetlocation := $itemgroup/def:leaf/@xlink:href
let $datasetdoc := doc(concat($base,$datasetlocation))
(: iterate over all the records in the dataset :)
for $record in $datasetdoc//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of --LLC :)
let $lltvalue := $record/odm:ItemData[@ItemOID=$lltoid]/@Value
(: give an error when the LLT value is not one of the LLT terms of MedDRA - case-insensitive :)
where $lltvalue and not(functx:is-value-in-sequence(upper-case($lltvalue),$lltterms))
return <error rule="FDAC351" dataset="{data($name)}" variable="{data($lltname)}" recordnumber="{data($recnum)}" rulelastupdate="2016-06-03">Value '{data($lltvalue)}' for {data($lltname)} was not found in the MedDRA dictionary</error>
Value for --LLT is in incorrect case - Case for the Dictionary-Derived Term (--DECOD) variable must be sentence case using a Preferred Term of the MedDRA dictionary of a version specified in the define.xml (Case-sensitive).
AE
MH
CE
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare namespace functx = "http://www.functx.com";
(: function to find out whether a value is in a sequence (array) :)
declare function functx:is-value-in-sequence
( $value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
declare variable $base external;
declare variable $define external;
declare variable $meddrabase external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: let $meddrabase := 'file:///e:/Validation_Rules_XQuery/meddra_17_1_english/MedAscii/' :)
let $meddrafile := 'llt.asc'
let $meddralocation := concat($meddrabase,$meddrafile)
(: read the meddra file line by line :)
let $lines := unparsed-text-lines($meddralocation)
(: get the LLT terms, which is the second fied - field separator is the $ character :)
let $lltterms := (
for $line in $lines
return tokenize($line,'\$')[2]
)
(: $lltterms know contains all the MedDRA LLT terms in ORIGINAL CASE :)
(: we also keep a list of the uppercase ones :)
let $llttermsuppercase := (
for $lltterm in $lltterms
return upper-case($lltterm)
)
(: iterate over all AE, MH and CE dataset definitions :)
let $definedoc := doc(concat($base,$define))
for $itemgroup in $definedoc//odm:ItemGroupDef[@Name='AE' or @Name='MH' or @Name='CE' or @Domain='AE' or @Domain='MH' or @Domain='CE']
let $name := $itemgroup/@Name
(: get the OID of the --LLT variable :)
let $lltoid := (
for $a in $definedoc//odm:ItemDef[ends-with(@Name,'LLT') and string-length(@Name)=5]/@OID
where $a = $itemgroup/odm:ItemRef/@ItemOID
return $a
)
let $lltname := $definedoc//odm:ItemDef[@OID=$lltoid]/@Name
(: get the dataset location :)
let $datasetlocation := $itemgroup/def:leaf/@xlink:href
let $datasetdoc := doc(concat($base,$datasetlocation))
(: iterate over all the records in the dataset :)
for $record in $datasetdoc//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of --LLT :)
let $lltvalue := $record/odm:ItemData[@ItemOID=$lltoid]/@Value
(: give an error when the LLT value is one of the PT terms of MedDRA (case-insensitive),
but not in the list of the LLT terms in original case :)
where $lltvalue and functx:is-value-in-sequence(upper-case($lltvalue),$llttermsuppercase) and not(functx:is-value-in-sequence($lltvalue,$lltterms))
return <error rule="FDAC352" dataset="{data($name)}" variable="{data($lltname)}" recordnumber="{data($recnum)}" rulelastupdate="2016-06-03">Value '{data($lltvalue)}' for {data($lltname)} is in incorrect case from the MedDRA dictionary</error>
Value for --LLTCD not found in MedDRA dictionary - Value for Lowest Level Term Code (--LLTCD) variable must be populated using a Lowest Level Term Code of the MedDRA dictionary of a version specified in the define.xml.
AE
MH
CE
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare namespace functx = "http://www.functx.com";
(: function to find out whether a value is in a sequence (array) :)
declare function functx:is-value-in-sequence
( $value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
declare variable $base external;
declare variable $define external;
declare variable $meddrabase external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: let $meddrabase := 'file:///e:/Validation_Rules_XQuery/meddra_17_1_english/MedAscii/' :)
let $meddrafile := 'llt.asc' (: :)
let $meddralocation := concat($meddrabase,$meddrafile)
(: read the meddra file line by line :)
let $lines := unparsed-text-lines($meddralocation)
(: get the LLT CODE, which is the first fied - field separator is the $ character :)
let $lltcodes := (
for $line in $lines
return upper-case(tokenize($line,'\$')[1])
)
(: $lltcodes know contains all the MedDRA LLT codes :)
(: iterate over all AE, MH and CE dataset definitions :)
let $definedoc := doc(concat($base,$define))
for $itemgroup in $definedoc//odm:ItemGroupDef[@Name='AE' or @Name='MH' or @Name='CE' or @Domain='AE' or @Domain='MH' or @Domain='CE']
let $name := $itemgroup/@Name
(: get the OID of the --LLTCD variable :)
let $lltcdoid := (
for $a in $definedoc//odm:ItemDef[ends-with(@Name,'LLTCD')]/@OID
where $a = $itemgroup/odm:ItemRef/@ItemOID
return $a
)
let $lltcdname := $definedoc//odm:ItemDef[@OID=$lltcdoid]/@Name
(: get the dataset location :)
let $datasetlocation := $itemgroup/def:leaf/@xlink:href
let $datasetdoc := doc(concat($base,$datasetlocation))
(: iterate over all the records in the dataset :)
for $record in $datasetdoc//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of --LLTCD :)
let $lltcdvalue := $record/odm:ItemData[@ItemOID=$lltcdoid]/@Value
(: give an error when the LLTCD value is not one of the LLTCD codes of MedDRA :)
where $lltcdvalue and not(functx:is-value-in-sequence($lltcdvalue,$lltcodes))
return <error rule="FDAC353" dataset="{data($name)}" variable="{data($lltcdname)}" recordnumber="{data($recnum)}" rulelastupdate="2016-06-03">Value '{data($lltcdvalue)}' for {data($lltcdname)} was not found in the MedDRA dictionary</error>
Value for --HLT not found in MedDRA dictionary - Value for High Level Term (--HLT) variable must be populated using a High Level Term of the MedDRA dictionary of a version specified in the define.xml (Case-insensitive).
AE
MH
CE
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare namespace functx = "http://www.functx.com";
(: function to find out whether a value is in a sequence (array) :)
declare function functx:is-value-in-sequence
( $value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
declare variable $base external;
declare variable $define external;
declare variable $meddrabase external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: let $meddrabase := 'file:///e:/Validation_Rules_XQuery/meddra_17_1_english/MedAscii/' :)
let $meddrafile := 'hlt.asc' (: :)
let $meddralocation := concat($meddrabase,$meddrafile)
(: read the meddra file line by line :)
let $lines := unparsed-text-lines($meddralocation)
(: get the HLT term, which is the second fied - field separator is the $ character :)
let $hltterms := (
for $line in $lines
return upper-case(tokenize($line,'\$')[2])
)
(: $hltterms know contains all the MedDRA HLT terms in UPPERCASE :)
(: iterate over all AE, MH and CE dataset definitions :)
let $definedoc := doc(concat($base,$define))
for $itemgroup in $definedoc//odm:ItemGroupDef[@Name='AE' or @Name='MH' or @Name='CE' or @Domain='AE' or @Domain='MH' or @Domain='CE']
let $name := $itemgroup/@Name
(: get the OID of the --HLT variable :)
let $hltoid := (
for $a in $definedoc//odm:ItemDef[ends-with(@Name,'HLT') and string-length(@Name)=5]/@OID
where $a = $itemgroup/odm:ItemRef/@ItemOID
return $a
)
let $hltname := $definedoc//odm:ItemDef[@OID=$hltoid]/@Name
(: get the dataset location :)
let $datasetlocation := $itemgroup/def:leaf/@xlink:href
let $datasetdoc := doc(concat($base,$datasetlocation))
(: iterate over all the records in the dataset :)
for $record in $datasetdoc//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of --HLT :)
let $hltvalue := $record/odm:ItemData[@ItemOID=$hltoid]/@Value
(: give an error when the HLT value is not one of the HLT terms of MedDRA - case-insensitive :)
where $hltvalue and not(functx:is-value-in-sequence(upper-case($hltvalue),$hltterms))
return <error rule="FDAC354" dataset="{data($name)}" variable="{data($hltname)}" recordnumber="{data($recnum)}" rulelastupdate="2016-06-03">Value '{data($hltvalue)}' for {data($hltname)} was not found in the MedDRA dictionary</error>
Value for --HLT is in incorrect case - Case for High Level Term (--HLT) variable must be sentence case using a High Level Term of the MedDRA dictionary of a version specified in the define.xml (Case-sensitive).
AE
MH
CE
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare namespace functx = "http://www.functx.com";
(: function to find out whether a value is in a sequence (array) :)
declare function functx:is-value-in-sequence
( $value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
declare variable $base external;
declare variable $define external;
declare variable $meddrabase external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: let $meddrabase := 'file:///e:/Validation_Rules_XQuery/meddra_17_1_english/MedAscii/' :)
let $meddrafile := 'hlt.asc'
let $meddralocation := concat($meddrabase,$meddrafile)
(: read the meddra file line by line :)
let $lines := unparsed-text-lines($meddralocation)
(: get the HLT terms, which is the second fied - field separator is the $ character :)
let $hltterms := (
for $line in $lines
return tokenize($line,'\$')[2]
)
(: $hltterms know contains all the MedDRA HLT terms in ORIGINAL CASE :)
(: we also keep a list of the uppercase ones :)
let $hlttermsuppercase := (
for $hltterm in $hltterms
return upper-case($hltterm)
)
(: iterate over all AE, MH and CE dataset definitions :)
let $definedoc := doc(concat($base,$define))
for $itemgroup in $definedoc//odm:ItemGroupDef[@Name='AE' or @Name='MH' or @Name='CE' or @Domain='AE' or @Domain='MH' or @Domain='CE']
let $name := $itemgroup/@Name
(: get the OID of the --HLT variable :)
let $hltoid := (
for $a in $definedoc//odm:ItemDef[ends-with(@Name,'HLT') and string-length(@Name)=5]/@OID
where $a = $itemgroup/odm:ItemRef/@ItemOID
return $a
)
let $hltname := $definedoc//odm:ItemDef[@OID=$hltoid]/@Name
(: get the dataset location :)
let $datasetlocation := $itemgroup/def:leaf/@xlink:href
let $datasetdoc := doc(concat($base,$datasetlocation))
(: iterate over all the records in the dataset :)
for $record in $datasetdoc//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of --HLT :)
let $hltvalue := $record/odm:ItemData[@ItemOID=$hltoid]/@Value
(: give an error when the HLT value is one of the PT terms of MedDRA (case-insensitive),
but not in the list of the HLT terms in original case :)
where $hltvalue and functx:is-value-in-sequence(upper-case($hltvalue),$hlttermsuppercase) and not(functx:is-value-in-sequence($hltvalue,$hltterms))
return <error rule="FDAC355" dataset="{data($name)}" variable="{data($hltname)}" recordnumber="{data($recnum)}" rulelastupdate="2016-06-03">Value '{data($hltvalue)}' for {data($hltname)} is in incorrect case from the MedDRA dictionary</error>
Value for --HLTCD not found in MedDRA dictionary - Value for High Level Term Code (--HLTCD) variable must be populated using a High Level Term Code of the MedDRA dictionary of a version specified in the define.xml.
AE
MH
CE
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare namespace functx = "http://www.functx.com";
(: function to find out whether a value is in a sequence (array) :)
declare function functx:is-value-in-sequence
( $value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
declare variable $base external;
declare variable $define external;
declare variable $meddrabase external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: let $meddrabase := 'file:///e:/Validation_Rules_XQuery/meddra_17_1_english/MedAscii/' :)
let $meddrafile := 'hlt.asc' (: :)
let $meddralocation := concat($meddrabase,$meddrafile)
(: read the meddra file line by line :)
let $lines := unparsed-text-lines($meddralocation)
(: get the HLT CODE, which is the first fied - field separator is the $ character :)
let $hltcodes := (
for $line in $lines
return upper-case(tokenize($line,'\$')[1])
)
(: $hltcodes know contains all the MedDRA HLT codes :)
(: iterate over all AE, MH and CE dataset definitions :)
let $definedoc := doc(concat($base,$define))
for $itemgroup in $definedoc//odm:ItemGroupDef[@Name='AE' or @Name='MH' or @Name='CE' or @Domain='AE' or @Domain='MH' or @Domain='CE']
let $name := $itemgroup/@Name
(: get the OID of the --HLTCD variable :)
let $hltcdoid := (
for $a in $definedoc//odm:ItemDef[ends-with(@Name,'HLTCD')]/@OID
where $a = $itemgroup/odm:ItemRef/@ItemOID
return $a
)
let $hltcdname := $definedoc//odm:ItemDef[@OID=$hltcdoid]/@Name
(: get the dataset location :)
let $datasetlocation := $itemgroup/def:leaf/@xlink:href
let $datasetdoc := doc(concat($base,$datasetlocation))
(: iterate over all the records in the dataset :)
for $record in $datasetdoc//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of --HLTCD :)
let $hltcdvalue := $record/odm:ItemData[@ItemOID=$hltcdoid]/@Value
(: give an error when the HLTCD value is not one of the HLTCD codes of MedDRA :)
where $hltcdvalue and not(functx:is-value-in-sequence($hltcdvalue,$hltcodes))
return <error rule="FDAC356" dataset="{data($name)}" variable="{data($hltcdname)}" recordnumber="{data($recnum)}" rulelastupdate="2016-06-03">Value '{data($hltcdvalue)}' for {data($hltcdname)} was not found in the MedDRA dictionary</error>
Value for --HLGT not found in MedDRA dictionary - Value for High Level Group Term (--HLGT) variable must be populated using a High Level Group Term of the MedDRA dictionary of a version specified in the define.xml (Case-insensitive).
AE
MH
CE
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare namespace functx = "http://www.functx.com";
(: function to find out whether a value is in a sequence (array) :)
declare function functx:is-value-in-sequence
( $value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
declare variable $base external;
declare variable $define external;
declare variable $meddrabase external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: let $meddrabase := 'file:///e:/Validation_Rules_XQuery/meddra_17_1_english/MedAscii/' :)
let $meddrafile := 'hlgt.asc' (: HLGT file :)
let $meddralocation := concat($meddrabase,$meddrafile)
(: read the meddra file line by line :)
let $lines := unparsed-text-lines($meddralocation)
(: get the HLGT term, which is the second fied - field separator is the $ character :)
let $hlgtterms := (
for $line in $lines
return upper-case(tokenize($line,'\$')[2])
)
(: $hlgtterms know contains all the MedDRA HLGT terms in UPPERCASE :)
(: iterate over all AE, MH and CE dataset definitions :)
let $definedoc := doc(concat($base,$define))
for $itemgroup in $definedoc//odm:ItemGroupDef[@Name='AE' or @Name='MH' or @Name='CE' or @Domain='AE' or @Domain='MH' or @Domain='CE']
let $name := $itemgroup/@Name
(: get the OID of the --HLGT variable :)
let $hlgtoid := (
for $a in $definedoc//odm:ItemDef[ends-with(@Name,'HLGT') and string-length(@Name)=6]/@OID
where $a = $itemgroup/odm:ItemRef/@ItemOID
return $a
)
let $hlgtname := $definedoc//odm:ItemDef[@OID=$hlgtoid]/@Name
(: get the dataset location :)
let $datasetlocation := $itemgroup/def:leaf/@xlink:href
let $datasetdoc := doc(concat($base,$datasetlocation))
(: iterate over all the records in the dataset :)
for $record in $datasetdoc//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of --HLGT :)
let $hlgtvalue := $record/odm:ItemData[@ItemOID=$hlgtoid]/@Value
(: give an error when the HLGT value is not one of the HLGT terms of MedDRA - case-insensitive :)
where $hlgtvalue and not(functx:is-value-in-sequence(upper-case($hlgtvalue),$hlgtterms))
return <error rule="FDAC357" dataset="{data($name)}" variable="{data($hlgtname)}" recordnumber="{data($recnum)}" rulelastupdate="2016-06-03">Value '{data($hlgtvalue)}' for {data($hlgtname)} was not found in the MedDRA dictionary</error>
Value for --HLGT is in incorrect case - Case for High Level Group Term (--HLGT) variable must be sentence case using a High Level Group Term of the MedDRA dictionary of a version specified in the define.xml (Case-sensitive).
AE
MH
CE
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare namespace functx = "http://www.functx.com";
(: function to find out whether a value is in a sequence (array) :)
declare function functx:is-value-in-sequence
( $value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
declare variable $base external;
declare variable $define external;
declare variable $meddrabase external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: let $meddrabase := 'file:///e:/Validation_Rules_XQuery/meddra_17_1_english/MedAscii/' :)
let $meddrafile := 'hlgt.asc'
let $meddralocation := concat($meddrabase,$meddrafile)
(: read the meddra file line by line :)
let $lines := unparsed-text-lines($meddralocation)
(: get the HLGT terms, which is the second fied - field separator is the $ character :)
let $hlgtterms := (
for $line in $lines
return tokenize($line,'\$')[2]
)
(: $hltgterms know contains all the MedDRA HLT terms in ORIGINAL CASE :)
(: we also keep a list of the uppercase ones :)
let $hlgttermsuppercase := (
for $hlgtterm in $hlgtterms
return upper-case($hlgtterm)
)
(: iterate over all AE, MH and CE dataset definitions :)
let $definedoc := doc(concat($base,$define))
for $itemgroup in $definedoc//odm:ItemGroupDef[@Name='AE' or @Name='MH' or @Name='CE' or @Domain='AE' or @Domain='MH' or @Domain='CE']
let $name := $itemgroup/@Name
(: get the OID of the --HLGT variable :)
let $hlgtoid := (
for $a in $definedoc//odm:ItemDef[ends-with(@Name,'HLGT') and string-length(@Name)=6]/@OID
where $a = $itemgroup/odm:ItemRef/@ItemOID
return $a
)
let $hlgtname := $definedoc//odm:ItemDef[@OID=$hlgtoid]/@Name
(: get the dataset location :)
let $datasetlocation := $itemgroup/def:leaf/@xlink:href
let $datasetdoc := doc(concat($base,$datasetlocation))
(: iterate over all the records in the dataset :)
for $record in $datasetdoc//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of --HLGT :)
let $hlgtvalue := $record/odm:ItemData[@ItemOID=$hlgtoid]/@Value
(: give an error when the HLGT value is one of the HLGT terms of MedDRA (case-insensitive),
but not in the list of the HLGT terms in original case :)
where $hlgtvalue and functx:is-value-in-sequence(upper-case($hlgtvalue),$hlgttermsuppercase) and not(functx:is-value-in-sequence($hlgtvalue,$hlgtterms))
return <error rule="FDAC358" dataset="{data($name)}" variable="{data($hlgtname)}" recordnumber="{data($recnum)}" rulelastupdate="2016-06-03">Value '{data($hlgtvalue)}' for {data($hlgtname)} is in incorrect case from the MedDRA dictionary</error>
Value for --HLGTCD not found in MedDRA dictionary - Value for High Level Group Term Code (--HLGTCD) variable must be populated using a High Level Group Term Code of the MedDRA dictionary of a version specified in the define.xml.
AE
MH
CE
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare namespace functx = "http://www.functx.com";
(: function to find out whether a value is in a sequence (array) :)
declare function functx:is-value-in-sequence
( $value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
declare variable $base external;
declare variable $define external;
declare variable $meddrabase external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: let $meddrabase := 'file:///e:/Validation_Rules_XQuery/meddra_17_1_english/MedAscii/' :)
let $meddrafile := 'hlgt.asc' (: :)
let $meddralocation := concat($meddrabase,$meddrafile)
(: read the meddra file line by line :)
let $lines := unparsed-text-lines($meddralocation)
(: get the HLGT CODE, which is the first fied - field separator is the $ character :)
let $hlgtcodes := (
for $line in $lines
return upper-case(tokenize($line,'\$')[1])
)
(: $hlgtcodes know contains all the MedDRA HLGT codes :)
(: iterate over all AE, MH and CE dataset definitions :)
let $definedoc := doc(concat($base,$define))
for $itemgroup in $definedoc//odm:ItemGroupDef[@Name='AE' or @Name='MH' or @Name='CE' or @Domain='AE' or @Domain='MH' or @Domain='CE']
let $name := $itemgroup/@Name
(: get the OID of the --HLGTCD variable :)
let $hlgtcdoid := (
for $a in $definedoc//odm:ItemDef[ends-with(@Name,'HLGTCD')]/@OID
where $a = $itemgroup/odm:ItemRef/@ItemOID
return $a
)
let $hlgtcdname := $definedoc//odm:ItemDef[@OID=$hlgtcdoid]/@Name
(: get the dataset location :)
let $datasetlocation := $itemgroup/def:leaf/@xlink:href
let $datasetdoc := doc(concat($base,$datasetlocation))
(: iterate over all the records in the dataset :)
for $record in $datasetdoc//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of --HLGTCD :)
let $hlgtcdvalue := $record/odm:ItemData[@ItemOID=$hlgtcdoid]/@Value
(: give an error when the HLGTCD value is not one of the HLGTCD codes of MedDRA :)
where $hlgtcdvalue and not(functx:is-value-in-sequence($hlgtcdvalue,$hlgtcodes))
return <error rule="FDAC359" dataset="{data($name)}" variable="{data($hlgtcdname)}" recordnumber="{data($recnum)}" rulelastupdate="2016-06-03">Value '{data($hlgtcdvalue)}' for {data($hlgtcdname)} was not found in the MedDRA dictionary</error>
Value for --BDSYCD not found in MedDRA dictionary - Value for Body System or Organ Class Code (--BDSYCD) variable should be populated using a System Organ Class Code of the MedDRA dictionary of a version specified in the define.xml
AE
MH
CE
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare namespace functx = "http://www.functx.com";
(: function to find out whether a value is in a sequence (array) :)
declare function functx:is-value-in-sequence
( $value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
declare variable $base external;
declare variable $define external;
declare variable $meddrabase external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: let $meddrabase := 'file:///e:/Validation_Rules_XQuery/meddra_17_1_english/MedAscii/' :)
let $meddrafile := 'soc.asc' (: :)
let $meddralocation := concat($meddrabase,$meddrafile)
(: read the meddra file line by line :)
let $lines := unparsed-text-lines($meddralocation)
(: get the SOC code, which is the first fied - field separator is the $ character :)
let $soccodes := (
for $line in $lines
return upper-case(tokenize($line,'\$')[1])
)
(: $soccodes know contains all the MedDRA SOC codes :)
(: iterate over all AE, MH and CE dataset definitions :)
let $definedoc := doc(concat($base,$define))
for $itemgroup in $definedoc//odm:ItemGroupDef[@Name='AE' or @Name='MH' or @Name='CE' or @Domain='AE' or @Domain='MH' or @Domain='CE']
let $name := $itemgroup/@Name
(: get the OID of the --BDSYCD variable :)
let $bdsycdoid := (
for $a in $definedoc//odm:ItemDef[ends-with(@Name,'BDSYCD')]/@OID
where $a = $itemgroup/odm:ItemRef/@ItemOID
return $a
)
let $bdsycdname := $definedoc//odm:ItemDef[@OID=$bdsycdoid]/@Name
(: get the dataset location :)
let $datasetlocation := $itemgroup/def:leaf/@xlink:href
let $datasetdoc := doc(concat($base,$datasetlocation))
(: iterate over all the records in the dataset :)
for $record in $datasetdoc//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of --BDSYCD :)
let $bdsycdvalue := $record/odm:ItemData[@ItemOID=$bdsycdoid]/@Value
(: give an error when the BDSYCD value is not one of the SOC codes of MedDRA :)
where $bdsycdvalue and not(functx:is-value-in-sequence($bdsycdvalue,$soccodes))
return <warning rule="FDAC360" dataset="{data($name)}" variable="{data($bdsycdvalue)}" recordnumber="{data($recnum)}" rulelastupdate="2016-06-03">Value '{data($bdsycdvalue)}' for {data($bdsycdname)} was not found in the MedDRA dictionary</warning>
Value for --SOC not found in MedDRA dictionary - Value for System Organ Class (--SOC) variable must be populated using a System Organ Class of the MedDRA dictionary of a version specified in the define.xml (Case-insensitive).
AE
MH
CE
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare namespace functx = "http://www.functx.com";
(: function to find out whether a value is in a sequence (array) :)
declare function functx:is-value-in-sequence
( $value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
declare variable $base external;
declare variable $define external;
declare variable $meddrabase external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: let $meddrabase := 'file:///e:/Validation_Rules_XQuery/meddra_17_1_english/MedAscii/' :)
let $meddrafile := 'soc.asc' (: SOC file :)
let $meddralocation := concat($meddrabase,$meddrafile)
(: read the meddra file line by line :)
let $lines := unparsed-text-lines($meddralocation)
(: get the SOC term, which is the second fied - field separator is the $ character :)
let $socterms := (
for $line in $lines
return upper-case(tokenize($line,'\$')[2])
)
(: $socterms know contains all the MedDRA SOC terms - UPPERCASE :)
(: iterate over all AE, MH and CE dataset definitions :)
let $definedoc := doc(concat($base,$define))
for $itemgroup in $definedoc//odm:ItemGroupDef[@Name='AE' or @Name='MH' or @Name='CE' or @Domain='AE' or @Domain='MH' or @Domain='CE']
let $name := $itemgroup/@Name
(: get the OID of the --SOC variable :)
let $socoid := (
for $a in $definedoc//odm:ItemDef[ends-with(@Name,'SOC') and string-length(@Name)=5]/@OID
where $a = $itemgroup/odm:ItemRef/@ItemOID
return $a
)
let $socname := $definedoc//odm:ItemDef[@OID=$socoid]/@Name
(: get the dataset location :)
let $datasetlocation := $itemgroup/def:leaf/@xlink:href
let $datasetdoc := doc(concat($base,$datasetlocation))
(: iterate over all the records in the dataset :)
for $record in $datasetdoc//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of --SOC :)
let $socvalue := $record/odm:ItemData[@ItemOID=$socoid]/@Value
(: give an error when the SOC value is not one of the SOC terms of MedDRA :)
where $socvalue and not(functx:is-value-in-sequence(upper-case($socvalue),$socterms))
return <error rule="FDAC361" dataset="{data($name)}" variable="{data($socname)}" recordnumber="{data($recnum)}" rulelastupdate="2016-06-03">Value '{data($socvalue)}' for {data($socname)} was not found in the MedDRA dictionary</error>
Value for --SOC is in incorrect case - Case for System Organ Class (--SOC) variable must be sentence case using a System Organ Class of the MedDRA dictionary of a version specified in the define.xml (Case-sensitive).
AE
MH
CE
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare namespace functx = "http://www.functx.com";
(: function to find out whether a value is in a sequence (array) :)
declare function functx:is-value-in-sequence
( $value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
declare variable $base external;
declare variable $define external;
declare variable $meddrabase external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: let $meddrabase := 'file:///e:/Validation_Rules_XQuery/meddra_17_1_english/MedAscii/' :)
let $meddrafile := 'soc.asc'
let $meddralocation := concat($meddrabase,$meddrafile)
(: read the meddra file line by line :)
let $lines := unparsed-text-lines($meddralocation)
(: get the SOC terms, which is the second fied - field separator is the $ character :)
let $socterms := (
for $line in $lines
return tokenize($line,'\$')[2]
)
(: $socterms know contains all the MedDRA HLT terms in ORIGINAL CASE :)
(: we also keep a list of the uppercase ones :)
let $soctermsuppercase := (
for $socterm in $socterms
return upper-case($socterm)
)
(: iterate over all AE, MH and CE dataset definitions :)
let $definedoc := doc(concat($base,$define))
for $itemgroup in $definedoc//odm:ItemGroupDef[@Name='AE' or @Name='MH' or @Name='CE' or @Domain='AE' or @Domain='MH' or @Domain='CE']
let $name := $itemgroup/@Name
(: get the OID of the --SOC variable :)
let $socoid := (
for $a in $definedoc//odm:ItemDef[ends-with(@Name,'SOC') and string-length(@Name)=5]/@OID
where $a = $itemgroup/odm:ItemRef/@ItemOID
return $a
)
let $socname := $definedoc//odm:ItemDef[@OID=$socoid]/@Name
(: get the dataset location :)
let $datasetlocation := $itemgroup/def:leaf/@xlink:href
let $datasetdoc := doc(concat($base,$datasetlocation))
(: iterate over all the records in the dataset :)
for $record in $datasetdoc//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of --SOC :)
let $socvalue := $record/odm:ItemData[@ItemOID=$socoid]/@Value
(: give an error when the SOC value is one of the SOC terms of MedDRA (case-insensitive),
but not in the list of the SOC terms in original case :)
where $socvalue and functx:is-value-in-sequence(upper-case($socvalue),$soctermsuppercase) and not(functx:is-value-in-sequence($socvalue,$socterms))
return <error rule="FDAC362" dataset="{data($name)}" variable="{data($socname)}" recordnumber="{data($recnum)}" rulelastupdate="2016-06-03">Value '{data($socvalue)}' for {data($socname)} is in incorrect case from the MedDRA dictionary</error>
Value for --SOCCD not found in MedDRA dictionary - Value for System Organ Class Code (--SOCCD) variable must be populated using a System Organ Class Code of the MedDRA dictionary of a version specified in the define.xml.
AE
MH
CE
xquery version "3.0";
declare namespace def = "http://www.cdisc.org/ns/def/v2.0";
declare namespace odm="http://www.cdisc.org/ns/odm/v1.3";
declare namespace data="http://www.cdisc.org/ns/Dataset-XML/v1.0";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare namespace functx = "http://www.functx.com";
(: function to find out whether a value is in a sequence (array) :)
declare function functx:is-value-in-sequence
( $value as xs:anyAtomicType? ,
$seq as xs:anyAtomicType* ) as xs:boolean {
$value = $seq
} ;
declare variable $base external;
declare variable $define external;
declare variable $meddrabase external;
(: let $base := '/db/fda_submissions/cdisc01/' :)
(: let $define := 'define2-0-0-example-sdtm.xml' :)
(: let $meddrabase := 'file:///e:/Validation_Rules_XQuery/meddra_17_1_english/MedAscii/' :)
let $meddrafile := 'soc.asc'
let $meddralocation := concat($meddrabase,$meddrafile)
(: read the meddra file line by line :)
let $lines := unparsed-text-lines($meddralocation)
(: get the SOC codes, which is the first fied - field separator is the $ character :)
let $soccodes := (
for $line in $lines
return tokenize($line,'\$')[2]
)
(: $soccodes know contains all the MedDRA SOC codes :)
(: iterate over all AE, MH and CE dataset definitions :)
let $definedoc := doc(concat($base,$define))
for $itemgroup in $definedoc//odm:ItemGroupDef[@Name='AE' or @Name='MH' or @Name='CE' or @Domain='AE' or @Domain='MH' or @Domain='CE']
let $name := $itemgroup/@Name
(: get the OID of the --SOCCD variable :)
let $soccdoid := (
for $a in $definedoc//odm:ItemDef[ends-with(@Name,'SOCCD') and string-length(@Name)=7]/@OID
where $a = $itemgroup/odm:ItemRef/@ItemOID
return $a
)
let $soccdname := $definedoc//odm:ItemDef[@OID=$soccdoid]/@Name
(: get the dataset location :)
let $datasetlocation := $itemgroup/def:leaf/@xlink:href
let $datasetdoc := doc(concat($base,$datasetlocation))
(: iterate over all the records in the dataset :)
for $record in $datasetdoc//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: get the value of --SOCCD :)
let $soccdvalue := $record/odm:ItemData[@ItemOID=$soccdoid]/@Value
(: give an error when the SOCCD value is not one of the SOC codes in MedDRA :)
where $soccdvalue and not(functx:is-value-in-sequence($soccdvalue,$soccodes))
return <error rule="FDAC363" dataset="{data($name)}" variable="{data($soccdname)}" recordnumber="{data($recnum)}" rulelastupdate="2016-06-03">Value '{data($soccdvalue)}' for {data($soccdname)} was not found in the MedDRA dictionary</error>