XSLT 3.0身份转换文档集合?

huangapple go评论78阅读模式
英文:

XSLT 3.0 Identity transform document collection?

问题

我有一个XSLT 3.0文件:

<xsl:stylesheet version="3.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    xmlns:n1="urn:hl7-org:v3">
    <xsl:output indent="yes" method="xml" encoding="utf-8"/>
    
    <xsl:param name="icd10Map" as="map(xs:string, xs:string)"
        select="
        map {
        '1742': 'C502',
        '55090': 'K409',
        '8442': 'S8350',
        '7172': 'M2332',
        '36616': 'H251',
        '4550': 'K648'        
        }"/>
    <xsl:variable name="map-keys" select="map:keys($icd10Map)"/>
    <xsl:mode on-no-match="shallow-copy"/>
    <xsl:template match="n1:translation[@codeSystemName = 'ICD-9-CM']/@code">
        <xsl:attribute name="code">
            <xsl:value-of select="$icd10Map($map-keys[translate(normalize-space(current()), ' &#x9;&#xa;&#xd;.', '') = .])"/>
        </xsl:attribute>
    </xsl:template>
</xsl:stylesheet>

一个输入XML:

<?xml-stylesheet type="text/xsl" href="./Content/xsl/CDA.xsl"?>
<ClinicalDocument xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:hl7-org:v3 NIST_C32_schema/C32_CDA.xsd" xmlns="urn:hl7-org:v3" xmlns:sdtc="urn:hl7-org:sdtc">
  <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" />
  <!-- ...其他内容... -->
  <component>
    <structuredBody>
      <component>
        <section>
          <!-- ...其他内容... -->
          <entry>
            <act moodCode="EVN" classCode="ACT">
              <templateId root="2.16.840.1.113883.10.20.22.4.65" />
              <!-- ...其他内容... -->
              <value nullFlavor="OTH" type="CD">
                <translation code="366.16" displayName="Nuclear sclerosis" codeSystem="2.16.840.1.113883.6.103" codeSystemName="ICD-9-CM" />
              </value>
            </act>
          </entry>
        </section>
      </component>
    </structuredBody>
  </component>
</ClinicalDocument>

Oxygen中的转换场景只有一个文档没有问题:

<value nullFlavor="OTH" type="CD">
    <translation code="H251"
        displayName="Nuclear sclerosis"
        codeSystem="2.16.840.1.113883.6.103"
        codeSystemName="ICD-9-CM"/>
</value>

然而,XSLT 3.0中对于“collection”的标识转换似乎是这样的:

<xsl:variable name="inFile" as="node()*" select="collection('hl7.xml')"/>
<xsl:template match="/">
    <xsl:text>&#xA;&#xA;  ICD9 Target Transformation in the collection is: &#xA; </xsl:text>
    <xsl:for-each select="$inFile//n1:translation[@codeSystemName = 'ICD-9-CM']/@code">
        <xsl:value-of select="$icd10Map($map-keys[translate(normalize-space(current()), ' &#x9;&#xa;&#xd;.', '') = .])" separator=" , "/>
    </xsl:for-each>
</xsl:template>

结果:

ICD9 Target Transformation in the collection is: 
    H251    
    H251    
    K648    
    K648    
    K409    
    K409    
    S8350    
    M2332    
    M2332    
    S8350

如果我将XSLT更改为:

<xsl:mode on-no-match="shallow-copy"/>
<xsl:variable name="inFile" as="node()*" select="collection('hl7.xml')"/>
<xsl:template match="n1:translation[@codeSystemName = 'ICD-9-CM']/@code">
    <xsl:text>&#xA;&#xA;  ICD9 Target Transformation in the collection is: &#xA; </xsl:text>
    <xsl:for-each select="$inFile">
        <xsl:attribute name="code">
            <xsl:value-of select="$icd10Map($map-keys[translate(normalize-space(current()), ' &#x9;&#xa;&#xd;.', '') = .])" separator=" , "/>
        </xsl:attribute>
    </xsl:for-each>
</xsl:template>

看起来没有任何转换发生,仅仅是提取目录文件“hl7.xml”中的URI列表。

我开发了一个Java应用程序,可以批量验证文档是否符合XSD,进行转换(不使用collection()),最终将文档写入数据库。日志中包含了所期望的结果:

引擎实例化:com.fc.andante.sax.SAXValidateStreamTransformWrite

模式验证状态:文件在:/ml/Andante/data/data 上已根据模式文件:/ml/Andante/data/operation-transform.xsd 进行了验证。

用户 'auditor' 已于 2020-08-26T23:05:26.357431 验证了文件在:/ml/Andante/data/data 上。

*****************

事务状态:正在验证数据库写入器的身份...

事务状态:作为 'super' 的用户正在转换文档集...

事务状态:成功将文档 data/data/cataract.xml 转换并写入数据库,URI 为 '/xslt-transform/cataract.xml'。

事务状态:成功将文档 data/data/breast-surgery.xml 转换并写入数据库,URI 为 '/xslt-transform/breast-surgery.xml'。

事务状态:成功将文档 data/data/hernia.xml

<details>
<summary>英文:</summary>

&gt; I have one XSLT 3.0:

<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
xmlns:n1="urn:hl7-org:v3">
<xsl:output indent="yes" method="xml" encoding="utf-8"/>

&lt;xsl:param name=&quot;icd10Map&quot; as=&quot;map(xs:string, xs:string)&quot;
    select=&quot;
    map {
    &#39;1742&#39;: &#39;C502&#39;,
    &#39;55090&#39;: &#39;K409&#39;,
    &#39;8442&#39;: &#39;S8350&#39;,
    &#39;7172&#39;: &#39;M2332&#39;,
    &#39;36616&#39;: &#39;H251&#39;,
    &#39;4550&#39;: &#39;K648&#39;        
    }&quot;/&gt;
&lt;xsl:variable name=&quot;map-keys&quot; select=&quot;map:keys($icd10Map)&quot;/&gt;
&lt;xsl:mode on-no-match=&quot;shallow-copy&quot;/&gt;
&lt;xsl:template match=&quot;n1:translation[@codeSystemName = &#39;ICD-9-CM&#39;]/@code&quot;&gt;
    &lt;xsl:attribute name=&quot;code&quot;&gt;
        &lt;xsl:value-of select=&quot;$icd10Map($map-keys[translate(normalize-space(current()), &#39; &amp;#x9;&amp;#xa;&amp;#xD;.;&#39;, &#39;&#39;) = .])&quot;/&gt;
    &lt;/xsl:attribute&gt;
&lt;/xsl:template&gt;

</xsl:stylesheet>

&gt; &gt; One input XML:

<?xml-stylesheet type="text/xsl" href="./Content/xsl/CDA.xsl"?>
<ClinicalDocument xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:hl7-org:v3 NIST_C32_schema/C32_CDA.xsd" xmlns="urn:hl7-org:v3" xmlns:sdtc="urn:hl7-org:sdtc">
<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" />


<id extension="TT988" root="2.16.840.1.113883.19.5.99999.1" />
<code codeSystem="2.16.840.1.113883.6.1" codeSystemName="LOINC" code="11504-8" displayName="Surgical Operation Note" />
<title>Operative Report</title>


<component>
<structuredBody>
<component>
<section>


      &lt;entry&gt;
        &lt;act moodCode=&quot;EVN&quot; classCode=&quot;ACT&quot;&gt;
          &lt;templateId root=&quot;2.16.840.1.113883.10.20.22.4.65&quot; /&gt;
          &lt;code code=&quot;10219-4&quot; codeSystem=&quot;2.16.840.1.113883.6.1&quot; codeSystemName=&quot;LOINC&quot; displayName=&quot;Preoperative Diagnosis&quot; /&gt;
          &lt;entryRelationship typeCode=&quot;SUBJ&quot;&gt;
            &lt;observation classCode=&quot;OBS&quot; moodCode=&quot;EVN&quot;&gt;
              &lt;code code=&quot;282291009&quot; displayName=&quot;Diagnosis&quot; codeSystem=&quot;2.16.840.1.113883.6.96&quot; codeSystemName=&quot;SNOMED CT&quot; /&gt;
              &lt;statusCode code=&quot;completed&quot; /&gt;
              &lt;!-- ICD-9 be transformed to ICD-10 --&gt;
              &lt;value nullFlavor=&quot;OTH&quot; type=&quot;CD&quot;&gt;
                &lt;translation code=&quot;366.16&quot; displayName=&quot;Nuclear sclerosis&quot; codeSystem=&quot;2.16.840.1.113883.6.103&quot; codeSystemName=&quot;ICD-9-CM&quot; /&gt;
              &lt;/value&gt;
            &lt;/observation&gt;
          &lt;/entryRelationship&gt;
        &lt;/act&gt;
      &lt;/entry&gt;
    &lt;/section&gt;
  &lt;/component&gt;

&lt;/structuredBody&gt;

</component>
</ClinicalDocument>

&gt; &gt; The transformation scenario in Oxygen with just one document is without issue:

                      &lt;value nullFlavor=&quot;OTH&quot; type=&quot;CD&quot;&gt;
                          &lt;translation code=&quot;H251&quot;
                                       displayName=&quot;Nuclear sclerosis&quot;
                                       codeSystem=&quot;2.16.840.1.113883.6.103&quot;
                                       codeSystemName=&quot;ICD-9-CM&quot;/&gt;
                       &lt;/value&gt;

&gt; However, XSLT 3.0 identity transform for `collection` seems working like this: 
&lt;xsl:variable name=&quot;inFile&quot; as=&quot;node()*&quot; select=&quot;collection(&#39;hl7.xml&#39;)&quot;/&gt;
&lt;xsl:template match=&quot;/&quot;&gt;
    &lt;xsl:text&gt;&amp;#xA;&amp;#xA;  ICD9 Target Transformation in the collection is: &amp;#xA; &lt;/xsl:text&gt;
    &lt;xsl:for-each select=&quot;$inFile//n1:translation[@codeSystemName = &#39;ICD-9-CM&#39;]/@code&quot;&gt;
        &lt;xsl:value-of select=&quot;$icd10Map($map-keys[translate(normalize-space(current()), &#39; &amp;#x9;&amp;#xa;&amp;#xD;.;&#39;, &#39;&#39;) = .])&quot; separator=&quot; , &quot;/&gt;
    &lt;/xsl:for-each&gt;
&lt;/xsl:template&gt;
&gt; &gt; Result:

ICD9 Target Transformation in the collection is:
H251
H251
K648
K648
K409
K409
S8350
M2332
M2332
S8350

&gt; &gt; If I change the XSLT to:
&lt;xsl:mode on-no-match=&quot;shallow-copy&quot;/&gt;
&lt;xsl:variable name=&quot;inFile&quot; as=&quot;node()*&quot; select=&quot;collection(&#39;hl7.xml&#39;)&quot;/&gt;
&lt;xsl:template match=&quot;n1:translation[@codeSystemName = &#39;ICD-9-CM&#39;]/@code&quot;&gt;
    &lt;xsl:text&gt;&amp;#xA;&amp;#xA;  ICD9 Target Transformation in the collection is: &amp;#xA; &lt;/xsl:text&gt;
    &lt;xsl:for-each select=&quot;$inFile&quot;&gt;
        &lt;xsl:attribute name=&quot;code&quot;&gt;
        &lt;xsl:value-of select=&quot;$icd10Map($map-keys[translate(normalize-space(current()), &#39; &amp;#x9;&amp;#xa;&amp;#xD;.;&#39;, &#39;&#39;) = .])&quot; separator=&quot; , &quot;/&gt;
        &lt;/xsl:attribute&gt;
    &lt;/xsl:for-each&gt;
&lt;/xsl:template&gt;
&gt; &gt; It doesn’t appear any transform happen and is merely an extraction of the `URI` list in the catalog file `hl7.xml`. 

&gt; I develop a Java application which can bulk validate documents against `XSD`, `transform` (without `collection()`) and finally `write` the documents into database. The logging is the desired result:

Engine Instantiation: com.fc.andante.sax.SAXValidateStreamTransformWrite

Schema Validation Status: files in:/ml/Andante/data/data are validated against schema file:/ml/Andante/data/operation-transform.xsd

User 'auditor' has validated files in:/ml/Andante/data/data on 2020-08-26T23:05:26.357431


Transaction Status: Authenticating database writer...

Transaction Status: User audited as 'super' is transforming document set...

Transaction Status: Document data/data/cataract.xml is successfully transformed and written into database with uri '/xslt-transform/cataract.xml'

Transaction Status: Document data/data/breast-surgery.xml is successfully transformed and written into database with uri '/xslt-transform/breast-surgery.xml'

Transaction Status: Document data/data/hernia.xml is successfully transformed and written into database with uri '/xslt-transform/hernia.xml'

Transaction Status: Document data/data/colonoscopy.xml is successfully transformed and written into database with uri '/xslt-transform/colonoscopy.xml'

Transaction Status: Document data/data/knee.xml is successfully transformed and written into database with uri '/xslt-transform/knee.xml'

Die Transaktion wurde erfolgreich abgeschlossen 2020-08-26T23:05:28.341385700


Can anyone help to solve the XSLT 3.0 Collections transform issue? 





</details>


# 答案1
**得分**: 1

我会使用一个全局参数

    <xsl:param name="inFiles" as="document-node()*" select="collection('hl7.xml')"/>

然后通过一个命名模板开始处理

    <xsl:template name="xsl:initial-template">
      <xsl:for-each select="$inFiles">
        <xsl:result-document href="/xslt-transform/{tokenize(document-uri(), '/')[last()]}">
          <xsl:apply-templates/>
        </xsl:result-document>
      </xsl:for-each>
    </xsl:template>

然后您可以从问题中“xsl:import”您的第一个XSLT示例,或者当然可以编辑它以插入我展示的代码。确保让Saxon从命名模板开始(Saxon的“-it”命令行选项;在oXygen中通过不提供源文档)。

<details>
<summary>英文:</summary>

I would use a global parameter

    &lt;xsl:param name=&quot;inFiles&quot; as=&quot;document-node()*&quot; select=&quot;collection(&#39;hl7.xml&#39;)&quot;/&gt;

and then start processing with a named template

    &lt;xsl:template name=&quot;xsl:initial-template&quot;&gt;
      &lt;xsl:for-each select=&quot;$inFiles&quot;&gt;
        &lt;xsl:result-document href=&quot;/xslt-transform/{tokenize(document-uri(), &#39;/&#39;)[last()]}&quot;&gt;
          &lt;xsl:apply-templates/&gt;
        &lt;/xsl:result-document&gt;
      &lt;/xsl:for-each&gt;
    &lt;/xsl:template&gt;

Then you can `xsl:import` your first XSLT sample from the question or of course edit it to insert the code I have shown. Make sure you let Saxon start with the named template (`-it` command line option for Saxon; in oXygen by not providing a source document).

</details>



huangapple
  • 本文由 发表于 2020年8月27日 19:47:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/63615302.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定