Application Development and Automation Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

ABAP XML Parsing - get all attributes and values from specific node

KayLoehmann
Product and Topic Expert
Product and Topic Expert
0 Likes
12,667

Hello folks,

I built a program that loads a xml file and parses it.

This all works fine.

For now i would like to get all the attributes and text from one single node. For example.

<diagnosis type="ICD10" code="X.91">Multimorbid</diagnosis>

<diagnosis type="ICD11" code="A.03">Multimorbid</diagnosis>

Can i do that by just one single call and how can that be done? Maybe in a little fine table?

This is really important since i dont have to parse the whole xml document. Only those parts i want.

HELP PLEASE!!!!

Message was edited by: Kay Loehmann

Hello folks,

I built a program that loads a xml file and parses it.

This all works fine.

For now i would like to get all the attributes and text from one single node. For example.

<diagnosis type="ICD10" code="X.91">Multimorbid</diagnosis>

<diagnosis type="ICD11" code="A.03">Multimorbid</diagnosis>

Can i do that by just one single call and how can that be done? Maybe in a little fine table?

This is really important since i dont have to parse the whole xml document. Only those parts i want.

HELP PLEASE!!!!

Message was edited by: Kay Loehmann

12 REPLIES 12
Read only

Former Member
0 Likes
5,154

Hi Kay,

I haven't done XML in ABAP, but would it be safe for me to assume that the XML file that you're loading and parsing will be contained within an internal table in your ABAP program? If yes, then you can process the internal table suitably to access only the selective content.

I would need further information on how the XML data is contained within the ABAP program, to give you a more precise answer.

You should also take a look at the class CL_XML_DOCUMENT. It's got some methods which seem to be right, but you're the one who has to decide.

Regards,

Anand Mandalika.

Read only

sergey_korolev
Active Contributor
0 Likes
5,154

I would recommend using CL_XML_DOCUMENT class wich is implementation of the DOM model. With its method IMPORT_FROM_FILE you can upload the file from the work station, or you can parse the content with PARSE_STRING, or PARSE_XSTRING, or PARSE_TABLE. After parsing you can find node with FIND_NODE.

Read only

KayLoehmann
Product and Topic Expert
Product and Topic Expert
0 Likes
5,154

Ok...heres the code!

form create_xmldatastream .

  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,
        event           type ref to if_ixml_event,
        type            type i,
        indent          type i,
        name            type string,
        value           type string,
        ptext           type ref to if_ixml_text.

*-- 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 table
  pistream = pstreamfactory->create_istream_string( string =
g_filecontent ).

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

  data: events type i.

  add if_ixml_event=>co_event_element_pre    to events.
  add if_ixml_event=>co_event_attribute_post to events.
  add if_ixml_event=>co_event_text_post      to events.

  pparser->set_event_subscription( events = events ).

* Event based parsing
  do.
* read next event
    event = pparser->parse_event( ).
    if event is initial.
      exit.
    endif.
* get event type
    type   = event->get_type( ).

    pnode   = event->get_node( ).
    indent = pnode->get_height( ) * 2.
    indent = indent + 20.
* evaluate event type
    case type.
      when if_ixml_event=>co_event_element_pre.
*     element event
        name    = pnode->get_name( ).
        value  = pnode->get_value( ).
*        IF name IS NOT INITIAL AND value IS NOT INITIAL.
        gs_xmltags-tagname = name.
        gs_xmltags-tagvalue = value.
        clear name.
        clear value.
        collect gs_xmltags into gt_xmltags.
*        ENDIF.
      when if_ixml_event=>co_event_attribute_post.
*     attr event
        name   = pnode->get_name( ).
        value  = pnode->get_value( ).
*        IF name IS NOT INITIAL AND value IS NOT INITIAL.
        gs_xmltags-tagname = name.
        gs_xmltags-tagvalue = value.
        clear name.
        clear value.
        collect gs_xmltags into gt_xmltags.
*        ENDIF.
      when if_ixml_event=>co_event_text_post.
        name   = pnode->get_name( ).
        value  = pnode->get_value( ).
*        IF name IS NOT INITIAL AND value IS NOT INITIAL.
        gs_xmltags-tagname = name.
        gs_xmltags-tagvalue = value.
        clear name.
        clear value.
        collect gs_xmltags into gt_xmltags.
*        ENDIF.

      when others.
        name   = pnode->get_name( ).
        value  = pnode->get_value( ).
*        IF name IS NOT INITIAL AND value IS NOT INITIAL.
        gs_xmltags-tagname = name.
        gs_xmltags-tagvalue = value.
        clear name.
        clear value.
        collect gs_xmltags into gt_xmltags.
*        ENDIF.

    endcase.

  enddo.

endform.                    " create_xmldatastream

With this code i get all the values in the xmlfile.

Could someone give me a hint on how to read a specific note?

I tried:

data: attribute type ref to if_ixml_attribute.

attribute = element->get_attribute_node( name = 'status' ).

But how do i reach the attributes etc?

Read only

0 Likes
5,154

Another code with CL_XML_DOCUMENT:

data:
  node type ref to IF_IXML_NODE,
  root type ref to IF_IXML_NODE,
  value type string,
  xml_doc type ref to cl_xml_document.

  create object xml_doc.
  xml_doc->parsestring( STREAM = g_filecontent ).
  node = xml_doc->find_node( name = <your name>
                             root = root ).
  value = xml_doc->get_node_attribute( node = node
                                       NAME = <attr_name> ).

Read only

KayLoehmann
Product and Topic Expert
Product and Topic Expert
0 Likes
5,154

Thanx,

i get a syntax error that root is not compatible to the formal parameter root.

Read only

KayLoehmann
Product and Topic Expert
Product and Topic Expert
0 Likes
5,154

Alright everything is working now!!!

How do i get to count the number of available nodes with a specific name eg. 'diagnosis' ?

Read only

0 Likes
5,154

A pity.. I do not see any possibility of direct finding all nodes of particular name. Anyway you can iterate through nodes by this code snippet:

  <b>while not</b> node <b>is initial</b>.
    node = node->get_next( ).
  <b>endwhile</b>.

Read only

KayLoehmann
Product and Topic Expert
Product and Topic Expert
0 Likes
5,154

Alright. Thanx for your help. I will see then!

Read only

KayLoehmann
Product and Topic Expert
Product and Topic Expert
0 Likes
5,154

Another little problem with xml parsing.

if i have two or more tags defined in my xmlfile:

<diagnosis type="ICD10" code="X.91">Multimorbid</diagnosis>

<diagnosis type="ICD10" code="A.03">Multimorbid</diagnosis>

I would like to read them after one another.

My coding doesnt work though:

do 2 times.

value = xml_doc->get_node_attribute( name = 'type' node = node ).

MOVE value TO lstr_diag_di-cataid1.

value = xml_doc->get_node_attribute( name = 'code' node = node ).

MOVE value TO lstr_diag_di-diagid1.

value = xml_doc->get_node_value( node ).

node->get_next( ).

enddo.

Node is as follows:

node = xml_doc->find_node( name = 'diagnosis' root = root ).

Any suggestions?

Read only

0 Likes
5,154

I would suggest slightly different coding:


node = xml_doc->find_node( name = 'diagnosis' root = root ).
<b>while not</b> node <b>is initial</b>.
  <b>if</b> node->get_name( ) = 'diagnosis'.
    value = xml_doc->get_node_attribute( name = 'type' node = node ).
    MOVE value TO lstr_diag_di-cataid1.
    value = xml_doc->get_node_attribute( name = 'code' node = node ).
    MOVE value TO lstr_diag_di-diagid1.
    value = xml_doc->get_node_value( node ).
  <b>endif</b>.
  node->get_next( ).
<b>endwhile</b>.

I remember once that after parsing some XML file I've found that it contained some dummy tags.

Read only

former_member192850
Participant
0 Likes
5,154

Hello,

I write the solution to get all attributes and values of a tag:

  DATA: xml_doc TYPE REF TO cl_xml_document.
  DATA node TYPE REF TO if_ixml_node.
  DATA value TYPE string.
  DATA name TYPE string.
  data counter type i.

  CREATE OBJECT xml_doc.
  xml_doc->parse_string( stream = xml_string ).

  node = xml_doc->find_node( name = NAMEATTRIBUTE ).

  DO.

  CALL METHOD xml_doc->get_node_attr
    EXPORTING
      node  = node
      index = counter
    IMPORTING
      name  = name
      value = value.

   IF name is initial.
   exit.
   ENDIF.

   WRITE: / name, value.

   counter = counter + 1.
  ENDDO.

Regards

Marco

Read only

Former Member
0 Likes
5,154

Hello Folks,

Please help me how to upload the XML File to internal table.

All data is in Attributes format. If it is in Elements i  can do using function modules.

Attributes file format not able to get it,

please help as early as possible...