将使用DB2fori生成的XML保存到ASCII文件中

将使用DB2fori生成的XML保存到ASCII文件中,xml,db2,ascii,ibm-midrange,rpgle,Xml,Db2,Ascii,Ibm Midrange,Rpgle,我正在尝试编写RPGLE,它将使用SQL生成XML并将其保存到IFS。我遇到的问题是,当使用网络共享从IFS复制XML时,XML不会自动从EBCDIC转换为ASCII。我尝试先用正确的CCSID创建文件,但似乎被忽略了。我能够克服这个问题的唯一方法是使用CPY并在应对时进行翻译。我只是希望有一个更干净的方法 File_Out_FO = SQFOVR; File_Out_NAME = '/ifs/path/test.xml'; File_Out_NL = %Len(%TrimR(Fi

我正在尝试编写RPGLE,它将使用SQL生成XML并将其保存到IFS。我遇到的问题是,当使用网络共享从IFS复制XML时,XML不会自动从EBCDIC转换为ASCII。我尝试先用正确的CCSID创建文件,但似乎被忽略了。我能够克服这个问题的唯一方法是使用
CPY
并在应对时进行翻译。我只是希望有一个更干净的方法

 File_Out_FO   = SQFOVR;
 File_Out_NAME = '/ifs/path/test.xml';
 File_Out_NL   = %Len(%TrimR(File_Out_NAME));
 EXEC SQL
   WITH
     elements AS (
         SELECT
          XMLELEMENT(NAME "element",
           XMLFOREST(
            field1 AS "field1",
            field2 AS "field2",
            field3 AS "field3"
           )
          ) AS element
         FROM table1
     )
     SELECT
      XMLSERIALIZE(
       XMLDOCUMENT(
        XMLELEMENT(NAME "document",
         XMLELEMENT(NAME "elements",
          XMLAGG(elements.element)
         )
        )
       ) AS CLOB  INCLUDING XMLDECLARATION
      ) AS response
     INTO :File_Out
     FROM elements  ;

首先,您必须使用windows代码页创建文件

  // C Language IFS Prototypes

  //-----------------------------------------------------------------
  // createTempSTMF():  Creates a file name for a temporary stream file
  //
  //   filename = (input) path to file in the IFS
  //-----------------------------------------------------------------
 DcreateTempSTMF   PR              *   extproc('_C_IFS_tmpnam')
 D string                        39A   options(*omit)

  //-----------------------------------------------------------------
  // removeSTMF():  Deletes the defined streamed file.
  //
  //   filename = (input) path to file in the IFS
  //-----------------------------------------------------------------
 DremoveSTMF       PR            10I 0 extproc('_C_IFS_remove')
 D filename                        *   VALUE OPTIONS( *String)

  //-----------------------------------------------------------------
  // openSTMF():  Open File for buffered reading/writing
  //
  //   filename = (input) path to file in the IFS
  //       mode = (input) various open mode flags.  (see manual)
  //
  //  returns *NULL upon error, or a pointer to a FILE structure
  //-----------------------------------------------------------------
 dopenSTMF         PR                  extproc('_C_IFS_fopen')
 d                                     like(pFILE)
 d filename                        *   value options(*string)
 d mode                            *   value options(*string)

  //-----------------------------------------------------------------
  // closeSTMF(): Close File
  //    stream = (input) pointer to FILE structure to close
  //-----------------------------------------------------------------
 dcloseSTMF        PR            10i 0 extproc('_C_IFS_fclose')
 dparStream                            like(pFILE) value

 dpFile            s               *   based(prototype_only)
 d fd              s                   like(openSTMF)


    //Unique filename in /tmp
    tempFileName = %trim(%str(createTempSTMF(*omit)));

    // create new output file
    fd = openSTMF(%trim(tempFileName): 'w codepage=1252');
    if (fd = *NULL);
       *INLR = *ON;
       return;
    endif;
然后用文本模式重新打开它,以便自动进行翻译

    // ------------------------------------------
    // close file & reopen in text mode so that
    // data will be automatically translated
    // ------------------------------------------
    closeSTMF(fd);
    fd = openSTMF( %trim(tempFileName) : 'a codepage=37');
    if (fd = *NULL);
       *INLR = *ON;
       return;
    endif;
然后写一些数据

     //Write some data
     fputsSTMF('Some data': fd);

首先,您必须使用windows代码页创建文件

  // C Language IFS Prototypes

  //-----------------------------------------------------------------
  // createTempSTMF():  Creates a file name for a temporary stream file
  //
  //   filename = (input) path to file in the IFS
  //-----------------------------------------------------------------
 DcreateTempSTMF   PR              *   extproc('_C_IFS_tmpnam')
 D string                        39A   options(*omit)

  //-----------------------------------------------------------------
  // removeSTMF():  Deletes the defined streamed file.
  //
  //   filename = (input) path to file in the IFS
  //-----------------------------------------------------------------
 DremoveSTMF       PR            10I 0 extproc('_C_IFS_remove')
 D filename                        *   VALUE OPTIONS( *String)

  //-----------------------------------------------------------------
  // openSTMF():  Open File for buffered reading/writing
  //
  //   filename = (input) path to file in the IFS
  //       mode = (input) various open mode flags.  (see manual)
  //
  //  returns *NULL upon error, or a pointer to a FILE structure
  //-----------------------------------------------------------------
 dopenSTMF         PR                  extproc('_C_IFS_fopen')
 d                                     like(pFILE)
 d filename                        *   value options(*string)
 d mode                            *   value options(*string)

  //-----------------------------------------------------------------
  // closeSTMF(): Close File
  //    stream = (input) pointer to FILE structure to close
  //-----------------------------------------------------------------
 dcloseSTMF        PR            10i 0 extproc('_C_IFS_fclose')
 dparStream                            like(pFILE) value

 dpFile            s               *   based(prototype_only)
 d fd              s                   like(openSTMF)


    //Unique filename in /tmp
    tempFileName = %trim(%str(createTempSTMF(*omit)));

    // create new output file
    fd = openSTMF(%trim(tempFileName): 'w codepage=1252');
    if (fd = *NULL);
       *INLR = *ON;
       return;
    endif;
然后用文本模式重新打开它,以便自动进行翻译

    // ------------------------------------------
    // close file & reopen in text mode so that
    // data will be automatically translated
    // ------------------------------------------
    closeSTMF(fd);
    fd = openSTMF( %trim(tempFileName) : 'a codepage=37');
    if (fd = *NULL);
       *INLR = *ON;
       return;
    endif;
然后写一些数据

     //Write some data
     fputsSTMF('Some data': fd);

要获取ASCII格式的数据,请在XmlSerialize函数中添加CCSID 1208(不可能是819),并确保ifs文件不存在。否则它将保留文件CCSID

  XMLSERIALIZE(
   XMLDOCUMENT(
    XMLELEMENT(NAME "document",
     XMLELEMENT(NAME "elements",
      XMLAGG(elements.element)
     )
    )
   ) AS CLOB CCSID 1208 INCLUDING XMLDECLARATION
  ) AS Response

并确保您的机器QCCSID设置为65535以外的值(这总是会导致很多转换问题,即无法自动转换)。

要获取ASCII格式的数据,请在XmlSerialize函数中添加CCSID 1208(819不可能),并确保ifs文件不存在。否则它将保留文件CCSID

  XMLSERIALIZE(
   XMLDOCUMENT(
    XMLELEMENT(NAME "document",
     XMLELEMENT(NAME "elements",
      XMLAGG(elements.element)
     )
    )
   ) AS CLOB CCSID 1208 INCLUDING XMLDECLARATION
  ) AS Response

并确保您的机器QCCSID设置为65535以外的值(这总是会导致很多转换问题,即无法自动转换)。

为什么您希望使用ASCII?我没有看到为XML指定任何CCSID。(我不擅长将XML转换为流文件。)我不希望使用ASCII——我需要它。我发布代码只是作为一个起点。就我试图用不同的CCSID创建文件而言,这是出于绝望(同样不是作为XML专家)。。。streamfiles由两部分组成:(1)文件的CCSID属性,(2)写入文件的数据的CCSID。在几乎所有情况下,两者都应该匹配。您将其创建为某种ASCII类型,因此我认为XMLSERIALIZE。。。要匹配的CCSID将是合适的。至少应该尝试一下。在某些过程中,可以预期编码的自动转换;我不知道这是否发生在你的过程中。不管怎样,当您知道自己想要什么时,显式声明通常是最好的?我没有看到为XML指定任何CCSID。(我不擅长将XML转换为流文件。)我不希望使用ASCII——我需要它。我发布代码只是作为一个起点。就我试图用不同的CCSID创建文件而言,这是出于绝望(同样不是作为XML专家)。。。streamfiles由两部分组成:(1)文件的CCSID属性,(2)写入文件的数据的CCSID。在几乎所有情况下,两者都应该匹配。您将其创建为某种ASCII类型,因此我认为XMLSERIALIZE。。。要匹配的CCSID将是合适的。至少应该尝试一下。在某些过程中,可以预期编码的自动转换;我不知道这是否发生在你的过程中。不管怎样,当您知道自己想要什么时,显式声明通常是最好的。尽管将QCCSID设置为65535,这仍然有效。不幸的是,我没有权力改变这一点。谢谢QCCSID设置不应该影响这一点,但它是我上面评论的一个很好的例子。QCCSID值65535不应为任何期望通过网络接口可靠传输数据(传入或传出)的系统设置。它通常是正确的。但每次传输完成后,如果不验证每个字节,就永远无法确定。尽管QCCSID设置为65535,但这仍然有效。不幸的是,我没有权力改变这一点。谢谢QCCSID设置不应该影响这一点,但它是我上面评论的一个很好的例子。QCCSID值65535不应为任何期望通过网络接口可靠传输数据(传入或传出)的系统设置。它通常是正确的。但每次传输完成后,如果不验证每个字节,就永远无法确定。