RAP – sXML Kullanarak XML Verilerinin Ayrıştırılması


Token-Based Parsing


Token-based ayrıştırmada, ayrıştırıcı XML verilerinin ağaç yapısındaki tüm düğümleri (belirteçleri) birbiri ardına yineler. Varsayılan olarak, yineleyici son düğüme kadar tüm alt düğüm dallarından geçer.

  • Örnekte kullanılacak demo XML verilerinin oluşturulması;
TRY.
    DATA(xml_to_parse) = cl_abap_conv_codepage=>create_out( )->convert(
      `<?xml version="1.0"?>` &&
      `<node attr_a="123">` &&
      ` <subnode1>` &&
      `  <hallo>hi</hallo>` &&
      ` </subnode1>` &&
      ` <subnode2>` &&
      `  <letter>a</letter>` &&
      `  <date format="mm-dd-yyyy">01-01-2025</date>` &&
      ` </subnode2>` &&
      ` <subnode3>`  &&
      `  <text attr_b="1" attr_c="a">abc</text>` &&
      `  <text attr_b="2" attr_c="b">def</text>` &&
      `  <text attr_b="3" attr_c="c">ghi</text>` &&
      `  <text attr_b="4" attr_c="d">jkl</text>` &&
      ` </subnode3>` &&
      `</node>` ).
  CATCH cx_sy_conversion_codepage.
ENDTRY.
  • Gösterim amacıyla dahili bir tablo oluşturma;
DATA: BEGIN OF node_info,
        node_type TYPE string,
        name      TYPE string,
        value     TYPE string,
      END OF node_info,
      nodes_tab LIKE TABLE OF node_info.
  • Okuyucuyu oluşturma;
DATA(reader) = cl_sxml_string_reader=>create( xml_to_parse ).
  • Tüm düğümleri yinelemek için NEXT_NODE yöntemini çağrılır;
TRY.
    DO.
      CLEAR node_info.
      reader->next_node( ).

      "XML verilerinin sonuna ulaşıldığında döngüden çıkılır.
      IF reader->node_type = if_sxml_node=>co_nt_final.
        EXIT.
      ENDIF.

      "Düğümün özelliklerine doğrudan erişebilirsiniz.
      "Görüntüleme amacıyla, özellik bilgileri dahili bir tabloda saklanır.
      "Buradaki örnekte sadece basit demo JSON verileri kullanılmaktadır. Tüm özellikler alınmaz ve görüntülenmez.

      "Düğüm türü, if_sxml_node arayüzüne bakın
      node_info-node_type = SWITCH #( reader->node_type WHEN if_sxml_node=>co_nt_initial THEN `CO_NT_INITIAL`
                                                        WHEN if_sxml_node=>co_nt_element_open THEN `CO_NT_ELEMENT_OPEN`
                                                        WHEN if_sxml_node=>co_nt_element_close THEN `CO_NT_ELEMENT_CLOSE`
                                                        WHEN if_sxml_node=>co_nt_value THEN `CO_NT_VALUE`
                                                        WHEN if_sxml_node=>co_nt_attribute THEN `CO_NT_ATTRIBUTE`
                                                        ELSE `Error` ).
      "Öğenin adı
      node_info-name = reader->name.

      node_info-value = COND #( WHEN reader->node_type = if_sxml_node=>co_nt_value THEN reader->value ).
      APPEND node_info TO nodes_tab.

      "Yöntem çağrıldıktan sonra, düğümün gerekli özellikleriyle okuyucunun niteliklerine doğrudan erişebilirsiniz. Ayrıştırıcı bir öğe açılışının düğümündeyken, XML öğesi nitelikleri arasında yineleme yapmak için NEXT_ATTRIBUTE yöntemini kullanabilirsiniz.
      IF reader->node_type = if_sxml_node=>co_nt_element_open.
        DO.
          reader->next_attribute( ).
          IF reader->node_type <> if_sxml_node=>co_nt_attribute.
            EXIT.
          ENDIF.
          APPEND VALUE #( node_type  = `CO_NT_ATTRIBUTE`
                          name       = reader->name
                          value      = reader->value ) TO nodes_tab.
        ENDDO.
      ENDIF.
    ENDDO.
  CATCH cx_sxml_state_error INTO DATA(error_parse_token).
    DATA(error_text) = error_parse_token->get_text( ).
ENDTRY.
  • Output: nodes_tab -> Tablonun ilk 10 kalemin ekran görüntüsü aşağıdaki gibidir. Tüm çıktı text olarak incelenebilir.
*NODE_TYPE              NAME        VALUE     
*CO_NT_ELEMENT_OPEN     node                  
*CO_NT_ATTRIBUTE        attr_a      123       
*CO_NT_ELEMENT_OPEN     subnode1              
*CO_NT_ELEMENT_OPEN     hallo                 
*CO_NT_VALUE            hallo       hi        
*CO_NT_ELEMENT_CLOSE    hallo                 
*CO_NT_ELEMENT_CLOSE    subnode1              
*CO_NT_ELEMENT_OPEN     subnode2              
*CO_NT_ELEMENT_OPEN     letter                
*CO_NT_VALUE            letter      a         
*CO_NT_ELEMENT_CLOSE    letter                
*CO_NT_ELEMENT_OPEN     date                  
*CO_NT_ATTRIBUTE        format      mm-dd-yyyy
*CO_NT_VALUE            date        01-01-2025
*CO_NT_ELEMENT_CLOSE    date                  
*CO_NT_ELEMENT_CLOSE    subnode2              
*CO_NT_ELEMENT_OPEN     subnode3              
*CO_NT_ELEMENT_OPEN     text                  
*CO_NT_ATTRIBUTE        attr_b      1         
*CO_NT_ATTRIBUTE        attr_c      a         
*CO_NT_VALUE            text        abc       
*CO_NT_ELEMENT_CLOSE    text                  
*CO_NT_ELEMENT_OPEN     text                  
*CO_NT_ATTRIBUTE        attr_b      2         
*CO_NT_ATTRIBUTE        attr_c      b         
*CO_NT_VALUE            text        def       
*CO_NT_ELEMENT_CLOSE    text                  
*CO_NT_ELEMENT_OPEN     text                  
*CO_NT_ATTRIBUTE        attr_b      3         
*CO_NT_ATTRIBUTE        attr_c      c         
*CO_NT_VALUE            text        ghi       
*CO_NT_ELEMENT_CLOSE    text                  
*CO_NT_ELEMENT_OPEN     text                  
*CO_NT_ATTRIBUTE        attr_b      4         
*CO_NT_ATTRIBUTE        attr_c      d         
*CO_NT_VALUE            text        jkl       
*CO_NT_ELEMENT_CLOSE    text                  
*CO_NT_ELEMENT_CLOSE    subnode3              
*CO_NT_ELEMENT_CLOSE    node  

Object-Oriented Parsing


Tıpkı token-based ayrıştırmada olduğu gibi, object-oriented(nesne yönelimli) ayrıştırma da bir XML okuyucu oluşturur ve XML verileri üzerinde yineleme yapmak için bu okuyucunun yöntemlerini kullanır. Ancak bazı yöntemler farklıdır. Object-oriented ayrıştırma için kullanılan yöntemler, token-based ayrıştırma yöntemlerini sarar ve geçerli düğüme object-oriented erişim sağlar. Bir ayrıştırıcı adımından sonra doğrudan okuyucunun niteliklerini okumak yerine, object-oriented ayrıştırma için kullanılan yöntemler geçerli düğümü temsil eden nesnelere referanslar döndürür. Bu nesnelerin sınıflarının ve arayüzlerinin yöntemleri ve nitelikleri düğümün özelliklerine erişmek için kullanılabilir. Token-based ayrıştırmanın aksine, yalnızca ilgili değerler kullanılabilir.

  • Örnekte kullanılacak demo XML verilerinin oluşturulması;
TRY.
    DATA(xml_to_parse) = cl_abap_conv_codepage=>create_out( )->convert(
      `<?xml version="1.0"?>` &&
      `<node attr_a="123">` &&
      ` <subnode1>` &&
      `  <hallo>hi</hallo>` &&
      ` </subnode1>` &&
      ` <subnode2>` &&
      `  <letter>a</letter>` &&
      `  <date format="mm-dd-yyyy">01-01-2025</date>` &&
      ` </subnode2>` &&
      ` <subnode3>`  &&
      `  <text attr_b="1" attr_c="a">abc</text>` &&
      `  <text attr_b="2" attr_c="b">def</text>` &&
      `  <text attr_b="3" attr_c="c">ghi</text>` &&
      `  <text attr_b="4" attr_c="d">jkl</text>` &&
      ` </subnode3>` &&
      `</node>` ).
  CATCH cx_sy_conversion_codepage.
ENDTRY.
  • Okuyucuyu oluşturma;
DATA(reader_oo) = cl_sxml_string_reader=>create( xml_to_parse ).
  • Tüm düğümleri yinelemek için READ_NEXT_NODE yöntemini çağrılır
TRY.
    DO.
      "XML verisinin sonuna ulaşıldığında, döndürülen değer başlangıç değeridir.
      DATA(node_oo) = reader_oo->read_next_node( ).
      IF node_oo IS INITIAL.
        EXIT.
      ENDIF.

     “ Object-oriented ayrıştırmada, token-based ayrıştırma için yöntemler sarılır. Düğüme nesne yönelimli bir erişim sağlanır. Geçerli düğümü temsil eden nesnelere referanslar döndürülür.
      " Node tipini alma
      DATA(n_type) = node_oo->type.

“Ayrıştırıcı o anda bir öğe açılışının düğümündeyse, düğüm nesnesi IF_SXML_OPEN_ELEMENT arayüzünü uygulayan CL_SXML_OPEN_ELEMENT sınıfına sahiptir. İçerdiği yöntemlerle, örneğin GET_ATTRIBUTES yöntemini kullanarak tüm özniteliklerin referanslarını dahili bir tabloya yerleştirmek gibi, öğenin XML özniteliklerine erişebilirsiniz. Özniteliklere erişmek için bir aşağı döküm gereklidir.
      CASE n_type.
        WHEN if_sxml_node=>co_nt_element_open.
          DATA(open_element) = CAST if_sxml_open_element( node_oo ).

          APPEND VALUE #( node_type = `open element`
                          name      = open_element->qname-name
                        ) TO nodes_tab.

          DATA(attributes) = open_element->get_attributes( ).

          LOOP AT attributes INTO DATA(attribute).
            APPEND VALUE #( node_type = `attribute`
                            name      = attribute->qname-name
                            value  = SWITCH #( attribute->value_type WHEN if_sxml_value=>co_vt_text THEN attribute->get_value( ) )
                          ) TO nodes_tab.
          ENDLOOP.

        WHEN  if_sxml_node=>co_nt_element_close.
          DATA(close_element) = CAST if_sxml_close_element( node_oo ).

          APPEND VALUE #( node_type = `close element`
                          name      = close_element->qname-name
                        ) TO nodes_tab.

        WHEN  if_sxml_node=>co_nt_value.
          DATA(value_node_oo) = CAST if_sxml_value_node( node_oo ).

          APPEND VALUE #( node_type = `value`
                          value     = SWITCH #( value_node_oo->value_type WHEN if_sxml_value=>co_vt_text THEN value_node_oo->get_value( ) )
                        ) TO nodes_tab.

        WHEN OTHERS.
          APPEND VALUE #( node_type = `Error` ) TO nodes_tab.
      ENDCASE.
    ENDDO.
  CATCH cx_sxml_state_error INTO DATA(error_parse_oo).
    DATA(error_parse_oo_text) = error_parse_oo->get_text( ).
ENDTRY.
  • Output: nodes_tab -> Tablonun ilk 10 kalemin ekran görüntüsü aşağıdaki gibidir. Tüm çıktı text olarak incelenebilir.
*NODE_TYPE        NAME        VALUE     
*open element     node                  
*attribute        attr_a      123       
*open element     subnode1              
*open element     hallo                 
*value                        hi        
*close element    hallo                 
*close element    subnode1              
*open element     subnode2              
*open element     letter                
*value                        a         
*close element    letter                
*open element     date                  
*attribute        format      mm-dd-yyyy
*value                        01-01-2025
*close element    date                  
*close element    subnode2              
*open element     subnode3              
*open element     text                  
*attribute        attr_b      1         
*attribute        attr_c      a         
*value                        abc       
*close element    text                  
*open element     text                  
*attribute        attr_b      2         
*attribute        attr_c      b         
*value                        def       
*close element    text                  
*open element     text                  
*attribute        attr_b      3         
*attribute        attr_c      c         
*value                        ghi       
*close element    text                  
*open element     text                  
*attribute        attr_b      4         
*attribute        attr_c      d         
*value                        jkl       
*close element    text                  
*close element    subnode3              
*close element    node       

İletişim

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir