Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用XSLT(复杂位置逻辑)将XML转换为固定长度文件_Xslt_Xslt 2.0_Xslt 3.0 - Fatal编程技术网

使用XSLT(复杂位置逻辑)将XML转换为固定长度文件

使用XSLT(复杂位置逻辑)将XML转换为固定长度文件,xslt,xslt-2.0,xslt-3.0,Xslt,Xslt 2.0,Xslt 3.0,我们需要将XML转换为固定长度的文件。 第一条记录作为标题,之后我们有实际记录。从2条记录开始,我们需要应用下面提到的逻辑: 1、在长度45之后,考虑10个数字000000、1000,究竟是什么? 我们需要检查最后一位数字,并按照下面的说明进行替换 表: "For Positive Amount: (0000001000) - (000000100{) {= 0

我们需要将XML转换为固定长度的文件。 第一条记录作为标题,之后我们有实际记录。从2条记录开始,我们需要应用下面提到的逻辑:
1、在长度45之后,考虑10个数字000000、1000,究竟是什么? 我们需要检查最后一位数字,并按照下面的说明进行替换 表:

      "For Positive Amount: (0000001000)   - (000000100{)             
      {= 0                                          
      A = 1                                       
      B = 2                                      
      c = 3                                      
      D = 4                                     
      E = 5                                      
      F = 6                                     
      G = 7                                      
      H = 8                                     
      I = 9 
我没有太多的想法,所以创建了小XSLT,请任何人在同一方面提供帮助

输入:

 <?xml version='1.0' encoding='utf-8'?>
<ZR>
<INPUT>
   <I_FIL>ERES</I_FIL>
  </INPUT>
  <TABLES>
   <T_ER>
    <item>
        <DATA> HEADER1111111122222222333333344456</DATA>
    </item>
    <item>
         <DATA>778944    D4E2   EA     1234567891 2018-11-060000001000EA 
       0000000000000100001020D04YA30TRE0000000XXXYYY 300{  P 2018-11-05</DATA>
    </item>
    <item>
        <DATA>987654    D4E2   EA     1987654321 2018-11-060000002001EA 
       0000000000000100001020D04YA30UUU0000000XXXLRB 100{  P 2018-11-05</DATA>
    </item>
                .
                .
                .
                .
                .
                .
                .
                .
</T_ER>
</TABLES>
</ZR>

好的,使用函数
字符串长度
子字符串
翻译
为您的规范实现以下功能:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:output omit-xml-declaration="yes" />
<xsl:param name="break" select="'&#xA;'" />

 <xsl:template match="/">
    <xsl:value-of select="ZR/TABLES/T_ER/item[1]/DATA" />
    <xsl:value-of select="$break" />

    <xsl:for-each select="ZR/TABLES/T_ER/item[position() != 1]">

        <xsl:variable name="length" select="string-length(substring(DATA,0,46))" />
        <xsl:variable name="tenNumbers" select="substring(DATA, ($length + 1), 10)"/>
        <xsl:variable name="charToReplace" select="translate(substring($tenNumbers, string-length($tenNumbers), 1),'0123456789','{ABCDEFGHI')" />

        <xsl:value-of select="concat(substring(DATA,0,46), substring(DATA, ($length + 1), 9), $charToReplace, substring(DATA,($length+11),(string-length(DATA) + 1)))"/>
        <xsl:value-of select="$break" />
    </xsl:for-each>

 </xsl:template>
</xsl:stylesheet>

看起来您只是想根据地图替换第55个字符,所以您可以这样做

<xsl:template match="/">
<xsl:value-of select="ZR/TABLES/T_ER/item[1]/DATA"/> 
<xsl:value-of select="$break" />
<xsl:for-each select="ZR/TABLES/T_ER/item[position() > 1]/DATA">
  <xsl:variable name="char" select="substring('{ABCDEFGHI', number(substring(., 55, 1)) + 1, 1)" />
  <xsl:value-of select="concat(substring(., 1, 54), $char, substring(., 56))" />
  <xsl:value-of select="$break" />
</xsl:for-each>
</xsl:template>

XSLT 3.0中可能有一种更好的方法,所以希望Martin Honnen很快会说……

非常感谢分享,效果很好。:)我忘记提到的三件事-1.我在末尾有标题…2.我们需要在第59到74位重复相同的逻辑..3.第77到80位-1020我们需要在变量中存储值。如果我必须再次发布问题,请让我知道。或者我应该修改吗?非常感谢分享,效果很好。:)我忘了提到的三件事-1.我在末尾有标题…2.同样的逻辑我们需要在第59位到第74位重复…3.还有第77位到第80位-1020我们需要在变量中存储值。如果我必须再次发布问题,请告诉我。或者我应该修改吗?你可以做任何一件事。如果它运行良好,通过接受其中一个答案来结束问题,并为您的问题发布新的答案。或者你也可以更新这个。谢谢你会提出一个新的。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:output omit-xml-declaration="yes" />
<xsl:param name="break" select="'&#xA;'" />

 <xsl:template match="/">
    <xsl:value-of select="ZR/TABLES/T_ER/item[1]/DATA" />
    <xsl:value-of select="$break" />

    <xsl:for-each select="ZR/TABLES/T_ER/item[position() != 1]">

        <xsl:variable name="length" select="string-length(substring(DATA,0,46))" />
        <xsl:variable name="tenNumbers" select="substring(DATA, ($length + 1), 10)"/>
        <xsl:variable name="charToReplace" select="translate(substring($tenNumbers, string-length($tenNumbers), 1),'0123456789','{ABCDEFGHI')" />

        <xsl:value-of select="concat(substring(DATA,0,46), substring(DATA, ($length + 1), 9), $charToReplace, substring(DATA,($length+11),(string-length(DATA) + 1)))"/>
        <xsl:value-of select="$break" />
    </xsl:for-each>

 </xsl:template>
</xsl:stylesheet>
<xsl:template match="/">
<xsl:value-of select="ZR/TABLES/T_ER/item[1]/DATA"/> 
<xsl:value-of select="$break" />
<xsl:for-each select="ZR/TABLES/T_ER/item[position() > 1]/DATA">
  <xsl:variable name="char" select="substring('{ABCDEFGHI', number(substring(., 55, 1)) + 1, 1)" />
  <xsl:value-of select="concat(substring(., 1, 54), $char, substring(., 56))" />
  <xsl:value-of select="$break" />
</xsl:for-each>
</xsl:template>
<xsl:template match="/">
<xsl:value-of select="ZR/TABLES/T_ER/item[1]/DATA,
                      ZR/TABLES/T_ER/item[position() > 1]/DATA/concat(substring(., 1, 54), substring('{ABCDEFGHI', number(substring(., 55, 1)) + 1, 1), substring(., 56))" 
              separator="&#xA;" />
</xsl:template>
<xsl:stylesheet version="3.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    xmlns:fn="http://www.w3.org/2005/xpath-functions" >

  <xsl:output omit-xml-declaration="yes"/>
  <xsl:param name="break" select="'&#xA;'" />

  <xsl:variable name="chars" as="map(xs:string, xs:string)">
    <xsl:map>
      <xsl:map-entry key="'0'" select="'{'"/>
      <xsl:map-entry key="'1'" select="'A'"/>
      <xsl:map-entry key="'2'" select="'B'"/>
      <xsl:map-entry key="'3'" select="'C'"/>
      <xsl:map-entry key="'4'" select="'D'"/>
      <xsl:map-entry key="'5'" select="'E'"/>
      <xsl:map-entry key="'6'" select="'F'"/>
      <xsl:map-entry key="'7'" select="'G'"/>
      <xsl:map-entry key="'8'" select="'H'"/>
      <xsl:map-entry key="'9'" select="'I'"/>
    </xsl:map>
  </xsl:variable>

  <xsl:template match="/">
    <xsl:value-of select="ZR/TABLES/T_ER/item[1]/DATA,
                          ZR/TABLES/T_ER/item[position() > 1]/DATA/concat(substring(., 1, 54), $chars(substring(., 55, 1)), substring(., 56))" separator="&#xA;" />
  </xsl:template>
</xsl:stylesheet>