OS2 World.Com Forum
2012.02.09, 11:58:55 *
Welcome, Guest. Please login or register.

Login with username, password and session length
News:
 
   Home   Help Search Login Register  
Pages: [1]
  Print  
Author Topic: count occurances in a string and extract balanced xml tags  (Read 1834 times)
jep
Global Moderator
Sr. Member
*****
Posts: 388


View Profile
« on: 2009.03.22, 20:23:22 »

Marked as: Easy
Hi,

It's sometimes necessary to count occurrences of a string within another string, and here's a little code I've written to do that.

Code:
COUNTSTR: PROCEDURE /* needle, haystack< <, startpos>, endpos> */
    IF ARG() < 2 THEN RETURN -1
    IF DATATYPE( ARG(3), 'W' ) THEN
        next = ARG(3)
    ELSE
        next = 1
    needle = ARG(1)
    haystack = ARG(2)
    IF DATATYPE( ARG(4), 'W' ) THEN
        haystack = SUBSTR( haystack, next, ABS( ARG(4) - next ) )
    next = 1
    count = 0
    DO WHILE next > 0
        next = POS( needle, haystack, next )
        IF next > 0 THEN DO
            next = next + LENGTH( needle )
            count = count + 1
        END
    END
RETURN count


If you try to use html pages or some other xml-like file format, it's very useful if you can specify the section you want to extract and not deal with things around, the function COUNTSTR above then come in handy to take care of some of the work.

Code:
xml_balanced_tags_parse: procedure /* xml-code, tag<, setting> */
    next = pos( '<'||translate( ARG(2)||ARG(3) ), translate( ARG(1) ) )
    if next = 0 then Return ARG(1)
    next = next + length( ARG(2)||ARG(3) ) + 2
    open_tag = next
    close_tag = pos( '</'||translate( ARG(2) ), translate( ARG(1) ), next )
    count = COUNTSTR( '<'||translate( ARG(2) ), translate( ARG(1) ), next, close_tag )
    do i = 1 to count
        next = close_tag + length( ARG(2) ) + 3
        close_tag = pos( '</'||translate( ARG(2) ), translate( ARG(1) ), next )
        count = count + COUNTSTR( '<'||translate( ARG(2) ), translate( ARG(1) ), next, close_tag )
    end
    if close_tag = 0 then end_tag = length( ARG(1) )
    else end_tag = close_tag - open_tag
Return substr( ARG(1), open_tag, max( 1, end_tag ) )

Example: retval = xml_balanced_tags_parse( xmlfile, 'div', ' style="color: blue;"' )

Please note that you have to specify the settings very accurately or it will ignore it and not find anything, that is, if something else may be present between "h1" and "style=..." in the example it will return nothing. It is possible to make it more relaxed/forgiving, but that is an exercise that I leave to you for the moment.

//Jan-Erik
« Last Edit: 2009.03.23, 09:55:42 by jep » Logged
jep
Global Moderator
Sr. Member
*****
Posts: 388


View Profile
« Reply #1 on: 2009.09.07, 17:36:47 »

Hi All,

I've rewritten the code somewhat now that RobertM has posted an alternative version.
You may compare both to see what they have in common and what differ as well see what may be improved or just added to be more useful.

Code:
xml_balanced_tags_parse: procedure /* xml-code, tag<, setting> */
    upper_arg_1 = translate( ARG(1) )
    upper_arg_2 = translate( ARG(2) )
    upper_arg_3 = translate( ARG(3) )
    next = pos( '<'||upper_arg_2||upper_arg_3, upper_arg_1 )
    if next = 0 then Return ARG(1)
    next = next + length( upper_arg_2||upper_arg_3 ) + 2
    open_tag = next
    close_tag = pos( '</'||upper_arg_2, upper_arg_1, next )
    count = COUNTSTR( '<'||upper_arg_2, upper_arg_1, next, close_tag )
    do i = 1 to count
        next = close_tag + length( ARG(2) ) + 3
        close_tag = pos( '</'||upper_arg_2, upper_arg_1, next )
        count = count + COUNTSTR( '<'||upper_arg_2, upper_arg_1, next, close_tag )
    end
    if close_tag = 0 then end_tag = length( ARG(1) )
    else end_tag = close_tag - open_tag
Return substr( ARG(1), open_tag, max( 1, end_tag ) )

There are at least two differences between our versions.
Can you spot them?
What benefit do they provide?
Can you combine the scripts into a new version that is better?

//Jan-Erik
« Last Edit: 2009.09.10, 17:01:39 by jep » Logged
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.14 | SMF © 2006-2011, Simple Machines LLC Valid XHTML 1.0! Valid CSS!