Use @Transform to build JSON and consume the output in an XAgent


Put this piece of code into a view column; in _exclude list all items from the document, that should not be included in the output
All items in the document that are not excluded are used to build a JSON String 

=========================== @Formula START =========================================

_exclude:="$FILE":"$Fonts":"Form":"$UpdatedBy":"$Revisions":"ID":"ModifiedBy":"AddressInvoiceAppartment";
_fld:=@Trim(@ReplaceSubstring(@DocFields;_exclude;@Nothing));

"{\"@unid\":\""
+@Text(@DocumentUniqueID)+"\","
+ @Implode (
@Transform (
_fld; "_fn" ; "\"" + _fn + "\":\"" + @Text ( @GetField ( _fn) ) + "\"" ) ; "," ) +
"},"

=========================== @Formula  END=========================================

To retrieve the JSON string, create a new XAgent

=========================== XAgent START=========================================

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" rendered="false">
	<xp:this.afterRenderResponse><![CDATA[#{javascript:try{
	var externalContext = facesContext.getExternalContext();
	var writer = facesContext.getResponseWriter();
	var response = externalContext.getResponse();
	  
	// Set content type	
	response.setContentType("application/json");	 
	response.setHeader("Cache-Control", "no-cache");
	var json:java.lang.StringBuilder = new java.lang.StringBuilder();
	var v:NotesView = database.getView("($jsonContact)");
	//do not do AutoUpdates
	v.AutoUpdate = false;
	var nav:NotesViewNavigator = v.createViewNav();
	nav.setEntryOptions(
	NotesViewNavigator.VN_ENTRYOPT_NOCOUNTDATA);
	//enable cache for max buffering
	nav.BufferMaxEntries = 400
	var entry:NotesViewEntry = nav.getFirst();

	while (entry != null) {
		json.append( entry.getColumnValues().elementAt(0).toString());
		var tmpentry:NotesViewEntry = nav.getNext(entry);
		entry.recycle();
		entry = tmpentry;
	}

	writer.write('[' + @Left(json.toString(), @Length(json.toString()) - 1) + ']');	 
	writer.endDocument();
} catch(e){
	_dump(e);	
}}]]>
	</xp:this.afterRenderResponse>
</xp:view>

=========================== XAgent END =========================================

The XAgent uses a ViewNavigator for fast retrieval of the column entries. The real magic is the use of java.lang.StringBuilder() to concat the view entries. A stringBuilder is the fastest way to concat a large number of strings. It is faster than just to use string1 + string2 

UPDATE:

Here is an enhancement, if you want to fetch the column values with Java

public class ViewColumn {
	private static final String MSG_STRING_ERROR = "ERROR: ";
	private static final String MSG_STRING_NOT_FOUND = " not found";

	public ViewColumn() {
	}
	
	public String getViewColumnValueJSON(String viewname, int pos) {
		ViewNavigator nav = null;
		StringBuilder json = new StringBuilder();
		json.append('[');
		String strValue = "";
		try {
			View view = getCurrentDatabase().getView(viewname);
			if (null != view) {
				view.setAutoUpdate(false);
				nav = view.createViewNav();
				nav.setEntryOptions(ViewNavigator.VN_ENTRYOPT_NOCOUNTDATA);
				nav.setBufferMaxEntries(400);
				ViewEntry entry = nav.getFirst();

				while (entry != null) {
					json.append( entry.getColumnValues().elementAt(pos).toString());
					ViewEntry tmpentry= nav.getNext(entry);
					entry.recycle();
					entry = tmpentry;
				}		
				strValue = json.toString();
				strValue = strValue.substring(0, strValue.lastIndexOf(",")) + "]";
				view.setAutoUpdate(true);
			} else {
				System.out.println(MSG_STRING_ERROR + viewname + MSG_STRING_NOT_FOUND);
			}
		} catch (NotesException e) {
			System.out.println(MSG_STRING_ERROR);
			strValue = "[{}]";
		}
		
		return strValue;

	}
}



All code submitted to OpenNTF XSnippets, whether submitted as a "Snippet" or in the body of a Comment, is provided under the Apache License Version 2.0. See Terms of Use for full details.
3 comment(s)Login first to comment...
sagar pat
(at 23:35 on 11.04.2016)
Love java languange.. Its like <a href="http://corporateofficehqinfo.com/mcdonalds-corporate-office/">mcdonalds </a> but way more good
jeniffer homes
(at 10:04 on 18.12.2015)
The real magic is the use of java.lang.StringBuilder() to concat the view entries. A stringBuilder is the fastest way to concat a large number of strings. It is faster than just to use string1 + string2
James George
(at 13:31 on 27.05.2015)
Thanks for your post...the code works great...I think multi-value fields are not working as expected...may be a tweak is needed for it.