« Search all scripts wi… | Home | Translation Framework… »

Saxon Visualize electronic Invoices in Xojo

When you receive an electronic invoice in the formats ZUGFeRD, Factur-X, X-Rechnung or UBL, you may need to visualize the XML file in your Xojo application. You can use our DynaPDF classes to extract the XML from the ZUGFeRD invoice. Once you have the XML for one of the formats UBL or Cross Industry Invoice, you may want to convert it to HTML and show it in a HTMLviewer.

We leverage the XRechnung Visualization Transformators project from GitHub. This project has a couple of XML stylesheets to convert our invoices to HTML. For this they first convert the UBL or CII XML to an intermediate XML and finally convert that to XML with a second transformation. There is also an alternative output to produce a XML for Apache FOP to make it a PDF file.

Step 1: Load Saxon

First load the Saxon library using our SaxonMBS module. You download the libraries either from our website or directly from Saxonica website. We suggest to copy the Saxon library to the same folder as the plugin. Then you only need to pass the library file name to load it. 

// load library #If TargetMacOS Var path As String = "/Users/cs/Libs/saxon/SaxonCEE-12.9/SaxonCEE-macos-universal-12-9-0/libsaxonc-core-ee.12.9.0.dylib" #ElseIf TargetWindows Var path As String = "saxonc-core-ee.dll" #ElseIf TargetLinux Then Var path As String = "libsaxonc-core-ee.so.12.9.0" #Else // not supported #EndIf Var bb As Boolean = SaxonMBS.LoadLibrary(path) // we have libraries here: // https://www.monkeybreadsoftware.com/filemaker/files/Libs/Saxon/ If bb Then // okay Else MessageBox "Failed to load Saxon library. Did you download it and adjust path in this example?"_ +EndOfLine+SaxonMBS.LoadErrorString Break Return End If

Step 2: Check the type

The main script loads Saxon if needed. Then we check if we got the folder with the xrechnung-visualization xsl files. You download the release of xrechnung-visualization, unpack the zip/tar file and then tell our plugin the native path to the xsl folder, e.g. "/Users/cs/xrechnung-3.0.2-xrechnung-visualization-2024-06-20/xsl".

We check the content of the XML and if it contains the namespace declaration for UBL, we use the ubl-invoice-xr.xsl stylesheet to transform the XML. But if we find the CrossIndustryInvoice namespace, we can use the cli-xr.xsl stylesheet instead and call the Run method.

// you can use DynaPDF functions to extract XML from PDF Var f As FolderItem = FolderItem.ShowOpenFileDialog(FileTypeGroup1.XML) If f = Nil Then Return Var b As BinaryStream = BinaryStream.Open(f) Var XML As String = b.Read(b.Length, encodings.UTF8) // is it an UBL or CII file? If XML.InStr("urn:oasis:names:specification:ubl:schema:xsd:Invoice") > 0 Then Run XML, UBLFile elseif XML.InStr("unece:uncefact:data:standard:CrossIndustryInvoice") > 0 Then Run XML, CIIFile End If

Step 3: Perform conversion

In the following script we perform the transformation. We first set the working directory to the xsl folder, so the related files referenced by the stylesheet can be found. Technically you could resolve this and make it one big stylesheet, but we just use them as they are. And the stylesheets need the common-xr.xsl file with common transformations. We read the XSLT to use and apply it on the invoice XML. When we get that XML, we can apply the stylesheet xrechnung-html.xsl to create the HTML using the XSLT convenience function in SaxonMBS module. When we store the HTML in the field, our web viewer shows it.

Sub Run(XML as string, XSLFile as FolderItem) // Apply XSLT to create html and show invoice. // Set the folder to find related files SaxonMBS.CWD = XSLFolder.NativePath // read the XSLT to convert Var b As BinaryStream = BinaryStream.Open(XSLFile) Var styleSheet As String = b.Read(b.Length, Encodings.UTF8) // Apply the XSLT // we use the quick function here. For more options use Xslt30ProcessorMBS class. var IntermediateXML as string = SaxonMBS.XSLT(XML, styleSheet) // now read second XSL to convert to html var xf as FolderItem = XSLFolder.Child("xrechnung-html.xsl") Var b2 As BinaryStream = BinaryStream.Open(xf) Var HTMLXSLT As String = B2.Read(b2.Length, encodings.UTF8) // Generate the HTML var InvoiceHTML as string = SaxonMBS.XSLT(IntermediateXML, HTMLXSLT) HTMLViewer1.LoadPage InvoiceHTML, xf End Sub

To have the Xojo HTMLViewer show the html, we call LoadPage method and pass the html. To clear the HTMLViewer, you can load "about:blank" to see an empty page.

If you need more control, you can use Xslt30ProcessorMBS class and set various properties and options. Then call transform yourself there.

Please try and let us know if you like it. You may want to modify the stylesheet if you prefer a different style. Our Saxon classes are in the MBS Xojo XML Plugin.

06 01 26 - 14:13