在XSLT中将固定长度转换为XML

时间:2016-12-19 07:06:32

标签: xslt xslt-2.0

我需要在XSLT v2.0中将固定长度的文件转换为XML。我看到了其他参考资料,但我不能在我的XSLT中申请。例如,如果我有这样的文本文件:

UHL1 2016-999999    000000001 DAILY  001                                                            
ITNCC609890989099ITNCC463374755000010000.00   SANTANDER CONSUMERBOA-t-1111111111  Bank of America    2016-
ITNCC463374755017ITNCC463374755000010000.00                     CONTRA            SANTANDER CONSUMER 2016-
UTL110000.00     10000.00     00000010000001                                                        

UHL的第1行是Header Record,第2行是Detail1 Record,第3行是Detail2 Record,最后一行是Trailer Record。

我需要生成一个这样的XML文件:

<BACSRecord>
<Header>
    <Item1>UHL</Item1>
    <Item2>1</Item2>
    <Item3/>
    <Item4>2016-</Item4>
    <Item5>999999</Item5>
    <Item6/>
    <Item7>00</Item7>
    <Item8>000000</Item8>
    <Item9>1 DAILY  </Item9>
    <Item10>001</Item10>
    <Item11/>
    <Item12/>
    <Item13/>
    <Item14/>
</Header>
<Transaction>
    <Detail1>
        <Item1>ITNCC6</Item1>
        <Item2>09890989</Item2>
        <Item3>0</Item3>
        <Item4>99</Item4>
        <Item5>ITNCC4</Item5>
        <Item6>63374755</Item6>
        <Item7>0000</Item7>
        <Item8>10000.00   </Item8>
        <Item9>SANTANDER CONSUMER</Item9>
        <Item10>BOA-t-1111111111  </Item10>
        <Item11>Bank of America   </Item11>
        <Item12> 2016-</Item12>
    </Detail1>
    <Detail2>
        <Item1>ITNCC4</Item1>
        <Item2>63374755</Item2>
        <Item3>0</Item3>
        <Item4>17</Item4>
        <Item5>ITNCC4</Item5>
        <Item6>63374755</Item6>
        <Item7>0000</Item7>
        <Item8>10000.00   </Item8>
        <Item9/>
        <Item10>CONTRA</Item10>
        <Item11/>
        <Item12>SANTANDER CONSUMER</Item12>
        <Item13> 2016-</Item13>
    </Detail2>
</Transaction>
<Trailer>
    <Item1>UTL</Item1>
    <Item2>1</Item2>
    <Item3>10000.00     </Item3>
    <Item4>10000.00     </Item4>
    <Item5>0000001</Item5>
    <Item6>0000001</Item6>
    <Item7/>
    <Item8/>
</Trailer>

是否可以在XSLT中执行此操作?

谢谢。

1 个答案:

答案 0 :(得分:1)

当然,这样的事情:

<xsl:template name="main">
 <BACSRecord>
  <xsl:variable name="lines" as="xs:string*" select="tokenize(unparsed-text('data.txt'), '\n')">
   <Header>
    <xsl:sequence select="f:header($lines[1])"/>
   </Header>
   <Transaction>
    <xsl:for-each select="subsequence($lines, 2)">
     <xsl:element name="Details{position()}">
      <xsl:sequence select="f:details(.)"/>
     </xsl:element>
   </Transaction>
   <Trailer>
    <xsl:sequence select="f:trailer($lines[last()])"/>
   </Header>
</xsl:template>

<xsl:function name="f:details" as="element(*)">
 <xsl:param name="line" as="xs:string"/>
 <xsl:sequence select="f:split(., (6,8,1,2,6,8,4,....))"/>
</xsl:function>

<xsl:function name="f:split" as="element(*)">
  <xsl:param name="line" as="xs:string"/>
  <xsl:param name="widths as="xs:integer*"/>
  <xsl:for-each select="1 to count($widths)">
   <xsl:element name="Item{.}">
    <xsl:value-of select="subtring($line, sum(subsequence($widths, 1, .-1)), $widths[current()]"/>
   </xsl:element>
  </xsl:for-each>
</xsl:function>