Need Notes Document as XML

I would like to write an agent that will output a document as XML so some javascript can access that XML and find specific fields in it. The ultimate goal is to do some sort of AJAX DBLookup that would be able to lookup on field names (there are examples of that but they all return column values based ona a view and a ?ReadViewEntries URL).

What would be the best way to send the document’s DXL back to the calling JS?

Thanks

Subject: Need Notes Document as XML

Here is an example I wrote for lookups. Note that all that is happening here is string variables are being built for the return of the lookup to place them inside xml tags. Then this is all wrapped within xml tags for message and content (so I can return any errors easily). Then you simply parse your xml. The important stuff here is in TheEnd where the xml is formatted. This is probably faster than parsing all of the document fields in xml.

XML is, in the end, text. It doesn’t matter how you build it, from a view or an agent, just make sure you have it formatted correctly, and that your return handler is written correctly to parse the xml that you return from the agent.

Sub Initialize

'Messagebox "Entering agtGetData Agent"



On Error Goto ErrorHandler		



Call InstantiateObjectVariables 	'session, etc



'these must be local for the Replace or it crashes the client

Dim varQSparam As Variant

Dim varQSparamFieldName As Variant

Dim strLKey As String

Dim strLKeyFieldName As String



varQSparam = Evaluate(|@Middle(QUERY_STRING ; "&vendor=" ; "&")|, docContext)

varQSparamFieldName = Evaluate(|@Middle(QUERY_STRING ; "&keyfieldname=" ; "&")|, docContext)



strLKey = Fulltrim(varQSparam(0))

'strLKey = Fulltrim("13")	'Testing purposes only

strLKey = 	urlDecode(strLKey)



'replace + in strLKey with &



Dim strParam(0 To 0) As String

Dim strFrom(0 To 0) As String

Dim strTo(0 To 0) As String

Dim varDecoded As Variant



strParam(0) = strLKey

strFrom(0) = "_"

strTo(0) = "&"



Dim ret As Variant

ret = Replace(strParam, strFrom, strTo)

strLKey = Cstr(ret(0))



strLKeyFieldName = Fulltrim(varQSparamFieldName(0))

strLKeyFieldName = 	urlDecode(strLKeyFieldName)

'strLKeyfieldName = "VendorNum" 		'Testing Purposes only



If strLKeyFieldName = "VendorNum" Then

	Set view = lookupdb.GetView("By Vendor Number")

Else

	Set view = lookupdb.GetView("By Vendor")

End If



If view.Name = "By Vendor Number" Then

		'I just need one entry as these are a 1 to 1 relationship when using the vendornum

	

	Set entry = view.GetEntryByKey(strLKey, True)

	

	If entry Is Nothing Then

		strReturnMsg = "failure no document was found"	 + " " + strLKey + " " + view.Name

	Else

		strReturnMsg = strLKeyFieldName

		strReturnResults = "<vendordata>"

		

	'Print strReturnMsg

	'Print doc.cname(0) + " " + doc.cAccountnum(0) + " " + doc.cPhone(0)

		

	'build strReturnResults

	'get the data from column 2

		tmpString = entry.ColumnValues(1)

		tmpString = parseAmpersand(tmpString)

		strReturnResults = strReturnResults + 	tmpString + "</vendordata>"		

		

	End If

	

	Messagebox "Return String: " & strReturnMsg	& Chr$(10)  + Chr$(13) + strReturnResults

Else

	'I need to return all of the data found for the collection of documents returned by vendorname

	'Also, for each entry, return the information on the document so that I may populate a selectable div

	'that the entry will be chosen from (because multiple vendor numbers may be assigned to one name

	'and I need to be able to select the appropriate record.

	

	Set docColl = view.GetAllDocumentsByKey(strLKey, True) 'make it false if she wants a less specific return.

	

	If docColl Is Nothing Then

		Set docColl = view.GetAllDocumentsByKey(strLKey, False)	'try a less specific search

	End If

	

	Set doc = docColl.GetFirstDocument()

	If doc Is Nothing Then

		strReturnMsg = "failure the collection was empty "	 + Str(docColl.Count) + " ...key=" + strLKey + " ...view=" + view.Name

	Else

		

		strReturnMsg = strLKeyFieldName	' + " " + strLKey + " " + Cstr(docColl.Count)

		strReturnResults = "<vendordata>"

%REM

<vendornumber></vendornumber>

	<address1></address1>

	.. and so on

<vendornumber></vendornumber>

	<address1></address1>

	.. and so on

%END REM

'---------------------------------------------------------------------------------------------------------------------------------------------------

		While Not (doc Is Nothing)

			vAddr = parseAmpersand(doc.Address_1(0))

			

			If vAddr = "" Then

				'Just in case it fails

				vAddr = doc.Address_1(0)

			End If

			

			vNumber = "<vendornumber>" + Cstr(doc.Vendor_num(0)) + "</vendornumber>"

			vAddr =  "<address>" + vAddr + "</address>"

			vPhone =  "<phone>" + Trim(doc.Area(0)) + "   " + Trim(doc.Phone(0)) + "</phone>"

’ tmpString = tmpString + docnumber + vNumber + vAddr1+ vPhone + docnumberend

			tmpString = tmpString + vNumber + vPhone + vAddr

			Set doc = docColl.GetNextDocument(doc)

		Wend

		

		xmlString = tmpString

'---------------------------------------------------------------------------------------------------------------------------------------------------

		If Left$(xmlString, 5) = "error" Then

			strReturnMsg = "failure"	 + " " + strLKey + " " + xmlString

			xmlString = ""

		End If

	End If

	

	strReturnResults = strReturnResults + 	xmlString + "</vendordata>"

	Messagebox "Return String: " & strReturnMsg	& Chr$(10)  + Chr$(13) + strReturnResults

End If

TheEnd:

'The cache-control statement will prevent the xml from being cached on the page.

Print "Cache-Control: no-cache"



'Return the xml so it can be parsed by the javascript function on the form

Print {Content-Type: text/xml}	

Print {<?xml version="1.0" ?>}

Print {<vendorinfo>}	

Print {<message>}

Print strReturnMsg

Print {</message>}	

If strReturnResults <> "" Then

	Print strReturnResults

End If	

Print {</vendorinfo>}	

Exit Sub

ErrorHandler:

strReturnMsg = "error " & Error & " on line " & Erl

Messagebox "Return String: " & strReturnMsg		

Goto TheEnd

End Sub

Subject: RE: Need Notes Document as XML

Thanks Joel.

I had a feeling there was no other way than generate the XML through an agent.

I started working on this before I got your answer. I’ll post my code once it’s fully functional.

Onr thing I’m not sure though: how to pass several field names to the agent? For now, I’ll use a stupid thing like

…?openagent&view=myview&key=mykey&returnfields=field1~field2~field3…

I’ll parse the returnfields param in my agent. The XML will contain all the requested fields and then Javascript will do whatever it has to do with these values.

Thanks for the code!

: )

Subject: RE: Need Notes Document as XML

FYI:Here is the function I call to build the url and create the AJAX request. I am only passing a few fields, so a get works fine. If you need to pass all of your fields to the agent, use a post instead unless you are only using it for existing documents, then you should stick with the get and obtain a handle to the current document by the docunid. Less overhead than a post.

function LookupVendorNameNumber(field, fieldname){

//field is the value in the field that I am passing to the agent

//fieldname is the name of the field. This is used in the agent

//to handle flow control

if (field != ""){

	//Cannot pass an ampersand, so I am replacing it with an underscore.  The agent will convert it back.

	field = field.replace(/&/g,"_")

	var url = "agtGetData?openagent&vendor=" + field + "&keyfieldname="+fieldname;

	initRequest(url);

	

	if(fieldname == "VendorNum"){

		req.onreadystatechange = processNameRequest;

	}else{

		req.onreadystatechange = processNumbersRequest;

	}



	req.open("GET", url, true);

	req.send(null);

}

}