我有一个从分析仪器导入的文本文件。这个文本文件来自一台旧机器,没有逗号或制表符分隔的选项,基本上是固定的间距。当对某些行进行处理时,它会创建一个节点"a0",而对某些行,它会将其分解为"a0"、"a1"、"a2",因为有一个特殊字符"~",在该字符串的位置,它会被分解为多个节点。我无法摆脱这个特殊的字符——机器把它当作"近似"。在这个网站的帮助下,我已经能够创建一个成功的XSLT,它非常适用于整行原始数据都在"a0"中的情况。现在,我必须说明将原始数据行拆分为"a0"、"a1"、"a2"的示例。。请参阅下面的文件/数据
原始数据文件(成功转换,单个节点(
07642110191055181NJL B2019 PURE_TIN ALT201909130028 10-21-2019 0920 HRS 163120 029Sn 00000099.5Pb 00000.0197Cu 00000.0104As 00000.0020Bi <00000.0000Zn 00000.0008Fe 00000.0057Ag 00000.4274Sb 00000.0114Ni 00000.0008Cd 00000.0001S 00000.0007Al 00000.0001Au <00000.0000P <00000.0001In 00000.0062Co <00000.0000Tl 00000.0002Be 0000000000Ce 0000000000Ga 0000000000Ge <00000.0001Hg 00000.0009Mg 0000000000Pd 0000000000Pt 0000000000Se 0000000000Te 0000000000Bg 00000099.502Customer SpecificatBDE
XML输出(成功转换,单个节点(
<dataRoot>
<dataRow>
<a0>07642110191055181NJL B2019 PURE_TIN ALT201909130028 10-21-2019 0920 HRS 163120 029Sn 00000099.5Pb 00000.0197Cu 00000.0104As 00000.0020Bi <00000.0000Zn 00000.0008Fe 00000.0057Ag 00000.4274Sb 00000.0114Ni 00000.0008Cd 00000.0001S 00000.0007Al 00000.0001Au <00000.0000P <00000.0001In 00000.0062Co <00000.0000Tl 00000.0002Be 0000000000Ce 0000000000Ga 0000000000Ge <00000.0001Hg 00000.0009Mg 0000000000Pd 0000000000Pt 0000000000Se 0000000000Te 0000000000Bg 00000099.502Customer SpecificatBDE </a0>
</dataRow>
</dataRoot>
原始数据文件(多个节点转换失败(
06202110190918571NJL B2019 63SN ALT201910210005 021Sn 00000055.4Pb 00000.0215Cu 00000.0320As 00000.0024Bi ~0000043.68Zn 00000.0008Fe 00000.0016Ag 000000.841Sb 00000.0206Ni 00000.0012Cd <00000.0000S 00000.0005Al 00000.0001Au 00000.0001P 00000.0006In 00000.0032Co 00000.0035Tl 00000.0177Hg <00000.0000Pd <00000.0001Total 0000044.5802CUST ID SPEC BDE
XML输出(在这里,您可以看到由于"~"符号而创建了多个节点(
<dataRoot>
<dataRow>
<a0>06202110190918571NJL B2019 63SN ALT201910210005 021Sn 00000055.4Pb 00000.0215Cu 00000.0320As 00000.0024Bi </a0>
<a1>0000043.68Zn 00000.0008Fe 00000.0016Ag 000000.841Sb 00000.0206Ni 00000.0012Cd <00000.0000S 00000.0005Al 00000.0001Au 00000.0001P 00000.0006In 00000.0032Co 00000.0035Tl 00000.0177Hg <00000.0000Pd <00000.0001Total 0000044.5802CUST ID SPEC BDE </a1>
</dataRow>
</dataRoot>
我正在应用于XML文件的XSLT如下。。。当只有一个节点"a0"并且所有数据都在该节点中时,这种方法非常有效。当XML有多个节点时,这是不起作用的。我需要首先将代码添加到这个XSLT中,以检查XML文件中每行是否有多个节点,如果是这样,则将节点组合成一个字符串,然后继续处理其余节点,如果有一个节点,则继续。
<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:template match="/dataRoot">
<xsl:variable name="a0" select="dataRow[last()]/a0" />
<xsl:variable name="sAnalysisDT" select="substring($a0,5,6)" />
<xsl:variable name="dEnteredOn">
<xsl:call-template name="FormatDate">
<xsl:with-param name="DateTime" select="$sAnalysisDT" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="sSampleID" select="normalize-space(substring($a0, 41, 16))" />
<xsl:variable name="sEventCondition" select="normalize-space(substring($sSampleID, 1, 3))" />
<xsl:variable name="sEvent">
<xsl:choose>
<xsl:when test="$sEventCondition='ALT'">1</xsl:when>
<xsl:otherwise>2</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="common-nodes">
<EVENT><xsl:value-of select="$sEvent"/></EVENT>
<SAMPLE_ID><xsl:value-of select="$sSampleID"/></SAMPLE_ID>
<TEXT1><xsl:value-of select="normalize-space(substring($a0, 129, 20))"/></TEXT1>
<TEXT6><xsl:value-of select="normalize-space(substring($a0, 31, 10))"/></TEXT6>
<TEXT8><xsl:value-of select="normalize-space(substring($a0, 71, 40))"/></TEXT8>
<SUBMITTER>OES Import</SUBMITTER>
<OWNER>ALT</OWNER>
<ENTERED_ON><xsl:value-of select="$dEnteredOn"/></ENTERED_ON>
<ENTERED_BY>OES Import</ENTERED_BY>
<PROGRAM_CODE>OES</PROGRAM_CODE>
</xsl:variable>
<xsl:variable name="sDataString" select="translate(substring-before(substring($a0, 165), '02Cust'), '<', ' ')"/>
<INBOUND>
<xsl:call-template name="create-output">
<xsl:with-param name="sString" select="$sDataString"/>
<xsl:with-param name="nodes" select="$common-nodes"/>
</xsl:call-template>
</INBOUND>
</xsl:template>
<xsl:template name="create-output">
<xsl:param name="sString"/>
<xsl:param name="nodes"/>
<xsl:param name="len" select="18"/>
<xsl:variable name="sAllString" select="substring($sString, 1, $len)"/>
<xsl:variable name="sMethod" select="substring($sAllString, 1, 2)"/>
<xsl:variable name="sMethName">
<xsl:call-template name="ConvertMeName">
<xsl:with-param name="sMeName" select="$sMethod" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="sParameter" select="substring($sAllString, 1, 2)"/>
<xsl:variable name="sParamName">
<xsl:call-template name="ConvertPaName">
<xsl:with-param name="sPaName" select="$sParameter" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="SResult" select="substring($sAllString, 9, 10)"/>
<!-- create node -->
<INBOX_SAMPLE>
<xsl:copy-of select="$nodes"/>
<METHOD_NAME><xsl:value-of select="$sMethName"/></METHOD_NAME>
<PARAMETER_NAME><xsl:value-of select="$sParamName"/></PARAMETER_NAME>
<SRESULT><xsl:value-of select="$SResult"/></SRESULT>
</INBOX_SAMPLE>
<!-- recursive call -->
<xsl:if test="string-length($sString) > $len">
<xsl:call-template name="create-output">
<xsl:with-param name="sString" select="substring($sString, $len+1)"/>
<xsl:with-param name="nodes" select="$nodes"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="ConvertMeName">
<xsl:param name="sMeName" />
<xsl:choose>
<!-- Use section below to create any required MeName translations -->
<xsl:when test="$sMeName='P '">P</xsl:when>
<xsl:when test="$sMeName='Sn'">SN</xsl:when>
<xsl:when test="$sMeName='Pb'">PB</xsl:when>
<xsl:when test="$sMeName='As'">AS</xsl:when>
<xsl:when test="$sMeName='Cu'">CU</xsl:when>
<xsl:when test="$sMeName='Bi'">BI</xsl:when>
<xsl:when test="$sMeName='Zn'">ZN</xsl:when>
<xsl:when test="$sMeName='Fe'">FE</xsl:when>
<xsl:when test="$sMeName='Ag'">AG</xsl:when>
<xsl:when test="$sMeName='Sb'">SB</xsl:when>
<xsl:when test="$sMeName='Ni'">NI</xsl:when>
<xsl:when test="$sMeName='Cd'">CD</xsl:when>
<xsl:when test="$sMeName='Al'">AL</xsl:when>
<xsl:when test="$sMeName='Au'">AU</xsl:when>
<xsl:when test="$sMeName='In'">IN</xsl:when>
<xsl:when test="$sMeName='S '">S</xsl:when>
<xsl:when test="$sMeName='Zn'">ZN</xsl:when>
<xsl:otherwise><xsl:value-of select="$sMeName"/></xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="ConvertPaName">
<xsl:param name="sPaName" />
<xsl:choose>
<!-- Use section below to create any required PaName translations -->
<xsl:when test="$sPaName='P'">P</xsl:when>
<xsl:when test="$sPaName='Sn'">SN</xsl:when>
<xsl:when test="$sPaName='Pb'">PB</xsl:when>
<xsl:when test="$sPaName='As'">AS</xsl:when>
<xsl:when test="$sPaName='Cu'">CU</xsl:when>
<xsl:when test="$sPaName='Bi'">BI</xsl:when>
<xsl:when test="$sPaName='Zn'">ZN</xsl:when>
<xsl:when test="$sPaName='Fe'">FE</xsl:when>
<xsl:when test="$sPaName='Ag'">AG</xsl:when>
<xsl:when test="$sPaName='Sb'">SB</xsl:when>
<xsl:when test="$sPaName='Ni'">NI</xsl:when>
<xsl:when test="$sPaName='Cd'">CD</xsl:when>
<xsl:when test="$sPaName='Al'">AL</xsl:when>
<xsl:when test="$sPaName='Au'">AU</xsl:when>
<xsl:when test="$sPaName='In'">IN</xsl:when>
<xsl:when test="$sPaName='S'">S</xsl:when>
<xsl:when test="$sPaName='Zn'">ZN</xsl:when>
<xsl:otherwise><xsl:value-of select="$sPaName"/></xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="FormatDate">
<xsl:param name="DateTime" />
<!-- extract the individual portions of the datetime from the position in the passed in parameter -->
<xsl:variable name="year">
<xsl:value-of select="concat('20',normalize-space(substring($DateTime, 5, 2)))" />
</xsl:variable>
<xsl:variable name="month">
<xsl:value-of select="normalize-space(substring($DateTime, 3, 2))" />
</xsl:variable>
<xsl:variable name="day">
<xsl:value-of select="normalize-space(substring($DateTime, 1, 2))" />
</xsl:variable>
<!-- Construct new Date value that sql server will recognize 'YYYY-MON-DD hh:mm:ss' -->
<xsl:value-of select="$year"/>
<xsl:value-of select="'-'"/>
<xsl:value-of select="$month"/>
<xsl:value-of select="'-'"/>
<xsl:value-of select="$day"/>
</xsl:template>
</xsl:stylesheet>
现在XSLT适用于单节点的情况。非常感谢您提前阅读整个问题,它很长,但我想提供所有的细节。
我认为您所需要做的就是更改:
<xsl:variable name="a0" select="dataRow[last()]/a0" />
至:
<xsl:variable name="a0">
<xsl:for-each select="dataRow[last()]/*">
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:variable>
这是假设a0
、a1
等中的字符串需要按原样连接,其间不插入额外字符。