OpenNTF.org - Parser for "field=value&field=
My Links (Not logged in)
Code Bin Search
 
Hosted by Prominic.NET
Rate This Code
5 - brilliant stuff
4 - very nice
3 - average
2 - needs work
1 - bad
   OpenNTF Code Bin
About This Code
Brief Description:
Parser for "field=value&field=value&..." 
Rating:
Rating: 4 , Number of votes: 3 
Contributor:
John Smart 
Category:
Lotusscript 
Type:
String functions 
Document Release:
1.03 
Notes Version:
R4.x, R6.x, R8.x, R5.x, R7.x 
Last Modified:
02 Jan 2008 
OpenNTF Disclaimer

All of the program code and information presented in the OpenNTF.org Code Bin are provided "as-is", and should be used at your own risk. OpenNTF.org make no express or implied warranty about anything in the Code Bin, and OpenNTF.org will not be responsible or liable for any damage caused by the use or misuse of anything from this site. OpenNTF.org makes no guarantees about anything. Please thoroughly test all of the knowledge and code you find here before you attempt to use them in your production environment.

Code / Description
Public Class RequestContentParser
 Private psRC As String
 Private piAmpPos As Integer
 
 Sub new(Byval sRequest_Content As String)
  psRC = sRequest_Content
  piAmpPos = 0
 End Sub
 
 Private Function Unescape(Byval s As String) As String
  Dim iPercent As Integer
  Dim iPlus As Integer
  Dim sL As String
  Dim sM As String
  Dim sR As String
  
  iPercent = Instr(s,"%")
  iPlus = Instr(s,"+")
  If iPlus = 0 Then
   If iPercent = 0 Then 'neither percent nor plus was found.
    Unescape = s
   Else 'plus not found, deal with percent
    sL = Left$(s,iPercent-1)
    sM = Mid$(s,iPercent+1,2)
    sR = Mid$(s, iPercent+3)
    Unescape = sL + Chr$(Cint("&h" & sM)) + Unescape(sR)
   End If
  Elseif iPercent = 0 Or iPlus < iPercent Then 'percent doesn't exist or plus comes before percent, deal with plus
   sL = Left$(s, iPlus - 1)
   sR = Mid$(s, iPlus + 1)
   Unescape = sL + " " + Unescape(sR)
  Else 'percent comes before plus, deal with percent
   sL = Left$(s,iPercent-1)
   sM = Mid$(s,iPercent+1,2)
   sR = Mid$(s, iPercent+3)
   Unescape = sL + Chr$(Cint("&h" & sM)) + Unescape(sR)
  End If
 End Function
 
 Public Function GetNextField(sFieldName As String, sValue As String) As Variant 'boolean, true if successful, false if no more fields
  Dim iEqPos As Integer
  Dim iFieldPos As Integer
  
  On Error 1 Goto ErrorSub
  If piAmpPos = -1 Then Error 1
  iFieldPos = piAmpPos + 1
  iEqPos = Instr(iFieldPos, psRC, "=")
  If iEqPos = 0 Then Error 1
  sFieldName = Mid(psRC, iFieldPos, iEqPos - iFieldPos)
  piAmpPos = Instr(iEqPos, psRC, "&")
  If piAmpPos <> 0 Then
   sValue = Unescape(Mid(psRC, iEqPos + 1, piAmpPos - iEqPos - 1))
  Else
   sValue = Unescape(Mid(psRC, iEqPos + 1))
   piAmpPos = -1 'flag that there are no more fields
  End If
  GetNextField = True
ExitSub:
  Exit Function
ErrorSub:
  GetNextField = False
  Resume ExitSub
 End Function
 
 Public Function GetFieldValue(sFieldName As String) As String
  Dim iAmpPos As Integer
  Dim iFieldPos As Integer
  Dim iValPos As Integer
  Dim sValue As String
  
  iFieldPos = Instr("&" + psRC, "&" + sFieldName + "=")
  If iFieldPos = 0 Then
   GetFieldValue = ""
  Else
   iValPos = iFieldPos + 1 + Len(sFieldName)
   iAmpPos = Instr(iValPos, psRC, "&")
   If iAmpPos = iValPos Then
    GetFieldValue = ""
   Elseif iAmpPos = 0 Then 'bug fix, added 02-JAN-2008
    GetFieldValue = Unescape(Mid(psRC, iValPos))
   Else
    GetFieldValue = Unescape(Mid(psRC, iValPos, iAmpPos - iValPos))
   End If
  End If
 End Function
End Class
Usage / Example
When a browser posts a page to an agent, the field contents are in the Request_Content field.


A simple way to use this would be to view what the browser just submitted:

Set Session = New NotesSession
Set RCP = New RequestContentParser(Session.DocumentContext.Request_Content(0))
Do while RCP.GetNextField(sFieldName, sValue)
 Print sFieldName + { = "} + sValue + {"<br>}
Loop


To find a specific value, you'd use
sProduct = RCP.GetFieldValue("Product")

You can also use this class to loop through or find values in the Query_String string.

1.02 08-Aug-02 Fixed bug in unescape method

 Comments
Posted by Ronald de Heer on 10/16/2002 01:03:09 PMSeems a bit overkill
Seems a bit overkill when you can do this with a few lines of code. 'Function Function ParseValue(inputStr As String, valueStr As String) As String Dim newStr As String Dim startpoint As Integer, endpoint As Integer startpoint = Instr(1,inputStr,valueStr+"=") + Len(valueStr)+1 endpoint = Instr(startpoint,inputStr,"&") - startpoint newStr = Mid(inputStr,startpoint,endpoint) ParseValue = newStr End Function Example of use: For Agents that we call the through a URL and we pass arguments through the URL if we call an agent like this: http://webserver/directory/database/MyAgent?OpenAgent&MyValue1=123&MyValue2=987 Set doc = s.DocumentContext 'Gives you the document as you know content = doc.Query_String(0) & "&" 'Gives you the Query_String CGI value corrected with an ending string Value1 = ParseValue(content,"MyValue1") 'Gives you the desired value of "123" Value2 = ParseValue(content,"MyValue2") 'Gives you the desired value of "987"
Posted by John Smart on 10/22/2002 03:30:49 PMI'd agree, except...
Posted by Konstantin Koval on 01/23/2003 09:12:55 AMOther
Public Class RequestContentParser Private list_elements_content List As String Private currentLog As NotesLog Sub new(sRequest_Content As Variant) On Error Goto errorhandler On Error Goto errh Dim concated_pairs As Variant,split_conc As Variant Set Me.currentLog = New NotesLog( "MyParser" ) Call Me.currentLog.OpenNotesLog( "", "agentlog.nsf" ) Forall ccc In sRequest_Content Call Me.currentLog.LogAction(" content " & ccc) concated_pairs =Split( ccc,"&") Forall in_tags In concated_pairs split_conc = Split( in_tags,"=") If Ubound(split_conc) > 0 Then Me.list_elements_content(split_conc(0))=Unescape(split_conc(1)) End Forall End Forall Exit Sub errorhandler: Call Me.currentLog.LogError( Me.currentLog.NumErrors, " :"+Error(Err()) + ". Line: " + Cstr(Erl()) ) Call Me.currentLog.Close Exit Sub errh : Msgbox " : "+Error(Err()) + ". Line: " + Cstr(Erl()) End Sub Public Property Get GetFieldValue(sFieldName As String) As String On Error Goto errorhandler If Iselement(Me.list_elements_content(sFieldName) ) Then GetFieldValue = Me.list_elements_content(sFieldName) Else GetFieldValue="" End If Exit Property errorhandler: Msgbox( " GetFieldValue Lib: MyParser, class RequestContentParser :"+Error(Err()) + ". Line: " + Cstr(Erl()) ) End Property End Class
Posted by John Smart on 07/03/2003 09:11:36 AMI'd agree, except...
What I originally created it for was to iterate through an unknown number of fields on the submitted page. For example, I wrote a quick order form that had a quantity field for each product in a database. In that case, I did a (LotusScript version of a)dblookup to the products database and made passthru html for each field and label, with each quantity field's name being the id of its product document. The user would fill out the web page and submit it into an agent that used this code to receive and parse the returned info appropriately. In this case, I needed something that would iterate through an unknown number of unknown label-value pairs, and I wanted code that was easily portable. Writing the GetFieldValue method to simply get a value given a known label was just an afterthought for me... plus it's more robust. Your version breaks if you go after MyValue or NonExistingLabel.
Posted by George Bennett on 04/02/2004 07:27:46 AMGood but doesn't handle multivalues
Like checkbox, select mutli fields, the following modification returns an array of values from the GetFieldValues(sFieldName) function, if sFieldName is null or doesn't exist a single value array of "" is returned, just like accessing field values on a form.
Hope this helps, George:
Public Class RequestContentParser
Private psRC As String
Private piAmpPos As Integer
Private iTempPrev As Integer ' tracks where the last field value was...
Sub new(Byval sRequest_Content As String)
psRC = sRequest_Content
piAmpPos = 0
End Sub
Private Function Unescape(Byval s As String) As String
Dim iPercent As Integer
Dim iPlus As Integer
Dim sL As String
Dim sM As String
Dim sR As String
iPercent = Instr(s,"%")
iPlus = Instr(s,"+")
If iPlus = 0 Then
If iPercent = 0 Then 'neither percent nor plus was found.
Unescape = s
Else 'plus not found, deal with percent
sL = Left$(s,iPercent-1)
sM = Mid$(s,iPercent+1,2)
sR = Mid$(s, iPercent+3)
Unescape = sL + Chr$(Cint("&h" & sM)) + Unescape(sR)
End If
Elseif iPercent = 0 Or iPlus < iPercent Then 'percent doesn't exist or plus comes before percent, deal with plus
sL = Left$(s, iPlus - 1)
sR = Mid$(s, iPlus + 1)
Unescape = sL + " " + Unescape(sR)
Else 'percent comes before plus, deal with percent
sL = Left$(s,iPercent-1)
sM = Mid$(s,iPercent+1,2)
sR = Mid$(s, iPercent+3)
Unescape = sL + Chr$(Cint("&h" & sM)) + Unescape(sR)
End If
End Function
Public Function GetFieldValues(sFieldName As String) As Variant 'rtns an array, if null then returns single value in array of value ""
'lets return an array of field values
Dim rtn() As String
Redim rtn(0) As String
iTempPrev = 1
Dim tmpString As String
tmpString = GetNextFieldValue(sFieldName)
Dim i As Integer
i = 0
If tmpString = "" Then
rtn(i) = ""
Else
While Not tmpString = ""
Redim Preserve rtn(i)
rtn(i) = tmpString
i = i+1
tmpString = GetNextFieldValue(sFieldName)
Wend
End If
GetFieldValues = rtn
End Function
Private Function GetNextFieldValue(sFieldName As String) As String
Dim iAmpPos As Integer
Dim iFieldPos As Integer
Dim iValPos As Integer
Dim sValue As String
iFieldPos = Instr( iTempPrev, "&" + psRC, "&" + sFieldName + "=")
If iFieldPos = 0 Then
GetNextFieldValue = ""
Else
iValPos = iFieldPos + 1 + Len(sFieldName)
iAmpPos = Instr(iValPos, psRC, "&")
iTempPrev = iValPos
If iAmpPos = iValPos Then
GetNextFieldValue = ""
Elseif iAmpPos < iValPos Then 'its the last value in the string....
GetNextFieldValue = Unescape(Mid(psRC, iValPos))
Else
GetNextFieldValue = Unescape(Mid(psRC, iValPos, iAmpPos - iValPos))
End If
End If
End Function
End Class
Posted by Barna Kovács on 05/04/2007 11:50:27 AMSimpler replacement for Unescape function
Dear John,
your code was really helpful for me, I would like to thank you.
However, Unescape is written in a recursive manner, which caused problems processing larger text entries. So I have written a replacement for it. It uses the StringBuffer class available on the NSFTools page (http://www.nsftools.com/tips/NotesTips.htm#stringbuffer)
I admit that my solution is a bit slow after a certain size of textarea processing, but it works.
Here it is:
Private Function Unescape(Byval s As String) As String
Dim i As Integer
Dim out As New StringBuffer(50)
Dim char As String
i=1
While i<=Len(s)
char=Mid(s,i,1)
If char="%" Then
out.append(Chr$(Cint("&h" & Mid(s,i+1,2))))
i=i+2
Elseif char="+" Then
out.append(" ")
Else
out.append(char)
End If
i=i+1
Wend
Unescape=out.toString
End Function
 Add your comment!