基于XSLT 3.0提取偏离参考范围的Observation为多文档
完善XSLT代码以检测偏离参考范围的观测值并按主题分组生成独立文档
看起来你需要实现检测观测值是否偏离参考范围,并按Subject分组生成指定结构的独立XML文档的需求。我帮你修正并完善了代码,同时解释关键逻辑:
原始输入XML
<doc> <Bundle> <entry> <Observation> <id value="o1-3" /> <subject> <reference value="Subject/1" /> </subject> <valueQuantity> <value value="400" /> <unit value="U" /> </valueQuantity> <referenceRange> <low> <value value="0" /> <unit value="U" /> </low> <high> <value value="45" /> <unit value="U" /> </high> </referenceRange> </Observation> </entry> <entry> <Observation> <id value="o8-3" /> <subject> <reference value="Subject/1" /> </subject> <valueQuantity> <value value="0.39" /> <unit value="L" /> </valueQuantity> <referenceRange> <low> <value value="0.14" /> <unit value="L" /> </low> <high> <value value="0.35" /> <unit value="L" /> </high> </referenceRange> </Observation> </entry> </Bundle> <Bundle> <entry> <Observation> <id value="o3-4" /> <subject> <reference value="Subject/2" /> </subject> <valueQuantity> <value value="10" /> <unit value="U" /> </valueQuantity> <referenceRange> <low> <value value="3" /> <unit value="U" /> </low> <high> <value value="30" /> <unit value="U" /> </high> </referenceRange> </Observation> </entry> <entry> <Observation> <id value="o15-4" /> <subject> <reference value="Subject/2" /> </subject> <valueQuantity> <value value="7.1" /> <unit value="m" /> </valueQuantity> <referenceRange> <low> <value value="3.5" /> <unit value="m" /> </low> <high> <value value="5.0" /> <unit value="m" /> </high> </referenceRange> </Observation> </entry> </Bundle> </doc>
需求回顾
- 检查每个
Observation的valueQuantity/value是否超出referenceRange的low/value和high/value范围(小于下限或大于上限) - 将所有偏离范围的
Observation按subject/reference的值分组 - 为每个分组生成独立的XML文档,结构符合给定的
<Interpretation>示例(包含命名空间、<Subject>节点和<Observations>集合)
原代码存在的问题
- 模板匹配
valueQuantity,导致逻辑分散,无法高效按Subject分组 - 没有生成要求的
<Interpretation>根节点结构,缺少命名空间和<Subject>节点 - 结果文档按
id命名,没有实现按Subject分组的要求 - 数值比较的逻辑不够严谨,没有确保字符串转数值的正确性
完善后的XSLT代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://intelli.org/interpretation"> <!-- 定义key:按subject的reference值分组偏离的Observation --> <xsl:key name="deviated-by-subject" match="Observation[ xs:double(valueQuantity/value/@value) lt xs:double(referenceRange/low/value/@value) or xs:double(valueQuantity/value/@value) gt xs:double(referenceRange/high/value/@value) ]" use="subject/reference/@value"/> <!-- 主模板:处理根节点doc --> <xsl:template match="/doc"> <!-- 遍历所有唯一的subject(仅包含偏离的Observation) --> <xsl:for-each select="Bundle/entry/Observation[ xs:double(valueQuantity/value/@value) lt xs:double(referenceRange/low/value/@value) or xs:double(valueQuantity/value/@value) gt xs:double(referenceRange/high/value/@value) ]/subject/reference/@value[not(. = preceding::subject/reference/@value)]"> <!-- 为每个subject生成独立的XML文档 --> <xsl:result-document include-content-type="no" href="/interpret&extract/deviation/interpretation_{replace(., '/', '_')}.xml"> <?xml version="1.0" encoding="UTF-8"?> <Interpretation> <Subject><xsl:value-of select="."/></Subject> <Observations> <!-- 取出当前subject下所有偏离的Observation --> <xsl:copy-of select="key('deviated-by-subject', .)"/> </Observations> </Interpretation> </xsl:result-document> </xsl:for-each> </xsl:template> <!-- 身份模板:复制节点结构(用于copy-of) --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:template> </xsl:template> </xsl:stylesheet>
关键逻辑解释
- 分组key定义:使用
<xsl:key>提前筛选出所有偏离范围的Observation,并按subject/reference的值分组,方便后续按Subject批量提取。 - 数值比较:使用
xs:double()将字符串类型的value转换为数值,确保比较逻辑的正确性(避免字符串比较的错误,比如"10"和"9"的字符串比较结果不符合数值逻辑)。 - 生成独立文档:遍历所有唯一的Subject(仅包含偏离的Observation),为每个Subject生成以
interpretation_{替换斜杠后的Subject值}.xml命名的文档,路径符合需求(用replace()处理路径中的斜杠,避免文件路径错误)。 - 结构生成:严格按照示例生成
<Interpretation>根节点,包含指定的命名空间、<Subject>节点和<Observations>集合,复制所有符合条件的Observation节点到集合中。 - 身份模板:确保
copy-of能正确复制Observation的完整节点结构(包括子节点和属性)。
输出示例
对于Subject/1,生成的interpretation_Subject_1.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?> <Interpretation xmlns="http://intelli.org/interpretation"> <Subject>Subject/1</Subject> <Observations> <Observation> <id value="o1-3"/> <subject> <reference value="Subject/1"/> </subject> <valueQuantity> <value value="400"/> <unit value="U"/> </valueQuantity> <referenceRange> <low> <value value="0"/> <unit value="U"/> </low> <high> <value value="45"/> <unit value="U"/> </high> </referenceRange> </Observation> <Observation> <id value="o8-3"/> <subject> <reference value="Subject/1"/> </subject> <valueQuantity> <value value="0.39"/> <unit value="L"/> </valueQuantity> <referenceRange> <low> <value value="0.14"/> <unit value="L"/> </low> <high> <value value="0.35"/> <unit value="L"/> </high> </referenceRange> </Observation> </Observations> </Interpretation>
内容的提问来源于stack exchange,提问作者Fiona Chen
相关产品推荐
相关产品推荐

