Αναζήτηση

Friday, June 22, 2012

Parse xml file with ABAP

Parse xml with abap using standard SAP classes and methonds:

Read first : http://developerpages.gr/index.php/en/desktop-development-2/abap/71-read-utf-8-xml-file-with-abap
and here the example program : 


REPORT zparse_xml MESSAGE-ID bcciixmlt3_msg LINE-SIZE 1000.
TYPE-POOLS: ixml.

*----------------------------------------------------------------------*
*       www.developerpages.gr
*
*     Parse xml file
*----------------------------------------------------------------------*

START-OF-SELECTION.

*-- data
  DATA: pixml          TYPE REF TO if_ixml,
        pdocument      TYPE REF TO if_ixml_document,
        pstreamfactory TYPE REF TO if_ixml_stream_factory,
        pistream       TYPE REF TO if_ixml_istream,
        pparser        TYPE REF TO if_ixml_parser,
        pnode          TYPE REF TO if_ixml_node,
        ptext          TYPE REF TO if_ixml_text,
        string         TYPE string,
        count          TYPE i,
        index          TYPE i,
        dsn(40)        TYPE c,
        xstr           TYPE xstring.

*-- read the XML document from the frontend machine
  TYPES: BEGIN OF xml_line,
          data(256) TYPE x,
        END OF xml_line.

  data xml_string TYPE string.

  parameters : xml_file TYPE string DEFAULT '\\'.

* Load file
  perform load_file.

* parse xml
  perform parse_xml.


*&---------------------------------------------------------------------*
*&      Form  load_file
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
form load_file.

  DATA line TYPE string.
  clear xml_string.

  OPEN DATASET xml_file IN TEXT MODE for input ENCODING UTF-8 .
  if sy-subrc = 0.
    DO.
      READ DATASET xml_file INTO line.
      IF sy-subrc <> 0.
        EXIT.
      else.
        CONCATENATE xml_string line INTO xml_string.
      ENDIF.
    ENDDO.
    if xml_string is initial.
      write :/ 'file is empty ! ', xml_file.
    endif.
  else.
    WRITE :/ 'cannot open file ', xml_file.
  endif.

endform.                    "load_file


*&---------------------------------------------------------------------*
*&      Form  parse_xml
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
form parse_xml.

*-- create the main factory
  pixml = cl_ixml=>create( ).

*-- create the initial document
  pdocument = pixml->create_document( ).

*-- create the stream factory
  pstreamfactory = pixml->create_stream_factory( ).

*-- create an input stream for the string
  pistream = pstreamfactory->create_istream_string( string = xml_string ).

*-- create the parser
  pparser = pixml->create_parser( stream_factory = pstreamfactory
                                  istream        = pistream
                                  document       = pdocument ).

*-- parse the stream
  IF pparser->parse( ) NE 0.
    IF pparser->num_errors( ) NE 0.
      count = pparser->num_errors( ).
      WRITE: count, ' parse errors have occured:'.
      DATA: pparseerror TYPE REF TO if_ixml_parse_error,
            i TYPE i.
      index = 0.
      WHILE index < count.
        pparseerror = pparser->get_error( index = index ).
        i = pparseerror->get_line( ).
        WRITE: 'line: ', i.
        i = pparseerror->get_column( ).
        WRITE: 'column: ', i.
        string = pparseerror->get_reason( ).
        WRITE: string.
        index = index + 1.
      ENDWHILE.
    ENDIF.
  ENDIF.

*-- we don't need the stream any more, so let's close it...
  CALL METHOD pistream->close( ).
  CLEAR pistream.

*-- print the whole DOM tree as a list...
  pnode = pdocument.
  PERFORM process_node USING pnode.

endform.                    "parse_xml


*---------------------------------------------------------------------*
*       FORM print_node                                               *
*---------------------------------------------------------------------*
*       ........                                                      *
*---------------------------------------------------------------------*
FORM process_node USING value(pnode) TYPE REF TO if_ixml_node.
  DATA: indent      TYPE i.
  DATA: ptext       TYPE REF TO if_ixml_text.
  DATA: string      TYPE string.
  data : ss type String.
  data: attribs type ref to IF_IXML_NAMED_NODE_MAP,
        attrib_node type ref to IF_IXML_NODE,
        attrib_value type string.

  indent  = pnode->get_height( ) * 2.

  CASE pnode->get_type( ).
    WHEN if_ixml_node=>co_node_element.
      string = pnode->get_name( ).
      attribs = pNode->get_attributes( ).
      clear attrib_value.
      case string.
        when 'Order'. "put your XML tag name here
          ss = pnode->get_value( ).
        when 'Item'. "put your XML tag name here
          ss = pnode->get_value( ).
          write: / ss.
      endcase.
*      WRITE: AT /indent '<', string, '> '.                  "#EC NOTEXT
    WHEN if_ixml_node=>co_node_text.
      ptext ?= pnode->query_interface( ixml_iid_text ).
      IF ptext->ws_only( ) IS INITIAL.
        string = pnode->get_value( ).
        WRITE: AT /indent string.
      ENDIF.
  ENDCASE.
  pnode = pnode->get_first_child( ).

  WHILE NOT pnode IS INITIAL.
    PERFORM process_node USING pnode.
    pnode = pnode->get_next( ).
  ENDWHILE.

ENDFORM.                    "print_node

Original Article : http://developerpages.gr/index.php/en/desktop-development-2/abap/72-parse-xml-file-with-abap

1 comment: