Skip to Content

In an

article

, DJ Adams really showed the power of RSS. He used a simple BSP page to publish information about cross systems transports as an RSS feed. Then, using a standard RSS browser, he could sit back and browse the information about transports from his system in the same way that news feeds are scanned. The best way to see what is moving!

From the beginning, SDN has supported RSS feeds, allowing one to browse different aspects of SDN using an RSS browser. Mark Finnern has written about this topic a few times. Highly recommended reading would be

Fastest Scan of SDN Forum Posts via an RSS -Aggregator

and Newsreaders give Weblog Content extra Speed  ().

In his weblog Standardizing Syndication  (),  Marc Andrue Goodner mentions ATOM as a new RSS replacement in the future, and alludes to a cool site that provides ATOM feeds. When we torture these RSS feeds from SDN they give interesting answers. Hmmm…

This weblog is not really about RSS. We are a very small department, and until recently (sniff, sniff) had a few people for a number of hot technologies in our department: XML, XSLT and BSP. This weblog is for lightweight reading. Using RSS as an example, it shows the use of the HTTP client, XML, XSLT and BSP in one example. This is programming purely for the fun factor.

What is RSS?

For a detailed overview of RSS, please read Mark’s weblogs, and follow the links referenced. For our purposes, an RSS feed is an XML document that can be fetched via HTTP. For this weblog, we will use an SDN feed to play with.

See:

http://weblogs.sdn.sap.com/pub/q/weblog_rss_topic?x-topic=24&x-ver=1.0

Just to get a feeling for the RSS format, click on the above link. One will get an XML document displayed in the browser. Reading through the XML, we see that a number of people are starting to write about their BSP experiences, which is definitely better to read than this dry technical stuff. Found it interesting to read the writings of Thomas Jung  (/people/thomas.jung3/blog) and Craig Cmehil  (/people/craig.cmehil3/blog) on their BSP experiences.</p>

HTTP Client

Whenever one thinks of HTTP in the context of BSP, one pictures the browser starting the HTTP request, and that the server returns an HTTP response. However, in WebAS it is also possible to play the role of a browser and to effectively make outgoing HTTP calls.

For complete details, please consult the online help for the if_http_client interface  (http://help.sap.com/saphelp_nw04/helpdata/en/e5/4d3514c11411d4ad310000e83539c3/frameset.htm) and an example  (http://help.sap.com/saphelp_nw04/helpdata/en/1f/93163f9959a808e10000000a114084/frameset.htm). Also consider transaction SE38, program RSHTTP01 as a nicetest program.

For this Sunday afternoon fun, we decided to use the minimum number of lines of code. No error handling is done. (If the exceptions are not mapped onto sy-subrc during the method calls, they will just be raised and the BSP program is terminated. This is acceptable for our example. See the documentation for ways to handle errors during communication.)

<!code>  DATA: url         TYPE STRING,

<!code>        http_client TYPE REF TO IF_HTTP_CLIENT,

<!code>        return_code TYPE I,

<!code>        content     TYPE STRING.

<!code>   

<!code>  url = ‘http://weblogs.sdn.sap.com/pub/q/weblog_rss_topic?x-topic=24&x-ver=1.0‘.

<!code>  cl_http_client=>create_by_url( EXPORTING url    = url

<!code>                                 IMPORTING client = http_client ).

<!code>  http_client->send( ).

<!code>  http_client->receive( ).

<!code>  http_client->response->get_status( IMPORTING code = return_code ).

<!code>  content = http_client->response->get_cdata( ).

<!code>  http_client->close( ).

<!code>   

These few linesare sufficient to pull the RSS data from SDN! The first line creates a new client using a complete URL that already contains the protocol to use (“http:”), plus destination system and port (implicitly port 80) and the requested URL. Once we have the HTTP client instance, we send the request and receive the answer. Ultra important is the close method call, to ensure that the resources held by the HTTP client are released.

When using the HTTP client, there are a number of interesting additional aspects to consider:

    • Setting headers such as Accept-Encoding and User-Agent in the request.

    • Setting the HTTP protocol and version to use and the method GET or POST.

    • Setting up of authentication information for the remote site, possibly also proxy authentication information.

    • Looking at the return_code and taking additional action. Interesting values would be rc=200 (OK), rc=302 (Redirect), rc=401 (Authentication Required) and rc=500 (Server Error).

All of these aspects are discussed in the online documentation.

XML

Once the RSS data has been retrieved, the next step is to parse this into an XML document. Of course, one could consider using normal string operations to extract the interesting data, but it does not have the same elegance.

Reading through the online help  (http://help.sap.com/saphelp_nw04/helpdata/en/47/b5413acdb62f70e10000000a114084/frameset.htm) on XML, we see a very rich API. However, the simple call “document = cl_ixml=>parse( content ).” does not exist. We have to jump through the loops to quickly parse the content. Let’s not complain, and just copy this code directly from the online help.

<!code>  TYPE-POOLS: ixml.

<!code>  DATA: ixml          TYPE REF TO if_ixml,

<!code>        streamFactory TYPE REF TO if_ixml_stream_factory,

<!code>        istream       TYPE REF TO if_ixml_istream,

<!code>        parser        TYPE REF TO if_ixml_parser,

<!code>        document      TYPE REF TO if_ixml_document.

<!code>   

<!code>  IF content CS ‘<!DOCTYPE’ AND content CS ‘]>’.

<!code>    DATA dummy type string.

<!code>    SPLIT content AT ‘<!DOCTYPE’ INTO dummy content.

<!code>    SPLIT content AT ‘]>’        INTO dummy content.

<!code>  ENDIF.

<!code>   

<!code>  ixml     = cl_ixml=>create( ).

<!code>  streamFactory = ixml->create_stream_factory( ).

<!code>  istream  = streamFactory->create_istream_cstring( content ).

<!code>  document = ixml->create_document( ).

<!code>  parser   = ixml->create_parser( stream_factory = streamFactory

<!code>                                 istream         = iStream

<!code>                                 document        = document ).

<!code>  parser->set_normalizing( ).

<!code>  parser->set_validating( mode = if_ixml_parser=>co_no_validation ).

<!code>  parser->parse( ).

<!code>   

<!code>  TYPES: BEGIN OF t_blog,

<!code>            title       TYPE string,

<!code>            link        TYPE string,

<!code>            description TYPE string,

<!code>            creator     TYPE string,

<!code>            date        TYPE string,

<!code>         END OF t_blog,

<!code>         t_blogs TYPE TABLE OF t_blog.

<!code>   

<!code>  DATA:          blogs type t_blogs.

<!code>  FIELD-SYMBOLS:  type t_blog.

<!code>   

<!code>  DATA:  collection      TYPE REF TO if_ixml_node_collection,

<!code>         node            TYPE REF TO if_ixml_node,

<!code>         element         TYPE REF TO if_ixml_element,

<!code>         index           TYPE i.

<!code>   

<!code>  collection = document->get_elements_by_tag_name( name = ‘item’ ).

<!code>  WHILE index < collection->get_length( ).

<!code>   

<!code>    APPEND INITIAL LINE TO blogs ASSIGNING .

<!code>    node     = collection->get_item( index ).

<!code>    element ?= node->query_interface( ixml_iid_element ).

<!code>    index    = index + 1.

<!code>   

<!code>    node = element->find_from_name( name = ‘title’ ).

<!code>    get_value( ).

<!code>   

<!code>    …. repeat above two line sequence for all bits of information required ….

<!code>  ENDWHILE.

<!code>   

BSP

The final part of the puzzle is to display the output. One technique could be to use an HTMLB tableView. Another could be to transform the table into raw HTML. However, for the fun factor, let’s use a PHTMLB formattedText control. See BSP application SBSPEXT_PHTMLB for an example.

The formattedText control accepts as input an XML string that contains markup sequences, similar to that of HTML. As a first step, just loop over the internal table with acquired data and generate the XML string.

<!code>  DATA: formattedText TYPE string.

<!code>  formattedText = ”.

<!code>  LOOP AT blogs ASSIGNING .

<!code>    CONCATENATE formattedText

<!code>                ‘

<!code>                ”

<!code>                ` by -date `  —  `

<!code>                -description

<!code>                ‘</P>’

<!code>           INTO formattedText.

<!code>  ENDLOOP.

<!code>  CONCATENATE formattedText ‘</ROOT>’ INTO formattedText.

<!code>   

<!code>  <% ….all coding from above…. %>

<!code>   

<!code>  <%@page language=”abap”%>

<!code>  <%@extension name=”htmlb”  prefix=”htmlb”%>

<!code>  <%@extension name=”phtmlb” prefix=”phtmlb”%>

<!code>  <htmlb:content design=”design2003″>

<!code>    <htmlb:page>

<!code>      <htmlb:form>

<!code>        <phtmlb:formattedText text = “<%=formattedText%>” />

<!code>      </htmlb:form>

<!code>    </htmlb:page>

<!code>  </htmlb:content>

<!code>   

The final output is a very nicely formatted list of all current weblogs listed under the BSP topic.

!https://weblogs.sdn.sap.com/weblogs/images/164/BP_RSSHCXMLXSLT_001.GIF|height=0 width=566 height=156 |width=0 width=566 height=156 |src=https://weblogs.sdn.sap.com/weblogs/images/164/BP_RSSHCXMLXSLT_001.GIF|border=0 width=566 height=156 !</body>

To report this post you need to login first.

1 Comment

You must be Logged on to comment or reply to a post.

  1. Clement Selvaraj
    Hi,
    I always get an error when I receive the HTTP Request.
    Error Details
    =============
    Code:    400                          
    Message:  ICM_HTTP_CONNECTION_FAILED  
    communication_error                   

    Kindly help

    Code
    ====
    REPORT  ZRSSFEEDREADER.
    DATA: url         TYPE STRING,
           http_client TYPE REF TO IF_HTTP_CLIENT,
           return_code TYPE I,
           content     TYPE STRING.
    data: dummy type string,
          subrc type sysubrc.

    url = ‘http://weblogs.sdn.sap.com/pub/q/weblog_rss_topic?x-topic=24&x-ver=1.0‘.
    cl_http_client=>create_by_url( EXPORTING url    = url
                                    IMPORTING client = http_client ).
    http_client->send( ).

    write: / ‘*************Before Calling Client.Receive’.
    write: / ‘Code : ‘, sy-subrc.
    write: / ‘Message :’, dummy.

    call method http_client->receive
      exceptions
        http_communication_failure = 1
        http_invalid_state         = 2
        http_processing_failed     = 3
        others                     = 4.

    write: / ‘*************After Calling Client.Receive’.
    write: / ‘Code : ‘, sy-subrc.
    write: / ‘Message :’, dummy.

    (0) 

Leave a Reply