Home AMX Forum NetLinx Studio
Options

Remove_String Issue

I'm baffled by this one. Using the Remove_String Command to parse some data that is returned from an XML sheet.

Here is the data returned:
Alive
Content-Type: text/plain

<WeatherData><Temperature>45</Temperature><Icon>partlycloudy</Icon></WeatherData>

and the code to parse it
	    cTRASHer = REMOVE_STRING(cWebBuffer,'<Temperature>',1)
	    nWEB_TEMPERATURE=atoi(REMOVE_STRING(cWebBuffer,'</Temperature>',1))
	    cTRASHer=REMOVE_STRING(cWebBuffer,'<Icon>',1)
	    cWEB_ICON=REMOVE_STRING(cWebBuffer,'</Icon>',1)

the nWEB_TEMPERATURE returns the proper value, but the cWEB_ICON always returns the icon code plus </Icon> on the end and I cannot figure out why. (I know the cTRASHer is not needed, just added to see the data passed). The </Weather> data is left in the cWebBuffer.

Any idea why it's grabbing the </Icon> as well? I'm sure it's something rather simple.

Comments

  • HARMAN_ChrisHARMAN_Chris Harman Professional University
    Remember that REMOVE_STRING is up-to AND including '</ICON>', so it is currently working as programmed. Do you want to now chop off the </icon>? There are several options for this, but if it is always '</icon>', you could use LENGTH_STRING and SET_LENGTH_STRING as a quick solution.
  • ColzieColzie Senior Member
    Also the reason you aren't seeing </Temperature> in nWEB_TEMPERATURE is due to ATOI.
  • HARMAN_ChrisHARMAN_Chris Harman Professional University
    Additionally, several forum members have contributed to function libraries to tackle common, but not so straight forward, tasks like this:

    Look Here
    http://www.amxforums.com/showthread.php?8675-Processing-Received-Strings&p=60394#post60394
  • jabramsonjabramson Junior Member
    Thanks everyone. For some reason I had it in my head that it was up to, but not including the search string. The number field was throwing me off since it was doing what it was supposed to do, only show a number.
  • HARMAN_ChrisHARMAN_Chris Harman Professional University
    Another way to manage this would be to use LEFT_STRING and LENGTH_STRING:
    cWEB_ICON= left_string(cWebBuffer, (length_string(cWebBuffer) - 7))
    

    In this example, we know that '</icon>' is 7 characters, so the above statement would equate to "give me my buffer minus the last 7 characters."
  • Just remember if you do use left, right or mid_string that you're only copying the strings and not removing them from the buffer so you'll have to do something the ensure these don't remain in your buffer for subsequent passess of your parsing routine. For this reason I tend to go with the pac man approach and gobble up strings from my buffer as I parse with the remove or get_buffer char or string commands. I tend to leave the copying commands for times when there is no specific order in which the strings can be processed then when I find everything I can possibly use I dump up to my delimeter, what ever that may be. Usually I'll remove up to and including my delimeter and put that portion of the string in a stack_var for the actually parsing which ensures it's always removed from my buffer and then if I am just copying strings out of my stack_var it automatically evaporates when that code block is done.
  • AMXJeffAMXJeff Senior Member
    I normally use my "getBoundString" function for this, I am not a big beliver in parsing by distroying the data, it tends to take more time. But I have done it!
    DEFINE_FUNCTION CHAR[MAX_STR_SIZE] getBoundString(CHAR source[], CHAR startString[], CHAR endString[])
    {
    	INTEGER startIndex;
    	INTEGER endIndex;
    	CHAR response[MAX_STR_SIZE];
    
    	response = "";
    	
    	// MAKE SURE THERE IS SOMETHING TO SEARCH
    	IF (LENGTH_STRING(source) > 0)
    	{
    		startIndex = FIND_STRING(source, startString, 1);
    		
    		// MAKE SURE IT FOUND THE START STRING
    		IF (startIndex > 0)
    		{
    			// ADJUST THE POSITION PAST THE START STRING
    			startIndex = startIndex + LENGTH_STRING(startString);			
    			// FIND THE END STRING BASED ON THE START STRINGS POSITION
    			endIndex = FIND_STRING(source, endString, startIndex);
    		
    			// IF THE ENDINDEX IS GREATER THAN THE START
    			if (startIndex < endIndex)
    				response = MID_STRING(source, startIndex, endIndex - startIndex);
    		}
    	}
    	
    	RETURN response;
    }
    
    DEFINE_START
    
    cTestString = '<?xml version="1.0"?><!--0000126--><SET_REG RT="C00" ID="0" L1PW="qsc"><REG_RATE S="50"/><REG O="0x001B0000" S="1"/></SET_REG>'
    
    send_string 0,"Length: ',getBoundString(cTestString,'<!--','-->')";
    send_string 0,"Password: ',getBoundString(cTestString,'L1PW="','"')";
    
  • The way i look at is the data has to be destroyed anyway at some point in order to prepare for new arriving data so if the data arrives in a known order or parsable segment i'll remove as I go and then dump the scraps that remain at the end as opposed to copying as i go and then dumping everything at the end.

    I've never really given the efficiency aspect any consideration but moving a pointer and referencing pointers should definitely be more efficient and probably a more eloquent way to go about it. I'm more a bull in a china shop kinda guy compared to a ballet dancer who has grace, style and fluidity in motion. :)
  • AMXJeffAMXJeff Senior Member
    LMAO! Those who know me would never discribe me or what I do as graceful!
Sign In or Register to comment.