我认为,这可以使用分组来解决,但作为XQuery的初学者,我无法编写有效的查询。
我正在使用带有XQuery version 3.
我有两个XML文档。第一个包含如下所示的记录:
<ItemGroupData ItemGroupOID="SUPPDM" data:ItemGroupDataSeq="1" >
<ItemData ItemOID="SUPPDM.USUBJID" Value="01-701-1015"/>
<ItemData ItemOID="SUPPDM.QNAM" Value="COMPLT16"/>
<ItemData ItemOID="SUPPDM.QLABEL" Value="Completers of Week 16 Population Flag"/>
</ItemGroupData>
<ItemGroupData ItemGroupOID="SUPPDM" data:ItemGroupDataSeq="2" >
<ItemData ItemOID="SUPPDM.USUBJID" Value="01-701-1015"/>
<ItemData ItemOID="SUPPDM.QNAM" Value="COMPLT24"/>
<ItemData ItemOID="SUPPDM.QLABEL" Value="Completers of Week 24 Population Flag"/>
</ItemGroupData>
<ItemGroupData ItemGroupOID="SUPPDM" data:ItemGroupDataSeq="3" >
<ItemData ItemOID="SUPPDM.USUBJID" Value="01-701-1015"/>
<ItemData ItemOID="SUPPDM.QNAM" Value="COMPLT8"/>
<ItemData ItemOID="SUPPDM.QLABEL" Value="Completers of Week 8 Population Flag"/>
</ItemGroupData>
<ItemGroupData ItemGroupOID="SUPPDM" data:ItemGroupDataSeq="4" >
<ItemData ItemOID="SUPPDM.USUBJID" Value="01-701-1015"/>
<ItemData ItemOID="SUPPDM.QNAM" Value="EFFICACY"/>
</ItemGroupData>
<ItemGroupData ItemGroupOID="SUPPDM" data:ItemGroupDataSeq="5" >
<ItemData ItemOID="SUPPDM.USUBJID" Value="01-701-1015"/>
<ItemData ItemOID="SUPPDM.QNAM" Value="ITT"/>
<ItemData ItemOID="SUPPDM.QLABEL" Value="Intent to Treat Population Flag"/>
</ItemGroupData>
<ItemGroupData ItemGroupOID="SUPPDM" data:ItemGroupDataSeq="6" >
<ItemData ItemOID="SUPPDM.USUBJID" Value="01-701-1015"/>
<ItemData ItemOID="SUPPDM.QNAM" Value="SAFETY"/>
<ItemData ItemOID="SUPPDM.QLABEL" Value="Safety Population Flag"/>
</ItemGroupData>
<ItemGroupData ItemGroupOID="SUPPDM" data:ItemGroupDataSeq="7" >
<ItemData ItemOID="SUPPDM.USUBJID" Value="01-701-1023"/>
<ItemData ItemOID="SUPPDM.QNAM" Value="EFFICACY"/>
<ItemData ItemOID="SUPPDM.QLABEL" Value="Efficacy Population Flag"/>
</ItemGroupData>
<ItemGroupData ItemGroupOID="SUPPDM" data:ItemGroupDataSeq="8" >
<ItemData ItemOID="SUPPDM.USUBJID" Value="01-701-1023"/>
<ItemData ItemOID="SUPPDM.QNAM" Value="ITT"/>
<ItemData ItemOID="SUPPDM.QLABEL" Value="Intent to Treat Population Flag"/>
</ItemGroupData>
<ItemGroupData ItemGroupOID="SUPPDM" data:ItemGroupDataSeq="9" >
<ItemData ItemOID="SUPPDM.USUBJID" Value="01-701-1023"/>
<ItemData ItemOID="SUPPDM.QNAM" Value="SAFETY"/>
<ItemData ItemOID="SUPPDM.QLABEL" Value="Safety Population Flag"/>
</ItemGroupData>
<ItemGroupData ItemGroupOID="SUPPDM" data:ItemGroupDataSeq="1198" >
<ItemData ItemOID="SUPPDM.USUBJID" Value="01-701-1015"/>
<ItemData ItemOID="SUPPDM.QNAM" Value="RACE1"/>
</ItemGroupData>
<ItemGroupData ItemGroupOID="SUPPDM" data:ItemGroupDataSeq="1199" >
<ItemData ItemOID="SUPPDM.USUBJID" Value="01-701-1015"/>
<ItemData ItemOID="SUPPDM.QNAM" Value="RACE2"/>
</ItemGroupData>
<ItemGroupData ItemGroupOID="SUPPDM" data:ItemGroupDataSeq="1200" >
<ItemData ItemOID="SUPPDM.USUBJID" Value="01-701-1023"/>
<ItemData ItemOID="SUPPDM.QNAM" Value="RACE1"/>
</ItemGroupData>
重点是最后三个记录(‘RACEx’
)。
第二个文档具有以下记录(具有唯一记录,每个记录具有不同的USUBJID
)。
<ItemGroupData ItemGroupOID="DM" data:ItemGroupDataSeq="1" >
<ItemData ItemOID="DM.USUBJID" Value="01-701-1015"/>
<ItemData ItemOID="DM.RACE" Value="Multiple"/>
</ItemGroupData>
<ItemGroupData ItemGroupOID="DM" data:ItemGroupDataSeq="2" >
<ItemData ItemOID="DM.USUBJID" Value="01-701-1023"/>
<ItemData ItemOID="DM.RACE" Value="Multiple"/>
</ItemGroupData>
正如您所看到的,SUPPDM
有多条记录具有相同的USUBJID
,但可以有多个QNAM
值。
我想检查QNAM
时USUBJID
对于某个RACEx
是否为“DM.RACE is Multiple
”。
我试着写一个XQuery,它实际上有点工作但是回报不知何故没有返回RACE
的值..你能帮我吗?
这是我的XQuery(在开始时,我声明了我从另一个Metadata 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";
let $base := '/db/mydataset/'
let $define := 'define_2_0.xml'
(: get the SUPPDM dataset :)
let $suppdmdataset := doc(concat($base,$define))//odm:ItemGroupDef[@Name='SUPPDM']
let $suppdmdatasetname := $suppdmdataset/def:leaf/@xlink:href
let $suppdmdatasetlocation := concat($base,$suppdmdatasetname)
(: 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)
(:get the USUBJID in DM :)
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 USUBJID in SUPPDM :)
let $suppdmusubjidoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='USUBJID']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='SUPPDM']/odm:ItemRef/@ItemOID
return $a
)
(: get the OID of RACE in DM dataset :)
let $raceoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='RACE']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='DM']/odm:ItemRef/@ItemOID
return $a
)
(: get the OID of QNAM in SUPPDM :)
let $qnamoid := (
for $a in doc(concat($base,$define))//odm:ItemDef[@Name='QNAM']/@OID
where $a = doc(concat($base,$define))//odm:ItemGroupDef[@Name='SUPPDM']/odm:ItemRef/@ItemOID
return $a
)
(:substring(QNAM,1,4) = „RACE“ :)
(:we are searching through the subjects in DM that have the value "Multiple" in RACE :)
for $record in doc($dmdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$raceoid and upper-case(@Value)='MULTIPLE']]
(:or for $record in doc($suppdmdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$qnamoid]]/starts-with(@Value,"RACE") :)
let $recnum := $record/@data:ItemGroupDataSeq
(: Get the DM USUBJID value :)
let $dmusubjidvalue := $record/odm:ItemData[@ItemOID=$dmusubjidoid]/@Value
(: now get the value of QNAM in SUPPDM for the subject with the corresponding USUBJID - it should be "RACE1", RACE2 or ... "RACEn"; principally it should start with 'RACE' :)
let $qnamvalue := (
for $a in doc($suppdmdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$suppdmusubjidoid and @Value=$dmusubjidvalue]]
let $b := doc($suppdmdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID=$qnamoid]]/upper-case(@Value)
where (starts-with($b, 'RACE'))
return $a
)
(:now check, whether the value QNAM starts with 'RACE' :)
(: where not(starts-with($qnamvalue, "RACE")):)
return <warning recordnumber="{data($recnum)}">Invalid value for QNAM in dataset {data($suppdmdatasetname)} - Label={data($qnamvalue)}. => RACE in {data($dmdatasetlocation)} for subject {data($dmusubjidvalue)} is 'Multiple', so QNAM should be in (RACE1, RACE2,... RACEn). If RACE is 'Multiple', additional information has to be added to the Supplemental Qualifier dataset of DM (SUPPDM) </warning>
我不确定WHERE
表达式。不幸的是,我的输出看起来像这样:
&#34;数据集QNAM
中的suppdm.xml
值无效。 =&GT;&#34;
$qnamvalue ...这总是空的。
(2015年12月5日更新) 在这里,我根据adamretter的建议发布了新的XQuery!
for $record in doc($dmdatasetlocation)//odm:ItemGroupData
let $recnum := $record/@data:ItemGroupDataSeq
(: get value of usubjid :)
let $dmusubjidvalue := $record//odm:ItemData[@ItemOID=$dmusubjidoid]/@Value
(:check, whether this usubjid has a record in SUPPDM that has QNAM in 'RACEx' :)
let $multiple-usubjid :=
not(empty(doc("$dmdatasetlocation")//odm:ItemGroupData[odm:ItemData[@ItemOID =$dmusubjidoid][@Value =$dmusubjidvalue]][odm:ItemData[@ItemOID eq $raceoid][@Value eq "Multiple"]]
))
return
(:it will return give a return if there exists a usubjid that has a QNAM that matches RACE :)
if($multiple-usubjid) then
doc($suppdmdatasetlocation)//odm:ItemGroupData[odm:ItemData[@ItemOID = $suppdmusubjidoid][@Value = $dmusubjidvalue]][odm:ItemData[@ItemOID =$qnamoid]
[fn:matches(@Value, "RACE[0-9]+")]]
else(
<warning rule="SPC_DM_RACE_01" rulelastupdate="2015-02-10" recordnumber="{data($recnum)}">Invalid value for QNAM in dataset {data($suppdmdatasetname)} - Label={data($multiple-usubjid)}. => RACE in {data
($dmdatasetlocation)} for subject {data($dmusubjidvalue)} is 'Multiple', so QNAM should be in (RACE1, RACE2,... RACEn). If RACE is 'Multiple', additional information has to be added to the Supplemental Qualifier dataset of DM (SUPPDM)
</warning>
我完全理解这些表达式,但是如何在QNAM
中检索正确的RACE
值呢?查询不按我想要的方式工作,不知怎的,我从DM
返回所有记录。
至少,我得到multiple-usubjid
的值(False或True),但我希望收到QNAM
中包含USUBJID
的{{1}}值。
我是一个真正的初学者,我不太清楚我必须在其他表达中加入什么,或者我必须如何重新组织&#34;查询。
再次感谢您的帮助! 克里斯蒂安
答案 0 :(得分:0)
您正在寻找两个文件之间的简单连接,尽管您也可以在没有连接的情况下进行连接。因为您确实有两个查询,并且只有在第一个查询匹配时才需要执行第二个查询。
为了简化您的问题,我将您的两个XML文件存储到/tmp/doc1.xml
和/tmp/doc2.xml
,并专注于查找您感兴趣的节点,上面的许多XQuery并没有真正专注于你遇到的核心问题。无论如何,这是我提出的解决方案 -
xquery version "1.0";
(: the USUBJID you are interested in :)
declare variable $local:usubjid := "01-701-1015";
let $multiple-usubjid :=
not(empty(
doc("/tmp/doc2.xml")
//ItemGroupData[ItemData[@ItemOID eq "DM.USUBJID"]
[@Value eq $local:usubjid]][ItemData[@ItemOID eq "DM.RACE"]
[@Value eq "Multiple"]]
))
return
if($multiple-usubjid) then
doc("/tmp/doc1.xml")
//ItemGroupData[ItemData[@ItemOID eq "SUPPDM.USUBJID"]
[@Value eq $local:usubjid]][ItemData[@ItemOID eq "SUPPDM.QNAM"]
[fn:matches(@Value, "RACE[0-9]+")]]
else()
现在很明显,如果要测试所有USUBJID
,可以将其提取到函数中或重写为更高效,但希望它是讨论的良好起点。