Файл XML с фиксированной длиной с использованием логики положения XSLT_Complex - ЧАСТЬ 2 - PullRequest
0 голосов
/ 20 марта 2019

У нас есть требование, по которому нужно конвертировать XML в файл фиксированной длины. Первая запись в качестве заголовка, и после этого у нас есть фактические записи. Начиная с 2 записи, мы должны применить логику, которая упоминается ниже:

  1. После длины 45 рассмотрим 10 цифр 0000001000, которые должны быть последней цифрой, которую мы должны проверить, и заменить ее, следуя приведенной ниже таблице.
  2. Та же логика, которую мы должны повторить в позициях с 59-го по 74-й.
  3. с 77-го по 80-е мы должны получить значение 5152 и сохранить в одну переменную

Я задал вопрос с 1-й логикой и получил потрясающий ответ, теперь у меня остались 2-я и 3-я логика

 For Positive: (0000001000)   - (000000100{)             
  {= 0                                          
  A = 1                                       
  B = 2                                      
  c = 3                                      
  D = 4                                     
  E = 5                                      
  F = 6                                     
  G = 7                                      
  H = 8                                     
  I = 9 

Попросите кого-нибудь помочь мне добиться того же, я упомянул XSLT, который я получил из предыдущих ответов. Спасибо

Введите:

<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 0000000000000100005152D04YA30TRE0000000XXXYYY 800{  Q 2018-11-05</DATA>
            </item>
            <item>
                <DATA>987654    D4E2   EA     1987654321 2018-11-060000002001EA 0000000000000100005152D04YA30UUU0000000XXXLRB 100{  Q 2018-11-05</DATA>
            </item>
                .
                .
                .
                .
                .
                .
                .
                .

            <item>
                <DATA>12345678912345678934562754378909726533297TRAILER</DATA>
            </item>         
        </T_ER>
    </TABLES>
</ZR>

XSLT:

<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>

OR

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

Ожидаемый результат:

   HEADER1111111122222222333333344456
   778944    D4E2   EA     1234567891 2018-11-06000000100{EA 
   000000000000010{005152D04YA30TRE0000000XXXYYY 800{  Q 2018-11-05
   987654    D4E2   EA     1987654321 2018-11-06000000200AEA 
   000000000000010{005152D04YA30UUU0000000XXXLRB 100{  Q 2018-11-05
.
.
.
.
  12345678912345678934562754378909726533297TRAILER

1 Ответ

1 голос
/ 20 марта 2019
<?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="sixteenNumbers" select="substring(DATA, (string-length(substring(DATA,0,59)) + 1), 16)" />

        <xsl:variable name="firstCharToReplace" select="translate(substring($tenNumbers, string-length($tenNumbers), 1),'0123456789','{ABCDEFGHI')" />
        <xsl:variable name="secondCharToReplace" select="translate(substring($sixteenNumbers, string-length($sixteenNumbers), 1),'0123456789','{ABCDEFGHI')" />

        <xsl:choose>
            <xsl:when test="string-length($tenNumbers) != 10">
                <xsl:value-of select="concat(substring(DATA,0,46), substring(DATA, ($length + 1), 9))" />
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="concat(substring(DATA,0,46),
                                                  substring(DATA, ($length + 1), 9),
                                                  $firstCharToReplace,
                                                  substring(DATA,($length+11), 18),
                                                  $secondCharToReplace,
                                                  substring(DATA,($length+30),(string-length(DATA) + 1)))" />
            </xsl:otherwise>
        </xsl:choose>
        <xsl:value-of select="$break" />
        <xsl:variable name="temp" select="substring(DATA,77,4)" />
    </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

Это зависит от того, какое условие вы хотите заменить символом.

Если оно основано на after EA (согласно комментарию), решение будет другим.

Длятеперь я реализовал его исключительно length на основе обоих пунктов 2 и 3.

http://xsltfiddle.liberty -development.net / 6r5Gh38 / 1

РЕДАКТИРОВАТЬ:

http://xsltfiddle.liberty -development.net / 6r5Gh38 / 2

РЕДАКТИРОВАТЬ 2: Краткое описание пунктов, упомянутых вкомментарий:

1. <xsl:when test="string-length($tenNumbers) != 10"> Это условие добавлено для удаления лишних R , появляющихся за последние <item>.Это означает, что если 10 чисел, которые мы берем в переменную, на самом деле имеют 10 чисел или нет.

В последнем случае

<item>
     <DATA>12345678912345678934562754378909726533297TRAILER</DATA>
</item>

Мы не получаем 10 чисел после 46-го символа.Мы получаем меньше, чем это.По этой причине выходные данные были выделены для двух разных случаев.

2. substring(DATA,0,46) ->, что будет соответствовать первым 45 символам 778944 D4E2 EA 1234567891 2018-11-06

substring(DATA, ($length + 1), 9) ->, что будет соответствовать 9 символам из 46-го индекса, чтобы соответствовать 000000100

$firstCharToReplace -> Это заменит 10-й символ как ваше требование 1-го вопроса, то есть {

substring(DATA,($length+11), 18) -> Будет начинаться оставшаяся строка с индексом (45 + 11)-го до 18 символов, который соответствует EA 000000000000010

$secondCharToReplace -> Это заменит (45 + 11 +18) = 74-й символ как ваше требование второго вопроса, т.е. {

substring(DATA,($length+30),(string-length(DATA) + 1)) -> Он начинается с (45 + 30) = 75-й символ до последнего индекса и дает 005152D04YA30TRE0000000XXXYYY 800{ Q 2018-11-05

Примечание: В вашем случае между строкой имеются дополнительные табуляции и пробелы.Вот почему номер индекса был изменен в соответствии с ожидаемым результатом.

...