lørdag den 7. december 2013

LibreOffice har nu indbygget XML-parser

LibreOffice benytter som bekendt et XML-baseret dokumentformat, så naturligvis er der en indbygget parser. Men hidtil har det været temmelig besværligt at arbejde med XML i f.eks. makroer eller regneark. I en makro er det f.eks. nødvendigt manuelt at tygge sig igennem XML-strukturen for at finde den rette information. Eksemplet herunder viser hvor besværligt det er at arbejde med (tak til Andrew Pitonyak):

Function CreateDocumentHandler()
oDocHandler = CreateUnoListener( "DocHandler_", "com.sun.star.xml.sax.XDocumentHandler" )
glLocatorSet = False
CreateDocumentHandler() = oDocHandler
End Function

'==================================================
' Methods of our document handler call these
' global functions.
' These methods look strangely similar to
' a SAX event handler. ;-)
' These global routines are called by the Sax parser
' as it reads in an XML document.
' These subroutines must be named with a prefix that is
' followed by the event name of the com.sun.star.xml.sax.XDocumentHandler interface.
'==================================================

Sub DocHandler_characters( cChars As String )

if xNode = "lipsum" then
oWrite=1
cChars= Left(cChars,len(cChars)-1)
if len(cChars)>1 then
cChars= cChars+ Chr$(13)
else
cChars=cChars
endif
WriteLoremipsum (cChars, oWrite)
Else oWrite=0
Endif
End Sub

Sub DocHandler_ignorableWhitespace( cWhitespace As String )
End Sub

Sub DocHandler_processingInstruction( cTarget As String, cData As String )
End Sub

Sub DocHandler_startDocument()
End Sub

Sub DocHandler_endDocument()
End Sub

Sub DocHandler_startElement( cName As String, oAttributes As com.sun.star.xml.sax.XAttributeList )
xNode = cName
End Sub

Sub DocHandler_endElement( cName As String )
End Sub

Sub DocHandler_setDocumentLocator( oLocator As com.sun.star.xml.sax.XLocator )
' Save the locator object in a global variable.
' The locator object has valuable methods that we can
' call to determine
goLocator = oLocator
glLocatorSet = True
End Sub

Eksemplet herover er fra udvidelsen Lorem Ipsum generator som kan downloades her: http://extensions.libreoffice.org/extension-center/magenta-lorem-ipsum-generator

Fra LibreOffice 4.2 bliver det meget lettere at tilgå XML-data ved hjælp af to nye funktioner i regneark, nemlig WEBSERVICE og FILTERXML. Fra en makro er det så muligt at benytte de pågældende regnearksfunktioner, også selv om det ikke er et regneark, der er aktuelt dokument.

Eksemplet herunder resulterer i store træk i samme resultat, som koden herover

Sub Main
svc = createUnoService( "com.sun.star.sheet.FunctionAccess" ) 'Create a service to use Calc functions
XML_String = svc.callFunction("WEBSERVICE",array("http://www.lipsum.com/feed/xml?amount=2&what=paras&start=Yes"))
Lipsum = svc.callFunction("FILTERXML", array(XML_String, "/feed/lipsum" ))
Print Lipsum
End Sub


Jeg ser virkelig frem til at arbejde med disse smarte nye funktioner.