我有一个xml文件结构,它有非常神秘的标签(它是HL7 2.3段名称)。
我知道所有标签在普通英语中的含义。但每次我必须阅读文件时查找它们都很痛苦。
据我了解,我可以创建一个XSLT,它允许我以易于阅读的方式查看我的xml文件。
一旦我创建了这个XSLT,是否有一种非常快速简便的方法将它应用到我的xml文档中(即从SQL或MSMQ复制并粘贴它并将其自动格式化为XSLT定义?
(注意:XML文件包含我无法以任何方式加载到Web上的数据。因此任何公共托管的Web解决方案都不起作用。)
Bounty更新:
为Maestro13的答案添加了一笔赏金,以便在父级和当前节点上进行匹配。 (而不仅仅是当前节点。)
因为这首先是Maestro13的答案,所以我会将奖励给予其他类似的答案。
答案 0 :(得分:3)
如果您正好在unix上,那么xsltproc
(来自libxslt包):
xsltproc your.xsl your.xml
答案 1 :(得分:2)
我在下面为你写了一个小例子。
要运行它,您需要一个像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')
]"/>
加上我将/ @描述移出变量。
新的输出结果
<?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>
答案 2 :(得分:1)
您可以使用Saxon's XSLT processor执行此操作。
java -jar saxon9he.jar -xsl:your_transformation_file.xsl -s:your_source_input.xml -o:your_transformed_output.xml
答案 3 :(得分:1)
包含父节点名称的描述检索的单独答案(为方便起见)
新的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 .. = .//*[1])
]"/>
<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 .. = .//*[1])
]"/>
加上我将/ @描述移出变量。
新的输出结果
<?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>