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

iXML - Reading a specific tag/specific attribute

Peter_Inotai
Active Contributor
0 Likes
3,251

Hi,

I'm trying to get out a specific tag ans specific attribute from an xml string.

I built my method based on BCCIIXMLT2 & BCCIIXMLT11 and , however it doesn't seem to work.

I already tried 2 approach, none of them worked

The loops are ended before the get_attributes method is called.

My code:

METHOD /eby/if_xml_output_writer~finish_element.

* Based on program BCCIIXMLT2 & BCCIIXMLT11

* \\ ======= iXML =======
  DATA:
    lr_ixml           TYPE REF TO if_ixml,
    lr_xml_doc        TYPE REF TO if_ixml_document,
    lr_node           TYPE REF TO if_ixml_node,
*    lr_iterator       TYPE REF TO if_ixml_inline_iterator,
    lr_iterator       TYPE REF TO if_ixml_node_iterator,
    lr_nodemap        TYPE REF TO if_ixml_named_node_map,
    lr_stream_factory TYPE REF TO if_ixml_stream_factory,
    lr_istream        TYPE REF TO if_ixml_istream,
    lr_parser         TYPE REF TO if_ixml_parser,
    lr_nnmap          TYPE REF TO if_ixml_named_node_map,
    lr_attr           TYPE REF TO if_ixml_node,

    lc_name           TYPE string,
    lc_value          TYPE string,
    lc_prefix         TYPE string,
    li_type           TYPE i,
    li_indent         TYPE i,
    li_index          TYPE i,
    li_count          TYPE i.
* // ======= iXML =======
*=======================================================================
  CLASS     cl_ixml          DEFINITION LOAD.
*=======================================================================

  CHECK i_parent IS INITIAL.

*-- Create the main factory
  lr_ixml = cl_ixml=>create( ).
*-- Create the initial document
  lr_xml_doc = lr_ixml->create_document( ).
*-- Create the stream factory
  lr_stream_factory = lr_ixml->create_stream_factory( ).
*-- Create a stream for the input (string)
  lr_istream = lr_stream_factory->create_istream_cstring( i_input ).
*-- Create the parser
 lr_parser = lr_ixml->create_parser( stream_factory = lr_stream_factory
                                     istream        = lr_istream
                                     document       = lr_xml_doc ).
*-- We don't need the stream any more, so let's close it...
  lr_istream->close( ).

* 1st attempt
*  lr_node = lr_xml_doc.
*  lr_iterator = lr_node->create_inline_iterator( ).
*  li_type     = lr_iterator->get_type( ).
*
*  WHILE li_type NE 0.
*    li_indent = lr_iterator->get_height( ) * 2.
*
*    CASE li_type.
*      WHEN if_ixml_node=>co_node_element.
*
*        lr_nnmap = lr_iterator->get_attributes( ).
*        li_index = 0.
*        li_count  = lr_nnmap->get_length( ).
*
*        WHILE li_index < li_count.
*
*          lr_attr  = lr_nnmap->get_item( li_index ).
*          lc_name  = lr_attr->get_name( ).
*          lc_value = lr_attr->get_value( ).
*
*          li_index = li_index + 1.
*        ENDWHILE.
*
*    ENDCASE.
*    li_type = lr_iterator->advance( ).
*  ENDWHILE.

* 2nd attempt

  lr_node ?= lr_xml_doc.
* Create a node iterator
  lr_iterator = lr_node->create_iterator( ).
* Get current node
  lr_node = lr_iterator->get_next( ).

* Loop over all nodes
  WHILE NOT lr_node IS INITIAL.

    li_indent = lr_node->get_height( ) * 2.
    li_indent = li_indent + 20.

    CASE lr_node->get_type( ).

      WHEN if_ixml_node=>co_node_element.

*       Element node
        lc_name = lr_node->get_name( ).
        lr_nodemap = lr_node->get_attributes( ).

        IF NOT lr_nodemap IS INITIAL.

*         Attributes
          li_count = lr_nodemap->get_length( ).

          DO li_count TIMES.
            li_index  = sy-index - 1.
            lr_attr   = lr_nodemap->get_item( li_index ).
            lc_name   = lr_attr->get_name( ).
            lc_prefix = lr_attr->get_namespace_prefix( ).
            lc_value  = lr_attr->get_value( ).
          ENDDO.

        ENDIF.

      WHEN if_ixml_node=>co_node_text OR
           if_ixml_node=>co_node_cdata_section.

*       Text node
        lc_value = lr_node->get_value( ).

    ENDCASE.

*   Advance to next node
    lr_node = lr_iterator->get_next( ).

  ENDWHILE.



ENDMETHOD.

Any idea what could be wrong?

Thanks in advance,

Peter

Hi,

I'm trying to get out a specific tag ans specific attribute from an xml string.

I built my method based on BCCIIXMLT2 & BCCIIXMLT11 and , however it doesn't seem to work.

I already tried 2 approach, none of them worked

The loops are ended before the get_attributes method is called.

My code:

METHOD /eby/if_xml_output_writer~finish_element.

* Based on program BCCIIXMLT2 & BCCIIXMLT11

* \\ ======= iXML =======
  DATA:
    lr_ixml           TYPE REF TO if_ixml,
    lr_xml_doc        TYPE REF TO if_ixml_document,
    lr_node           TYPE REF TO if_ixml_node,
*    lr_iterator       TYPE REF TO if_ixml_inline_iterator,
    lr_iterator       TYPE REF TO if_ixml_node_iterator,
    lr_nodemap        TYPE REF TO if_ixml_named_node_map,
    lr_stream_factory TYPE REF TO if_ixml_stream_factory,
    lr_istream        TYPE REF TO if_ixml_istream,
    lr_parser         TYPE REF TO if_ixml_parser,
    lr_nnmap          TYPE REF TO if_ixml_named_node_map,
    lr_attr           TYPE REF TO if_ixml_node,

    lc_name           TYPE string,
    lc_value          TYPE string,
    lc_prefix         TYPE string,
    li_type           TYPE i,
    li_indent         TYPE i,
    li_index          TYPE i,
    li_count          TYPE i.
* // ======= iXML =======
*=======================================================================
  CLASS     cl_ixml          DEFINITION LOAD.
*=======================================================================

  CHECK i_parent IS INITIAL.

*-- Create the main factory
  lr_ixml = cl_ixml=>create( ).
*-- Create the initial document
  lr_xml_doc = lr_ixml->create_document( ).
*-- Create the stream factory
  lr_stream_factory = lr_ixml->create_stream_factory( ).
*-- Create a stream for the input (string)
  lr_istream = lr_stream_factory->create_istream_cstring( i_input ).
*-- Create the parser
 lr_parser = lr_ixml->create_parser( stream_factory = lr_stream_factory
                                     istream        = lr_istream
                                     document       = lr_xml_doc ).
*-- We don't need the stream any more, so let's close it...
  lr_istream->close( ).

* 1st attempt
*  lr_node = lr_xml_doc.
*  lr_iterator = lr_node->create_inline_iterator( ).
*  li_type     = lr_iterator->get_type( ).
*
*  WHILE li_type NE 0.
*    li_indent = lr_iterator->get_height( ) * 2.
*
*    CASE li_type.
*      WHEN if_ixml_node=>co_node_element.
*
*        lr_nnmap = lr_iterator->get_attributes( ).
*        li_index = 0.
*        li_count  = lr_nnmap->get_length( ).
*
*        WHILE li_index < li_count.
*
*          lr_attr  = lr_nnmap->get_item( li_index ).
*          lc_name  = lr_attr->get_name( ).
*          lc_value = lr_attr->get_value( ).
*
*          li_index = li_index + 1.
*        ENDWHILE.
*
*    ENDCASE.
*    li_type = lr_iterator->advance( ).
*  ENDWHILE.

* 2nd attempt

  lr_node ?= lr_xml_doc.
* Create a node iterator
  lr_iterator = lr_node->create_iterator( ).
* Get current node
  lr_node = lr_iterator->get_next( ).

* Loop over all nodes
  WHILE NOT lr_node IS INITIAL.

    li_indent = lr_node->get_height( ) * 2.
    li_indent = li_indent + 20.

    CASE lr_node->get_type( ).

      WHEN if_ixml_node=>co_node_element.

*       Element node
        lc_name = lr_node->get_name( ).
        lr_nodemap = lr_node->get_attributes( ).

        IF NOT lr_nodemap IS INITIAL.

*         Attributes
          li_count = lr_nodemap->get_length( ).

          DO li_count TIMES.
            li_index  = sy-index - 1.
            lr_attr   = lr_nodemap->get_item( li_index ).
            lc_name   = lr_attr->get_name( ).
            lc_prefix = lr_attr->get_namespace_prefix( ).
            lc_value  = lr_attr->get_value( ).
          ENDDO.

        ENDIF.

      WHEN if_ixml_node=>co_node_text OR
           if_ixml_node=>co_node_cdata_section.

*       Text node
        lc_value = lr_node->get_value( ).

    ENDCASE.

*   Advance to next node
    lr_node = lr_iterator->get_next( ).

  ENDWHILE.



ENDMETHOD.

Any idea what could be wrong?

Thanks in advance,

Peter

3 REPLIES 3
Read only

athavanraja
Active Contributor
0 Likes
1,433

setting and getting attribute


REPORT  YXMLATTRIBUTE1.


types: begin of p_type ,
       identity(10),
       end of p_type .
data: l_xml  type ref to cl_xml_document  ,
     if_xml type ref to if_ixml_document ,
     node type ref to if_ixml_node  ,
     rval type string .
data: wa_persons type p_type .
data: xml_out type string .


call transformation id
      source persons = wa_persons
      result xml xml_out.


create object l_xml.

call method l_xml->parse_string
  exporting
    stream = xml_out.


node = l_xml->find_node(
    name   = 'IDENTITY'
*    ROOT   = ROOT
       ).

l_xml->set_attribute(
    name    = 'Name'
    value   = 'Charles'
    node    = node
       ).

l_xml->set_attribute(
    name    = 'Name2'
    value   = 'Mayer'
    node    = node
       ).
l_xml->set_attribute(
      name    = 'Job'
      value   = 'Development'
      node    = node
         ).

clear rval .
CALL METHOD l_xml->find_attribute
  EXPORTING
    node_name = 'IDENTITY'
    attr_name = 'Name'
*    root      =
  receiving
    value     = rval .


call method l_xml->display.

Read only

0 Likes
1,433

Thanks!

Unfortunately my code should also work on 46C, so XLST is not an option. Anyway I used some code from SAPLink and it works fine now.

*-- Create the main factory
  lr_ixml = cl_ixml=>create( ).
*-- Create the initial document
  lr_xml_doc = lr_ixml->create_document( ).
*-- Create the stream factory
  lr_stream_factory = lr_ixml->create_stream_factory( ).
*-- Create a stream for the input (string)
  lr_istream = lr_stream_factory->create_istream_cstring( i_input ).
*-- Create the parser
  lr_parser = lr_ixml->create_parser(
                      stream_factory = lr_stream_factory
                      istream        = lr_istream
                      document       = lr_xml_doc ).
*-- Parse the stream
  lr_parser->parse( ).
*-- We don't need the stream any more, so let's close it...
  CLEAR lr_istream.

* Find the tag
  lr_rootnode = lr_xml_doc->find_from_name( c_tag_structureddocument ).


  lr_attributelist = lr_rootnode->get_attributes( ).
  lr_nodeiterator  = lr_attributelist->create_iterator( ).
  lr_attributenode = lr_nodeiterator->get_next( ).

* Find the attribute
  WHILE lr_attributenode IS NOT INITIAL.
    lc_name = lr_attributenode->get_name( ).
    IF lc_name = c_attribute_id.
      lc_value = lr_attributenode->get_value( ).
      EXIT.
    ENDIF.
    lr_attributenode = lr_nodeiterator->get_next( ).
  ENDWHILE.

  mc_output = lc_value.

Read only

0 Likes
1,433

Dear all,

I have a related query for CL_XML_DOCUMENT and IF_IXML_NODE classes.

How to treat a node if its an internal table.

I use CALL TRANSFORMATION id to convert a deep strcuture into XML document. and traverse it using iterator. If the iterator->get_next( ) is an intenal table in the deep structure then i need to read/write the records. HOw do we do this ?

If its a flat field then GET_VALUE and SET_VALUES methods works fine but it fails in case of an Internal table.

Appreciate your thoughts here.

Thanks in advance.

BR

Nilesh