我有一个包含许多记录的xml文件。这些记录用于更新SAP中的自定义表。现在我的要求是,如果记录数量大于60k,则拆分文件,并分别处理每个文件。例如:如果xml文件中的记录数是100k,那么它应该被分成60k和40k两个文件,每个文件应该单独处理。我用csv文件做过同样的事情。我可以拆分它并并行处理它。但是对于xml文件,这是非常困难的。我不能做这件事。当我在文本模式下使用打开数据集,然后使用读取数据集时,我无法逐行读取文件。同样,以二进制模式打开数据集也会失败。请给我一个逻辑来分割xml文件。我不能做这件事。
我的xml文件是:
<Batch>
<header>
<system>ABC</system>
<time>20160428202244</time>
<user>a456</user>
<recver>5550458319J</recver>
<sender>29468422437</sender>
</header>
<status id="01006102739077803428">
<A>305430887B</A>
<B>2</B>
<C>20160404</C>
<D>Y</D>
<E>N</E>
<F>N</F>
<G>Y</G>
</status>
<status id="09007300449401352520">
<A>305449919L</A>
<B>2</B>
<C>20160404</C>
<D>N</D>
<E>Y</E>
<F>N</F>
<G>Y</G>
</status>
<trailer>
<numrecords>2</numrecords>
</trailer>
</Batch>
我已经告诉过我的文件大小大约是0.2 GB。现在,文件大小可能会根据数据提取而增加。请帮助。
- 启动事务
STRANS
,创建新的转换ZTEST
(转换类型为X XSLT Program
)。 -
粘贴以下转换并激活
<xsl:template match="Batch"> <xsl:apply-templates /> </xsl:template> <xsl:template match="header"> <xsl:text>HEADER;</xsl:text><xsl:value-of select="system" />;<xsl:value-of select="time" />;<xsl:value-of select="user" />;<xsl:value-of select="recver" />;<xsl:value-of select="sender" /> </xsl:template> <xsl:template match="status"> <xsl:text>STATUS;</xsl:text><xsl:value-of select="@id" />;<xsl:value-of select="A" />;<xsl:value-of select="B" />;<xsl:value-of select="C" />;<xsl:value-of select="D" />;<xsl:value-of select="E" />;<xsl:value-of select="F" />;<xsl:value-of select="G" /> </xsl:template> <xsl:template match="trailer"> <xsl:text>TRAILER;</xsl:text><xsl:value-of select="numrecords" /> </xsl:template>
-
启动事务
SXSLT
以测试转换。从演示服务器中选择文件,例如选择"Output to string" -
阅读
CALL TRANSFORMATION
的文档,以便熟悉如何从ABAP代码处理应用程序服务器上的文件。 -
使用您以前的经验来分割CSV文件
请注意,这只适用于不大于500 Mb的文件。对于更大的文件,您可能会遇到运行时异常,因为XSLT工作在完全加载到RAM中的DOM树上。
虽然XML解析可以通过多种方式完成,但我认为使用OPEN DATASET
是读取文件本身的唯一选择,note 872457也建议这样做。
GUI_UPLOAD有大约150 Mb的限制,因此解决方案是通过FTP或CG3Z/SXDA_TOOLS事务将文件上传到应用服务器,然后您将能够使用位置读取(具有可调块大小),如:
DATA fname(60) VALUE 'myfile'.
DATA num TYPE I VALUE 0.
DATA n TYPE I VALUE 100000.
DO n TIMES.
OPEN DATASET fname FOR INPUT IN TEXT MODE ENCODING DEFAULT AT POSITION num.
IF sy-subrc NE 0.
WRITE:/ 'error opening file'.
EXIT.
ELSE.
WHILE ( sy-subrc EQ 0 ).
READ DATASET v_file INTO wa_it_final.
IF NOT wa_it_final IS INITIAL.
APPEND wa_it_final TO it_final.
ENDIF.
CLEAR wa_it_final.
ENDWHILE.
ENDIF.
num = num + n.
ENDDO.
CLOSE DATASET file_str.