XSLT中xsl:apply-templates传递cqrKeyw参数值未生效问题
问题:XSLT中使用xsl:apply-templates传递参数cqrKeyw始终为空
我用<xsl:apply-templates>传递名为cqrKeyw的参数,值设为'CQR',但被调用模板里这个参数一直为空。试过用<xsl:param name="cqrKeyw" select="."/>声明参数,问题仍未解决。
调用模板代码
<xsl:template match="ServiceRequest[category/coding/code[@value='services']]"> <entry> <xsl:comment> Planned Procedure (V2) </xsl:comment> <procedure classCode="PROC" moodCode="INT"> <xsl:call-template name="templateId"> <xsl:with-param name="template-ids">2.16.840.1.113883.10.20.22.4.41:2014-06-09 2.16.840.1.113883.10.20.22.4.41</xsl:with-param> </xsl:call-template> <xsl:apply-templates select="id|identifier" mode="id" /> <xsl:choose> <!-- 从code映射编码 --> <xsl:when test="code"> <xsl:variable name="cqrString"><xsl:value-of select = "'CQR'"></xsl:value-of></xsl:variable> <xsl:text>AAAAAAAAAAAAAAAAAAA</xsl:text> <xsl:value-of select="$cqrString"></xsl:value-of> <xsl:apply-templates select="code" mode="code"> <xsl:with-param name="cqrKeyw" select="$cqrString"></xsl:with-param> </xsl:apply-templates> </xsl:when> <xsl:otherwise> <code nullFlavor="NI" /> </xsl:otherwise> </xsl:choose> <statusCode code="active" /> <!-- 从occurrenceDateTime映射effectiveTime --> <xsl:apply-templates mode="effectiveTimeIVL_TS" select="occurrenceDateTime" /> <!-- 从requester映射author--> <xsl:if test="contains(requester/reference/@value,'Practitioner')"> <xsl:variable name="refId" select="substring-after(requester/reference/@value,'/')"/> <xsl:apply-templates mode="author" select="(//Bundle/entry/resource/Practitioner[id/@value=$refId])[1]"> <xsl:with-param name="time" select="meta/lastUpdated"/> </xsl:apply-templates> </xsl:if> </procedure> </entry> </xsl:template>
被调用模板代码
<xsl:template name="coding" match="coding|valueCoding" mode="code"> <xsl:param name="this" select="."/> <xsl:param name="doc" select="/"/> <xsl:param name="DisplayName" select="/"/> <xsl:param name="cqrKeyw"/> <xsl:choose> <!-- 处理v3版本NullFlavor代码系统的特殊编码情况 --> <xsl:when test="$this/code/@value and $this/system/@value = 'http://hl7.org/fhir/v3/NullFlavor'"> <xsl:attribute name="nullFlavor"> <xsl:value-of select="$this/code/@value"/> </xsl:attribute> </xsl:when> <xsl:when test="$this/code/@value"> <xsl:choose> <xsl:when test="not($cqrKeyw='CQR') and contains($this/code/@value,':')"> <xsl:variable name="cptOrSnomedCode" select="substring-before($this/code/@value,':')"/> <xsl:attribute name="code"> <xsl:value-of select="$cptOrSnomedCode"/> <xsl:text>cqrKey值为:</xsl:text> <xsl:copy-of select="$cqrKeyw"></xsl:copy-of> </xsl:attribute> </xsl:when> <xsl:otherwise> <xsl:attribute name="code"> <xsl:value-of select="$this/code/@value"/> </xsl:attribute> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:otherwise> <xsl:attribute name="nullFlavor">UNK</xsl:attribute> </xsl:otherwise> </xsl:choose> <xsl:choose> <xsl:when test="$this/system/@value = 'http://hl7.org/fhir/v3/NullFlavor'"> <!-- 代码系统为nullFlavor时不做处理 --> </xsl:when> <xsl:when test="$this/system/@value"> <xsl:call-template name="translate-codeSystem"> <xsl:with-param name="this" select="$this/system/@value"/> <xsl:with-param name="code" select="$this/code/@value"/> <xsl:with-param name="doc" select="$doc"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:attribute name="nullFlavor">UNK</xsl:attribute> </xsl:otherwise> </xsl:choose> <xsl:choose> <xsl:when test="$this/system/@value='http://www.nlm.nih.gov/research/umls/rxnorm' and $DisplayName[contains($DisplayName,'(')] "> <xsl:variable name="MedicationGenericName" select="substring-before(substring-after($DisplayName,'('),')')"/> <xsl:if test="$MedicationGenericName"> <xsl:attribute name="displayName"> <xsl:value-of select="$MedicationGenericName"/> </xsl:attribute> </xsl:if> </xsl:when> <xsl:otherwise> <xsl:if test="$this/code/@value and $this/display/@value and not($this/system/@value = 'http://hl7.org/fhir/v3/NullFlavor')"> <xsl:attribute name="displayName"> <xsl:value-of select="$this/display/@value"/> </xsl:attribute> </xsl:if> </xsl:otherwise> </xsl:choose> </xsl:template>
问题原因及解决方法
核心问题
你当前的调用逻辑是对ServiceRequest下的code节点应用mode="code"的模板,但被调用的coding模板匹配的是coding|valueCoding节点:
- 如果
code节点下包含coding子节点,XSLT会先找匹配code节点且mode="code"的模板(若存在),若该模板内部调用coding模板时未传递cqrKeyw参数,就会导致参数为空; - 若没有专门匹配
code节点的mode="code"模板,XSLT会使用默认模板处理code节点,默认模板仅遍历子节点但不会传递你传入的cqrKeyw参数,最终coding模板仍拿不到值。
解决办法
直接选择目标节点:如果目标是处理
code下的coding子节点,修改调用代码的select属性,直接将参数传递给coding模板:<xsl:apply-templates select="code/coding" mode="code"> <xsl:with-param name="cqrKeyw" select="$cqrString"></xsl:with-param> </xsl:apply-templates>传递参数到中间模板:若必须先处理
code节点,需编写匹配code节点且mode="code"的模板,并在其中传递cqrKeyw参数:<xsl:template match="code" mode="code"> <xsl:param name="cqrKeyw"/> <!-- 添加code节点的处理逻辑 --> <xsl:apply-templates select="coding" mode="code"> <xsl:with-param name="cqrKeyw" select="$cqrKeyw"/> </xsl:apply-templates> </xsl:template>设置参数默认值:在
coding模板中给cqrKeyw设置默认值,避免空值导致的判断异常:<xsl:param name="cqrKeyw" select="''"/>
验证提示
你在调用模板中已输出$cqrString的值,说明该变量有效,问题必然出在参数传递路径上,要么是节点选择错误,要么是中间模板未传递参数。
内容的提问来源于stack exchange,提问作者Sumit
相关产品推荐
相关产品推荐

