Platforms to show: All Mac Windows Linux Cross-Platform
/XML/Saxon/Saxon ZUGFeRD Validation
Required plugins for this example: MBS XML Plugin, MBS Util Plugin
You find this example project in your MBS Xojo Plugin download as a Xojo project file within the examples folder: /XML/Saxon/Saxon ZUGFeRD Validation
Download this example: Saxon ZUGFeRD Validation.zip
Project "Saxon ZUGFeRD Validation.xojo_binary_project"
Class App Inherits DesktopApplication
Const kEditClear = "&Delete"
Const kFileQuit = "&Quit"
Const kFileQuitShortcut = ""
EventHandler Sub Opening()
// License code registration could be done here
End EventHandler
EventHandler Function UnhandledException(error As RuntimeException) As Boolean
If error IsA SaxonExceptionMBS Then
System.DebugLog error.Message
MessageBox error.Message
Return True
End If
End EventHandler
End Class
Class MainWindow Inherits DesktopWindow
Const XSLT1 = "<?xml version=""1.0"" encoding=""UTF-8""?>\n<xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" xmlns:svrl=""http://purl.oclc.org/dsdl/svrl"" version=""1.0"">\n <!-- Match the root element -->\n <xsl:template match=""/svrl:schematron-output"">\n <html>\n <head>\n <title>SVRL Report</title>\n <style>\n body {\n font-family: Arial, sans-serif;\n margin: 20px;\n }\n h1 {\n text-align: center;\n }\n .point {\n margin-bottom: 20px;\n padding: 10px;\n border: 1px solid #ccc;\n border-radius: 5px;\n }\n .point h2 {\n color: #2a5d84;\n font-size: 18px;\n margin: 0;\n }\n .point p {\n margin: 5px 0;\n }\n </style>\n </head>\n <body>\n <!-- Apply template to each failed-assert element -->\n <xsl:for-each select=""svrl:failed-assert"">\n <div class=""point"">\n <!-- ID as headline -->\n <h2>\n <xsl:value-of select=""@id""/>\n </h2>\n <!-- Text below ID -->\n <p>\n <xsl:value-of select=""svrl:text""/>\n </p>\n </div>\n </xsl:for-each>\n </body>\n </html>\n </xsl:template>\n</xsl:stylesheet>\n"
Const XSLT2 = "<?xml version=""1.0"" encoding=""UTF-8""?>\n<xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" xmlns=""http://saxon.sf.net/ns/validation"" version=""1.0"">\n <!-- Output HTML -->\n <xsl:output method=""html"" encoding=""UTF-8"" doctype-public=""-//W3C//DTD HTML 4.01//EN"" doctype-system=""http://www.w3.org/TR/html4/strict.dtd""/>\n <!-- Template to match the root element and begin the HTML structure -->\n <xsl:template match=""/"">\n <html>\n <head>\n <title>Validation Report</title>\n <style>\n body {\n font-family: Arial, sans-serif;\n margin: 20px;\n color: #333;\n }\n h1 {\n color: #E74C3C;\n }\n ul {\n list-style-type: none;\n padding: 0;\n }\n li {\n background-color: #F9E1E1;\n border: 1px solid #E74C3C;\n margin-bottom: 10px;\n padding: 10px;\n }\n .path {\n font-weight: bold;\n color: #C0392B;\n overflow-wrap: break-word; \n }\n .message {\n color: #7F8C8D;\n overflow-wrap: break-word; \n }\n </style>\n </head>\n <body>\n <!-- Title -->\n <h1>Validation Report - <xsl:value-of select=""//*[local-name()='results']/@errors""/> Errors</h1>\n <!-- Error List -->\n <ul>\n <xsl:for-each select=""//*[local-name()='error']"">\n <li>\n <div class=""path"">\n <xsl:value-of select=""./text()""/>\n </div>\n <div class=""message"">\n <xsl:value-of select=""@path""/>\n </div>\n </li>\n </xsl:for-each>\n </ul>\n </body>\n </html>\n </xsl:template>\n</xsl:stylesheet>\n"
Control LoadButton Inherits DesktopButton
ControlInstance LoadButton Inherits DesktopButton
EventHandler Sub Pressed()
// 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)
InvoiceTextArea.Text = xml
End EventHandler
End Control
Control InvoiceTextArea Inherits DesktopTextArea
ControlInstance InvoiceTextArea Inherits DesktopTextArea
End Control
Control ValidateLibXMLButton Inherits DesktopButton
ControlInstance ValidateLibXMLButton Inherits DesktopButton
EventHandler Sub Pressed()
Var f As FolderItem = XSLFolder.Child("Factur-X_1.07.2_EN16931.xsd")
If f <> Nil And f.Exists Then
// read the XSD file into a variable
Var b As BinaryStream = BinaryStream.Open(f)
Var xsd As String = b.Read(b.Length, encodings.UTF8)
// set current working directory, so related files can be found
Call SetCurrentWorkingDirectoryMBS XSLFolder
// invoice from the text area
var InvoiceXML as string = InvoiceTextArea.Text
// we have a subclass to collect error messages from Error/Warning events
Var v As New XMLValidator(f)
// run the validation of the invoice
Var e As Integer = v.ValidateString(InvoiceXML)
// show errors if we got one
If e = 0 Then
MessageBox "Okay"
ResultTextArea.Text = "Okay"
Else
ResultTextArea.Text = Join(v.Errors, EndOfLine)
end if
Else
MessageBox "Factur-X_1.07.2_EN16931.xsd file not found!?"
End If
End EventHandler
End Control
Control ValidateStructureButton Inherits DesktopButton
ControlInstance ValidateStructureButton Inherits DesktopButton
EventHandler Sub Pressed()
// Validate the structure of the invoice against the schema file
Var SchemaFile As FolderItem = XSLFolder.Child("Factur-X_1.07.2_EN16931.xsd")
If SchemaFile <> Nil And SchemaFile.Exists Then
Var b As BinaryStream = BinaryStream.Open(SchemaFile)
Var schemaXML As String = b.Read(b.Length, encodings.UTF8)
// set current working directory, so related files can be found
SaxonMBS.CWD = XSLFolder.NativePath
// run validation
Var InvoiceXML As String = InvoiceTextArea.Text
try
Var r As Boolean = SaxonMBS.Validate(InvoiceXML, schemaXML)
Catch s As SaxonExceptionMBS
// failed to validate
System.DebugLog s.Message
end try
Var report As String = SaxonMBS.ValidationReport
ResultTextArea.Text = report
Var html As String
If report.len > 0 Then
html = SaxonMBS.XSLT(report, XSLT2)
Else
html = "<p>Failed. No EE-V license?</p>"
end If
HTMLViewer1.LoadPage html, XSLFolder
Else
MessageBox "Factur-X_1.07.2_EN16931.xsd file not found!?"
End If
End EventHandler
End Control
Control ValidateContentButton Inherits DesktopButton
ControlInstance ValidateContentButton Inherits DesktopButton
EventHandler Sub Pressed()
// Validate Content With Saxon In file Saxon ZUGFeRD Validation
// We read the XSLT needed To Do validation
Var f As FolderItem = XSLFolder.Child("FACTUR-X_EN16931.xslt")
If f <> Nil And f.Exists Then
Var b As BinaryStream = BinaryStream.Open(f)
Var xslt As String = b.Read(b.Length, encodings.UTF8)
// check count If you like To know how many rules you have
var namespaces() as string = Array("svrl", "http://purl.oclc.org/dsdl/svrl")
Var query As String = "count(//svrl:failed-assert)"
Var countRules As Integer = xslt.CountFields("<svrl:failed-assert")-1
// we need To set where To find related files. Some functions don't work with paths containing spaces
SaxonMBS.CWD = XSLFolder.NativePath
// perform check
Var InvoiceXML As String = InvoiceTextArea.Text
Var report As String = SaxonMBS.XSLT(InvoiceXML, xslt)
ResultTextArea.Text = report
if report <> "" then
// check count If you like To know how many rules you have
Var countFailed As Integer = report.CountFields("<svrl:failed-assert")-1
// convert report To html
Var html As String = SaxonMBS.XSLT(report, XSLT1)
HTMLViewer1.LoadPage html, XSLFolder
MessageBox "Check completed." + EndOfLine + EndOfLine + countFailed.ToString + " of " + countRules.tostring + " rules failed."
End If
Else
MessageBox "Failed to find FACTUR-X_EN16931.xslt file."
end if
End EventHandler
End Control
Control ResultTextArea Inherits DesktopTextArea
ControlInstance ResultTextArea Inherits DesktopTextArea
End Control
Control HTMLViewer1 Inherits DesktopHTMLViewer
ControlInstance HTMLViewer1 Inherits DesktopHTMLViewer
End Control
Control PickFolderButton Inherits DesktopButton
ControlInstance PickFolderButton Inherits DesktopButton
EventHandler Sub Pressed()
// you need to download ZUGFeRD files with the schema folder.
Var folder As FolderItem = FolderItem.ShowSelectFolderDialog
If folder <> Nil Then
// you may need to update the file name if the xsd file gets a newer name
Var f As FolderItem = folder.Child("Factur-X_1.07.2_EN16931.xsd")
If f <> Nil And f.Exists Then
XSLFolder = folder
ValidateContentButton.Enabled = True
ValidateLibXMLButton.Enabled = True
ValidateStructureButton.Enabled = True
Else
MessageBox "Factur-X_1.07.2_EN16931.xsd file not found!?"
End If
End If
End EventHandler
End Control
EventHandler Sub Opening()
#If DebugBuild Then
var Folder as FolderItem = GetFolderItem("Schema")
Var f As FolderItem = folder.Child("Factur-X_1.07.2_EN16931.xsd")
If f <> Nil And f.Exists Then
XSLFolder = folder
ValidateStructureButton.Enabled = True
ValidateContentButton.Enabled = True
ValidateLibXMLButton.Enabled = True
End If
Var d As FolderItem = GetFolderItem("factur-x.xml")
If d <> Nil And d.Exists then
Var b As BinaryStream = BinaryStream.Open(d)
Var XML As String = b.Read(b.Length, encodings.UTF8)
InvoiceTextArea.Text = xml
end if
#EndIf
End EventHandler
Property XSLFolder As FolderItem
End Class
MenuBar MainMenuBar
MenuItem FileMenu = "&File"
MenuItem FileQuit = "#App.kFileQuit"
MenuItem EditMenu = "&Edit"
MenuItem EditUndo = "&Undo"
MenuItem EditSeparator1 = "-"
MenuItem EditCut = "Cu&t"
MenuItem EditCopy = "&Copy"
MenuItem EditPaste = "&Paste"
MenuItem EditClear = "#App.kEditClear"
MenuItem EditSeparator2 = "-"
MenuItem EditSelectAll = "Select &All"
MenuItem WindowMenu = "Window"
MenuItem HelpMenu = "&Help"
End MenuBar
Sign
End Sign
Class XMLValidator Inherits XMLValidatorMBS
EventHandler Sub Error(message as XMLValidatorMessageMBS)
Errors.Add "Error: "+message.Message
End EventHandler
EventHandler Sub Warning(message as XMLValidatorMessageMBS)
Errors.Add "Warning: "+message.Message
End EventHandler
Property Errors() As String
End Class
FileTypeGroup1
Filetype XML
End FileTypeGroup1
End Project
See also:
- /XML/Saxon/Saxon test
- /XML/Saxon/Saxon Visualize electronic Invoices/Saxon Visualize electronic Invoices
- /XML/Saxon/Saxon Visualize electronic Invoices/Saxon Visualize electronic Invoices Web
Download this example: Saxon ZUGFeRD Validation.zip
The items on this page are in the following plugins: MBS XML Plugin.