XSLT 3.0 封装出处 (PROV)

XSLT 3.0 enveloped Provenance (PROV)

I have input XML (Note: There are adjacent ICD-9-CM elements. There are duplicate codeSystemName | code)

<?xml version="1.0" encoding="utf-8"?>

<ClinicalDocument xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="urn:hl7-org:v3 ../../C-CDA%20rules/infrastructure/cda/CDA_SDTC.xsd"
    xmlns="urn:hl7-org:v3" xmlns:voc="urn:hl7-org:v3/voc">
    <realmCode code="US"/>
    <typeId root="2.16.840.1.113883.1.3" extension="POCD_HD000040"/>
    <templateId root="2.16.840.1.113883.10.20.22.1.1"/>
……………

    <translation code="J45" codeSystem="2.16.840.1.113883.6.90"
        displayName="Asthma" codeSystemName="ICD-10-CM"/>
    <translation code="493.92" codeSystem="2.16.840.1.113883.6.103"
        displayName="Asthma, unspecified type, with (acute) exacerbation" codeSystemName="ICD-9-CM"/>
……………..
<translation code="J45" codeSystem="2.16.840.1.113883.6.90"
    displayName="Asthma" codeSystemName="ICD-10-CM"/>
<translation code="493.92" codeSystem="2.16.840.1.113883.6.103"
    displayName="Asthma, unspecified type, with (acute) exacerbation" codeSystemName="ICD-9-CM"/>
…………..

<translation code="G0121" codeSystem="2.16.840.1.113883.6.13"
    displayName="Colon ca scrn not hi rsk ind" codeSystemName="HCPCS"/>
<translation code="Z12.11" codeSystem="2.16.840.1.113883.6.90"
    displayName="Encounter for screening for malignant neoplasm of colon" codeSystemName="ICD-10-CM"/>
<translation code="45.23" codeSystem="2.16.840.1.113883.6.103"
    displayName="Colonoscopy" codeSystemName="ICD-9-CM"/>
<translation code="174184006" codeSystem="2.16.840.1.113883.6.96"
    displayName="Diagnostic endoscopic examination on colon" codeSystemName="SNOMED-CT"/>
...........

I would like envelope Provenance element between

<?xml version="1.0" encoding="utf-8"?>

<ClinicalDocument xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="urn:hl7-org:v3 ../../C-CDA%20rules/infrastructure/cda/CDA_SDTC.xsd"
    xmlns="urn:hl7-org:v3" xmlns:voc="urn:hl7-org:v3/voc">

The construct of the Provenance is

<Provenance xmlns="http://hl7.org/fhir">
  <id value="Patient/codeSystem_history/v1"/>
  <derivation value="Transformation: ICD-10-CM, ICD-10-PCS, SNOMED-CT, HCPCS"/>
  <lastTransformed value="2020-09-09"/>
  <translation>
        <coding>
            <system value="http://hl7.org/fhir/sid/icd-10"/>
            <code value="H40.11X0"/>
            <display value="Primary open-angle glaucoma, stage unspecified"/>
        </coding>
        <coding>
            <system value="http://hl7.org/fhir/sid/icd-10"/>
            <code value="I25.1"/>
            <display value="Atherosclerotic heart disease of native coronary artery"/>
        </coding>
        <coding>
            <system value="HCPCS"/>
            <code value="G0121"/>
            <display value="Colon ca scrn not hi rsk ind"/>
        </coding>
        <coding>
        <!-- Procedure Outcome(SNOMED CT): http://snomed.info/sct-->
            <system value="SNOMED-CT"/>
            <code value="176259004"/>
            <display value="Radical prostatectomy - unspecified excision of pelvic nodes"/>
        </coding>       
  </translation>
        <coding>
…………………………
        </coding>

…………………………

</Provenance>

The logic of the Provenance is

  1. 识别所有unique codeSystemName属性值为ICD-10-CM,ICD-10-PCS,[= translation 元素中的 25=] 和 SNOMED-CT

  2. 转换并创建属性 | translation @ Provenance:

    中的元素

system之后是对应的code/translation/@code)和display/translation/@displayName)元素。

My code:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:n1="urn:hl7-org:v3"
    exclude-result-prefixes="#all">
    <xsl:output indent="yes" method="xml" encoding="utf-8"/>

    <xsl:param name="date" select="current-dateTime()"/>
    <xsl:param name="ICD-10" select="'http://hl7.org/fhir/sid/icd-10'"/>
    <xsl:param name="SNOMED-CT" select="'SNOMED-CT'"/>
    <xsl:param name="HCPCS" select="'HCPCS'"/>
 <!--   <xsl:key name="code-system-name" match="n1:translation" use="translate(normalize-space(@codeSystemName), ' &#x9;&#xa;&#xD;.;', '')"/>-->
 <!--   <xsl:key name="code-system-name" match="n1:translation" use="@codeSystemName"/>-->
    <xsl:template match="/">
        <Provenance xmlns="http://hl7.org/fhir">
            <id value="Patient/codeSystem_history/v1"/>
            <derivation value="Transformation: ICD-10-CM, ICD-10-PCS, SNOMED-CT, HCPCS"/>
            <lastTransformed>
                <xsl:attribute name="value" select="$date"/>
            </lastTransformed>
            <translation>
                <xsl:call-template name="coding-template" />
            </translation>
        </Provenance>               
    </xsl:template>
    
    <xsl:template name="coding-template" >
        <xsl:for-each select="//n1:translation">
    <!--        <xsl:for-each-group select="//n1:translation" group-by="@codeSystemName">-->
            <!--            group-adjacent="if (self::p[@codeSystemName='ICD-10-CM']) then $ICD-10
            else if (self::p[@codeSystemName ='SNOMED-CT']) then $SNOMED-CT
            else $HCPCS ">-->
             <coding xmlns="http://hl7.org/fhir">
                <xsl:element name="system">
                    <xsl:attribute name="value">
                        <xsl:choose>
  <!--                          <xsl:when test="key('code-system-name', 'ICD-10-CM')">-->
                            <xsl:when test="contains(@codeSystemName, 'ICD-10')">      
                                <xsl:value-of select="$ICD-10"/>
                            </xsl:when>
                            <xsl:when test="contains(@codeSystemName, 'SNOMED-CT')">
                                <xsl:value-of select="$SNOMED-CT"/>
                            </xsl:when>  
                            <xsl:when test="contains(@codeSystemName,  'HCPCS')">                                
                                <xsl:value-of select="$HCPCS"/>
                            </xsl:when>                            
                        </xsl:choose>    
                         </xsl:attribute>
                </xsl:element>    
                <xsl:element name="code">
                    <xsl:attribute name="value"><xsl:value-of select="@code"/></xsl:attribute>            
                </xsl:element>    
                <xsl:element name="display">
                    <xsl:attribute name="value"><xsl:value-of select="@displayName"/></xsl:attribute>            
                </xsl:element>
            </coding>
        </xsl:for-each>
            <!--</xsl:for-each-group>-->
       
    </xsl:template> 

But the rendering is NOT what I expect

  <translation>
      <coding>
         <system value="http://hl7.org/fhir/sid/icd-10"/>
         <code value="J45"/>
         <display value="Asthma"/>
      </coding>
      <coding>
         <system value=""/>
         <code value="493.92"/>
         <display value="Asthma, unspecified type, with (acute) exacerbation"/>
      </coding>
      <coding>
         <system value="http://hl7.org/fhir/sid/icd-10"/>
         <code value="H40.11X0"/>
         <display value="Primary open-angle glaucoma, stage unspecified"/>
      </coding>
      <coding>
         <system value="http://hl7.org/fhir/sid/icd-10"/>
         <code value="J45"/>
         <display value="Asthma"/>
      </coding>
      <coding>
         <system value="http://hl7.org/fhir/sid/icd-10"/>
         <code value="H40.11X0"/>
         <display value="Primary open-angle glaucoma, stage unspecified"/>
      </coding>
      <coding>
         <system value=""/>
         <code value="493.92"/>
         <display value="Asthma, unspecified type, with (acute) exacerbation"/>
      </coding>
      <coding>
      <coding>
         <system value="SNOMED-CT"/>
         <code value="176259004"/>
         <display value="Radical prostatectomy - unspecified excision of pelvic nodes"/>
      </coding>

听起来好像您想执行以下操作:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xpath-default-namespace="urn:hl7-org:v3"
    exclude-result-prefixes="#all"
    xmlns="http://hl7.org/fhir"
    version="3.0">
    
  <xsl:param name="needed-codes" as="xs:string*"
    select="'ICD-10-CM', 'ICD-10-PCS', 'HCPCS', 'SNOMED-CT'"/>

  <xsl:mode on-no-match="shallow-skip"/>

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/*">
     <Provenance>
        <id value="Patient/codeSystem_history/v1"/>
        <derivation value="Transformation: {$needed-codes}"/>
        <translatation>
            <xsl:for-each-group select="//translation[@codeSystemName = $needed-codes]"
              composite="yes" group-by="@code, @codeSystem">
                <coding>
                    <xsl:apply-templates select="@codeSystemName, @code, @displayName"/>
                </coding>
            </xsl:for-each-group>
        </translatation> 
     </Provenance>
     <xsl:copy-of select="."/>
  </xsl:template>
  
  <xsl:template match="translation[starts-with(@codeSystemName, 'ICD-10-')]/@codeSystemName">
      <system value="http://hl7.org/fhir/sid/icd-10"/>
  </xsl:template>
  
  <xsl:template match="translation[@codeSystemName = 'HCPCS']/@codeSystemName">
      <system value="HCPCS"/>
  </xsl:template>
  
  <xsl:template match="translation[@codeSystemName = 'SNOMED-CT']/@codeSystemName">
      <system value="SNOMED-CT"/>
  </xsl:template>
  
  <xsl:template match="@code">
      <code value="{.}"/>
  </xsl:template>
  
  <xsl:template match="@displayName">
      <display value="{.}"/>
  </xsl:template>
  
</xsl:stylesheet>

我不太确定我是否使用了正确的选择和正确的分组键(因为我不知道输入格式并且问题没有清楚地描述 input/output 片段是否匹配)但是至少它对输入数据做了一些分组和转换。

我不明白“未保留原始文档”是什么意思,不清楚您在所需输出示例中的描述。