Tuesday, July 17, 2007

LS XSL transformation from URL's (inc. https)

Most of this code is borrowed from a bloke named David Frahm. He posted that he had problems using the Microsoft.XMLDOM-object for transformation when the DB required authentication as a comment to Jakes article, "Putting Domino's XML to use", on Codestore.net.


I have been working with MSXML Parser in LotusScript agent for weeks now. Works great except with secure data. By that I mean that when the MSXML object requests a url from the domino server, it does not pass the userid/password and all I get back are documents that an Anonymous user would.

The post on codestore

The problem

I needed to transform 5-6 views to HTML-tables (reports) inside a form. Ajax wasn't an option, since the page that should contain the transformed views should be readable to both machine (DominoPDF) and man.

The database I was going to "read the view entries" from is on a secure server, which made it nearly impossible to use a Java-agent (from what I read on "the forum", you need to alter some settings in java security, make certificate, etc), which I thought was the only solution when transforming from URLs in Notes.

The solution

Simple function that takes three parameters in, and returns the result of the transformation:

Function transformXML( login As String, xml As String, xsl As String) As String
xml is the url to the XML to transform, e.g. http://your.domain.com/db.nsf/view?readviewentries

xsl is the url to the XSL-template, e.g. http://your.domain.com/db.nsf/transformview.xsl

Dim source As Variant, style As Variant
Set source = CreateObject( "Microsoft.XMLDOM" )
source.async = False

'login is optional. Only use when you need to authenticate on
'the server

'form of login-url:

If login <> "" Then
source.load( login )
End If

source.load( xml )

Set style = CreateObject( "Microsoft.XMLDOM" )
style.async = False
style.load( xsl )

If Not(source.parseError.errorCode = 0) Then
Error source.parseError.errorCode , source.parseError.reason
'transform source
transformXML = source.transformNode(style)
End If

'not sure if this is necessary to avoid memory leaks
Set style = Nothing
Set source = Nothing
End Function

Download in text-file below

I believe the code above can be used to convert from whatever source (rss, xhtml, application xml, etc), but I've only tested ?ReadViewEntries with https.

My use is a WebQueryOpen-agent that prints html to a RichText field in a form. The reports are collected from several categorized view, per user, "..?ReadViewEntries&RestrictToCategory=[userid]"

The agent currently transform 5-6 views. I also use WinHTTP.WinHTTPRequest.5.1 to get HTML from a document in the same report-form.

Function getHTML(url As String) As String
If Datatype ( httpobj ) = 0 Then 'ikke initialisert
Set httpobj = CreateObject("WinHTTP.WinHTTPRequest.5.1")
End If
Call httpobj.Open("GET", url,False)
' Send the HTTP Request.
Call httpobj.Send

getHTML = httpobj.ResponseText
Set httpobj = Nothing
End Function

The two functions in a text-file

I'm not sure if (server) performance is an issue on this application. But if it comes to that, I'll only run the WQO-agent if some parameter is in the url, e.g. "https://my.domain.no/application.nsf/report?openform&category=expenses&print", and use sarissa for web-clients.