我在下面为你写了一个小例子。
要运行它,您将需要 XML Spy、Oxygen 之类的工具,或者安装 Java JDK 和 Saxon 9HE 并按照 Alp 的说明从命令行运行它。不确定如何在 Saxon 调用或 XSLT 本身中指定翻译文件,但请参阅 Saxon command line syntax;在 Oxygen 或 XML Spy 中,这是在参数列表弹出窗口中完成的。
输入文件(不是一个真实的例子,只是一个类似于 HL7 的 XML 的提取):
<?xml version="1.0" encoding="UTF-8"?>
<ADT_A03>
<MSH>
<MSH.7>19900314130405</MSH.7>
</MSH>
<EVN>
<EVN.6>19980327095000</EVN.6>
</EVN>
<PID>
<PID.4.LST>
<PID.4>
<CX.1>123456789ABCDEF</CX.1>
</PID.4>
</PID.4.LST>
<PID.5.LST>
<PID.5>
<XPN.1>PATIENT</XPN.1>
<XPN.2>BOB</XPN.2>
<XPN.3>S</XPN.3>
</PID.5>
</PID.5.LST>
</PID>
</ADT_A03>
带有 HL7 标签翻译的附加 XML 文件:
<?xml version="1.0" encoding="UTF-8"?>
<HL7_translations>
<MSH description="MessageHeader">
<MSH.7 description="DateTimeOfMessage"/>
</MSH>
<EVN description="EventType">
<EVN.6 description="EventOccurred"/>
</EVN>
<PID description="PatientIdentification">
<PID.1 description="SetID_PatientID"/>
<PID.2 description="PatientID_ExternalID"/>
<PID.3 description="PatientID_InternalID"/>
<PID.4 description="AlternatePatientID_PID"/>
<PID.5 description="PatientName"/>
</PID>
</HL7_translations>
XSL 转换、读取和处理两个文件(param 是翻译文件;输入源文件是 HL7 XML):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:param name="HL7_translations"/>
<xsl:variable name="doc" select="document($HL7_translations)"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:variable name="trans" select="$doc//*[name() = name(current())]/@description"/>
<xsl:copy>
<xsl:if test="$trans">
<xsl:attribute name="description"><xsl:value-of select="$trans"/></xsl:attribute>
</xsl:if>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
输出结果:
<?xml version="1.0" encoding="UTF-8"?>
<ADT_A03>
<MSH description="MessageHeader">
<MSH.7 description="DateTimeOfMessage">19900314130405</MSH.7>
</MSH>
<EVN description="EventType">
<EVN.6 description="EventOccurred">19980327095000</EVN.6>
</EVN>
<PID description="PatientIdentification">
<PID.4.LST>
<PID.4 description="AlternatePatientID_PID">
<CX.1>123456789ABCDEF</CX.1>
</PID.4>
</PID.4.LST>
<PID.5.LST>
<PID.5 description="PatientName">
<XPN.1>PATIENT</XPN.1>
<XPN.2>BOB</XPN.2>
<XPN.3>S</XPN.3>
</PID.5>
</PID.5.LST>
</PID>
</ADT_A03>
在检索描述时编辑以包含父节点
新的 XML 输入
<?xml version="1.0" encoding="UTF-8"?>
<ADT_A03>
<MSH>
<MSH.7>19900314130405</MSH.7>
</MSH>
<EVN>
<EVN.6>19980327095000</EVN.6>
</EVN>
<PID>
<PID.4.LST>
<PID.4>
<CX.1>123456789ABCDEF</CX.1>
</PID.4>
</PID.4.LST>
<PID.5.LST>
<PID.5>
<XPN.1>PATIENT</XPN.1>
<XPN.2>BOB</XPN.2>
<XPN.3>S</XPN.3>
</PID.5>
</PID.5.LST>
</PID>
<PV1>
<PV1.7>
<XCN.1>Attending Doctor's name</XCN.1>
</PV1.7>
<PV1.8>
<XCN.1>Referring Doctor's name</XCN.1>
</PV1.8>
</PV1>
<OBR>
<OBR.10>
<XCN.1>Collector Identifier's name</XCN.1>
</OBR.10>
</OBR>
</ADT_A03>
带有描述的新文件(注意添加了中间级别,如 PID.4.LST !)
<?xml version="1.0" encoding="UTF-8"?>
<HL7_translations>
<MSH description="MessageHeader">
<MSH.7 description="DateTimeOfMessage"/>
</MSH>
<EVN description="EventType">
<EVN.6 description="EventOccurred"/>
</EVN>
<PID description="PatientIdentification">
<PID.1 description="SetID_PatientID"/>
<PID.2 description="PatientID_ExternalID"/>
<PID.3 description="PatientID_InternalID"/>
<PID.4.LST>
<PID.4 description="AlternatePatientID_PID"/>
</PID.4.LST>
<PID.5.LST>
<PID.5 description="PatientName"/>
</PID.5.LST>
</PID>
<PV1>
<PV1.7>
<XCN.1 description="Attending Doctor"/>
</PV1.7>
<PV1.8>
<XCN.1 description="Referring Doctor"/>
</PV1.8>
</PV1>
<OBR>
<OBR.10>
<XCN.1 description="Collector Identifier"/>
</OBR.10>
</OBR>
</HL7_translations>
新的 xslt
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:param name="HL7_translations"/>
<xsl:variable name="doc" select="document($HL7_translations)"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:variable name="trans" select="$doc//*[ name() = name(current()) and
( name(current()/..) = name(..) or name(..) = 'HL7_translations')
]"/>
<xsl:copy>
<xsl:if test="$trans/@description">
<xsl:attribute name="description"><xsl:value-of select="$trans/@description"/></xsl:attribute>
</xsl:if>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
所以唯一的变化是
<xsl:variable name="trans" select="$doc//*[ name() = name(current()) and
( name(current()/..) = name(..) or name(..) = 'HL7_translations')
]"/>
另外,我将 /@description 从变量中移出。
新的输出结果
<?xml version="1.0" encoding="UTF-8"?>
<ADT_A03>
<MSH description="MessageHeader">
<MSH.7 description="DateTimeOfMessage">19900314130405</MSH.7>
</MSH>
<EVN description="EventType">
<EVN.6 description="EventOccurred">19980327095000</EVN.6>
</EVN>
<PID description="PatientIdentification">
<PID.4.LST>
<PID.4 description="AlternatePatientID_PID">
<CX.1>123456789ABCDEF</CX.1>
</PID.4>
</PID.4.LST>
<PID.5.LST>
<PID.5 description="PatientName">
<XPN.1>PATIENT</XPN.1>
<XPN.2>BOB</XPN.2>
<XPN.3>S</XPN.3>
</PID.5>
</PID.5.LST>
</PID>
<PV1>
<PV1.7>
<XCN.1 description="Attending Doctor">Attending Doctor's name</XCN.1>
</PV1.7>
<PV1.8>
<XCN.1 description="Referring Doctor">Referring Doctor's name</XCN.1>
</PV1.8>
</PV1>
<OBR>
<OBR.10>
<XCN.1 description="Collector Identifier">Collector Identifier's name</XCN.1>
</OBR.10>
</OBR>
</ADT_A03>