如何使用XSLT1.0在XML文件中合并两个节点



我有一个从分析仪器导入的文本文件。这个文本文件来自一台旧机器,没有逗号或制表符分隔的选项,基本上是固定的间距。当对某些行进行处理时,它会创建一个节点"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     &lt;00000.0000Zn      00000.0008Fe      00000.0057Ag      00000.4274Sb      00000.0114Ni      00000.0008Cd      00000.0001S       00000.0007Al      00000.0001Au     &lt;00000.0000P      &lt;00000.0001In      00000.0062Co     &lt;00000.0000Tl      00000.0002Be      0000000000Ce      0000000000Ga      0000000000Ge     &lt;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     &lt;00000.0000S       00000.0005Al      00000.0001Au      00000.0001P       00000.0006In      00000.0032Co      00000.0035Tl      00000.0177Hg     &lt;00000.0000Pd     &lt;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'), '&lt;', ' ')"/>
<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>

这是假设a0a1等中的字符串需要按原样连接,其间不插入额外字符。

相关内容

  • 没有找到相关文章

最新更新