B4J Question XML validation with multiple XSD

rosippc64a

Active Member
Licensed User
Hi All!
I used some code found here to validate an xml.
B4X:
    XMLconstants.InitializeStatic("javax.xml.XMLConstants")
    SchemaFactory.InitializeStatic("javax.xml.validation.SchemaFactory")
    factory = SchemaFactory.RunMethod("newInstance",Array(XMLconstants.GetField("W3C_XML_SCHEMA_NS_URI")))
    xsd.InitializeNewInstance("java.io.File",Array(xsdFile))
    xml.InitializeNewInstance("java.io.File",Array(xmlFile))
    Schema = factory.RunMethod("newSchema",Array As Object(xsd))
    Validator = Schema.RunMethod("newValidator",Null)
    StreamSource.InitializeNewInstance("javax.xml.transform.stream.StreamSource",Array(xml))
    Validator.RunMethod("setErrorHandler",Array(Validator.CreateEvent("org.xml.sax.ErrorHandler","xmlerr",Null)))
    Validator.RunMethod("validate",Array(StreamSource))
That worked well, but now I had to validate one xml file with two xsd file. I found, that would be simple:
B4X:
    XMLconstants.InitializeStatic("javax.xml.XMLConstants")
    SchemaFactory.InitializeStatic("javax.xml.validation.SchemaFactory")
    factory = SchemaFactory.RunMethod("newInstance",Array(XMLconstants.GetField("W3C_XML_SCHEMA_NS_URI")))
    xsd.InitializeNewInstance("java.io.File",Array(xsdFile))
    xsd2.InitializeNewInstance("java.io.File",Array(xsdFile2))
    xml.InitializeNewInstance("java.io.File",Array(xmlFile))
    Schema = factory.RunMethod("newSchema",Array As Object(xsd2,xsd))
    Validator = Schema.RunMethod("newValidator",Null)
    StreamSource.InitializeNewInstance("javax.xml.transform.stream.StreamSource",Array(xml))
    Validator.RunMethod("setErrorHandler",Array(Validator.CreateEvent("org.xml.sax.ErrorHandler","xmlerr",Null)))
    Validator.RunMethod("validate",Array(StreamSource))
because of
B4X:
Schema = factory.RunMethod("newSchema",Array As Object(xsd2,xsd))
has array parameter. But not.
I got error message: java.lang.RuntimeException: Method: newSchema not matched.
I found a code, how to give multiple parameter, but this is in java:
B4X:
Schema schema = factory().newSchema(new Source[] {
  new StreamSource(stream("foo.xsd")),
  new StreamSource(stream("Alpha.xsd")),
  new StreamSource(stream("Mercury.xsd")),
});
How can I translate it into B4J?
Thanks in advance
Steven
 

rosippc64a

Active Member
Licensed User
Ok, works. I had to write a main xsd file, what imports namespaces and xsd files.
The XXX from the xs:import namespace="XXX" is in the relevant xsd file <xs:schema xmlns="XXX" ...

B4X:
Sub ValidateFile(xsdFile As String,xsdFile2 As String,xsdFile3 As String,xmlFile As String,ptxw As TextWriter) As ResumableSub
    ErrorList.Initialize
    XMLconstants.InitializeStatic("javax.xml.XMLConstants")
    SchemaFactory.InitializeStatic("javax.xml.validation.SchemaFactory")
    factory = SchemaFactory.RunMethod("newInstance",Array(XMLconstants.GetField("W3C_XML_SCHEMA_NS_URI")))
    File.WriteString(File.DirTemp,"main.xsd",$"<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
targetNamespace="http://schemas.nav.gov.hu/OSA/1.0/common">
<xs:import namespace="http://schemas.nav.gov.hu/OSA/3.0/data" schemaLocation="${xsdFile}"/>
<xs:import namespace="http://schemas.nav.gov.hu/NTCA/1.0/common" schemaLocation="${xsdFile2}"/>
<xs:import namespace="http://schemas.nav.gov.hu/OSA/3.0/base" schemaLocation="${xsdFile3}"/>
</xs:schema>
    "$)
    xsd.InitializeNewInstance("java.io.File",Array(File.Combine(File.DirTemp,"main.xsd")))
    xml.InitializeNewInstance("java.io.File",Array(xmlFile))
    Schema = factory.RunMethod("newSchema",Array(xsd))
    Validator = Schema.RunMethod("newValidator",Null)
    StreamSource.InitializeNewInstance("javax.xml.transform.stream.StreamSource",Array(xml))
    Validator.RunMethod("setErrorHandler",Array(Validator.CreateEvent("org.xml.sax.ErrorHandler","xmlerr",Null)))
    Validator.RunMethod("validate",Array(StreamSource))

    If ErrorList.Size > 0 Then
'        For Each i As Object In ErrorList
'            Log("Error "&i)
'        Next
        'Technical error report
        For a = 0 To ErrorList.Size-2 Step 2
            ptxw.WriteLine(ErrorList.Get(a))
            Log(ErrorList.Get(a))
        Next
        Return False
    End If
    Return True
End Sub
 
Last edited:
Top