I have document
diagnosis.xml
<diagnosis>
<component name="heart attack" classCode="healthcare service">
<component name="Diabetes I" classCode="observation" spec="intraocular lens">
<component name="Diabetes II" classCode="manifestation">
<component name="Diabetic Retinopathy" classCode="RSON :: rational service" spec="generalized obesity"/>
</component>
<component name="Coronary Artery Disease" classCode="ACT :: healthcare service" spec="hypertension"/>
</component>
<component name="nonproliferative diabetic retinopathy" classCode="ACT">
<component name="Ophthalmic diagnosis" classCode="OBS observation" spec="Viscoelastic applied"/>
</component>
</component>
<component name="Extracapsular cataract removal" classCode="PCPR :: care provision">
<component name="intraocular lens" classCode="Allopathic & Osteopathic" spec="Diabetes I">
<component name="Viscoelastic applied" classCode="SBADM :: substance administration" spec="Ophthalmic diagnosis"/>
</component>
<component name="lipoprotein cholesterol " classCode="BATTERY">
<component name="Furosemide" classCode="SBADM :: substance administration"/>
<component name="hypertension" classCode="OBS" spec="Coronary Artery Disease">
<component name="generalized obesity" classCode="observation" spec="Diabetic Retinopathy"/>
</component>
</component>
</component>
</diagnosis>
In order to discover the intricacy between
name
andspec
(similar to PK-FK in RDBMS), I havediagnosis-q1-q4.xsl
<xsl:template match="diagnosis">
<xsl:variable name="q" select="//component"/>
<result>
<!-- for each q3 -->
<xsl:for-each select="$q[../../../component]">
<!-- get quartile/Q1 -->
<quartile Q1="{../../@name}" Q3="{@name}"/>
<!-- get quartile/Q1-spec if quartile/Q1's spec exists -->
<xsl:if test="../../@spec">
<dup q1-spec="{../../@spec}" q3="{@name}"/>
</xsl:if>
<!-- get parent's spec of this component -->
<xsl:variable name="q2" select="../@spec"/>
<!-- get parent of q2 if exists -->
<xsl:variable name="q3" select="$q[component/@name=$q2]"/>
<xsl:if test="$q3">
<dup q2-spec="{$q3/@name}" q3="{@name}"/>
<xsl:if test="$q3/@spec">
<dup q3-spec="{$q3/@spec}" q3="{@name}"/>
</xsl:if>
</xsl:if>
</xsl:for-each>
</result>
</xsl:template>
</xsl:stylesheet>
diagnosis-q1-q4.xsl
equivalent isdiagnosis-q1-q4.xqy
:
xquery version "1.0-ml";
<Lineage>
{
for $gp in doc("diagnosis.xml")//component,
$p in $gp/component,
$gc in $p/component
return
if (exists($gp/@spec))
then (<quartile Q1="{ $gp/@name }" Q3="{ $gc/@name }"/>,
<quartile-spec Q1-spec="{ $gp/@spec }" q3="{ $gc/@name }"/>)
else (<quartile Q1="{ $gp/@name }" Q3="{ $gc/@name }"/>)
}
{
for $gp in doc("diagnosis.xml")//component,
$p in $gp/component[@spec != ''],
$gc in $p/component
return
let $p-spec := $p/@spec
for $p-node in doc("diagnosis.xml")//component
where every $andante in $p-node/@name
satisfies ($andante = $p-spec)
return
if (exists($p-node/../@spec))
then (<quartile-spec q2-spec-Q1="{ $p-node/../@name }" q3="{ $gc/@name }"/>,
<quartile-spec q2-spec-Q1-spec="{ $p-node/../@spec }" q3="{ $gc/@name }"/>)
else (<quartile-spec q2-spec-Q1-="{ $p-node/../@name }" q3="{ $gc/@name }"/>)
}
</Lineage>
Either diagnosis-q1-q4.xsl or diagnosis-q1-q4.xqy yields the same result:
<Lineage>
<quartile Q1="heart attack" Q3="Diabetes II"/>
<quartile Q1="heart attack" Q3="Coronary Artery Disease"/>
<quartile Q1="heart attack" Q3="Ophthalmic diagnosis"/>
<quartile Q1="Diabetes I" Q3="Diabetic Retinopathy"/>
<quartile-spec Q1-spec="intraocular lens" q3="Diabetic Retinopathy"/>
<quartile Q1="Extracapsular cataract removal" Q3="Viscoelastic applied"/>
<quartile Q1="Extracapsular cataract removal" Q3="Furosemide"/>
<quartile Q1="Extracapsular cataract removal" Q3="hypertension"/>
<quartile Q1="lipoprotein cholesterol " Q3="generalized obesity"/>
<quartile-spec q2-spec-Q1-="Extracapsular cataract removal" q3="Diabetes II"/>
<quartile-spec q2-spec-Q1-="Extracapsular cataract removal"
q3="Coronary Artery Disease"/>
<quartile-spec q2-spec-Q1-="heart attack" q3="Viscoelastic applied"/>
<quartile-spec q2-spec-Q1="Diabetes I" q3="generalized obesity"/>
<quartile-spec q2-spec-Q1-spec="intraocular lens" q3="generalized obesity"/>
</Lineage>
My questions are:
- Is it possible to simplify
diagnosis-q1-q4.xqy
?- Is it possible to simplify
diagnosis-q1-q4.xsl
with XSLT 3.0 ?
From what I understand you wanted to see how to turn XSLT into xquery. So I tried to stay as close as possible to the original stylesheet you provided.
xquery version "3.1";
let $doc := doc("diagnosis.xml")
let $q := $doc//component
for $c in $q[../../../component]
return (
<quartile Q1="{$c/../../@name}" Q3="{$c/@name}"/>
,
if (exists($c/../../@spec))
then <dup q1-spec="{$c/../../@spec}" q3="{$c/@name}"/>
else ()
,
let $q2 := $c/../@spec
let $q3 := $q[component/@name=$q2]
return (
if (exists($q3))
then (
<dup q2-spec="{$q3/@name}" q3="{$c/@name}"/>
,
if (exists($q3/@spec))
then <dup q3-spec="{$q3/@spec}" q3="{$c/@name}"/>
else ()
)
else ()
)
)
I also liked the original approach, since it iterates only once over all matching components.
Hope it sheds some light in the relationship of the two.