将使用 DB2 for i 生成的 XML 保存到 ASCII 文件中
Save XML generated using DB2 for i into ASCII file
我正在尝试编写 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);
要获取 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 以外的值(这总是会导致很多转换问题,也就是无法自动转换)。
我正在尝试编写 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);
要获取 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 以外的值(这总是会导致很多转换问题,也就是无法自动转换)。