XML validation: Difference between revisions

Added FreeBASIC
(Added FreeBASIC)
 
(38 intermediate revisions by 20 users not shown)
Line 2:
 
Given an XML document and an XSD schema definition validate that the document follows the schema described.
 
Sample XML and XSD for tests can be found on [https://www.w3schools.com/xml/schema_example.asp this W3 Schools page].
 
=={{header|C}}==
{{libheader|LibXML}}
At the time of writing, the XML and XSD files at the URLs used in the other examples were inaccessible. The files from the W3 Schools page were used for tests.
<syntaxhighlight lang="c">
#include <libxml/xmlschemastypes.h>
 
int main(int argC, char** argV)
{
if (argC <= 2) {
printf("Usage: %s <XML Document Name> <XSD Document Name>\n", argV[0]);
return 0;
}
xmlDocPtr doc;
xmlSchemaPtr schema = NULL;
xmlSchemaParserCtxtPtr ctxt;
char *XMLFileName = argV[1];
char *XSDFileName = argV[2];
int ret;
 
xmlLineNumbersDefault(1);
 
ctxt = xmlSchemaNewParserCtxt(XSDFileName);
 
xmlSchemaSetParserErrors(ctxt, (xmlSchemaValidityErrorFunc) fprintf, (xmlSchemaValidityWarningFunc) fprintf, stderr);
schema = xmlSchemaParse(ctxt);
xmlSchemaFreeParserCtxt(ctxt);
 
 
doc = xmlReadFile(XMLFileName, NULL, 0);
 
if (doc == NULL){
fprintf(stderr, "Could not parse %s\n", XMLFileName);
}
else{
xmlSchemaValidCtxtPtr ctxt;
 
ctxt = xmlSchemaNewValidCtxt(schema);
xmlSchemaSetValidErrors(ctxt, (xmlSchemaValidityErrorFunc) fprintf, (xmlSchemaValidityWarningFunc) fprintf, stderr);
ret = xmlSchemaValidateDoc(ctxt, doc);
if (ret == 0){
printf("%s validates\n", XMLFileName);
}
else if (ret > 0){
printf("%s fails to validate\n", XMLFileName);
}
else{
printf("%s validation generated an internal error\n", XMLFileName);
}
xmlSchemaFreeValidCtxt(ctxt);
xmlFreeDoc(doc);
}
 
 
if(schema != NULL)
xmlSchemaFree(schema);
 
xmlSchemaCleanupTypes();
xmlCleanupParser();
xmlMemoryDump();
 
return 0;
}
</syntaxhighlight>
Output, files used from the W3 Schools page :
<pre>
C:\rosettaCode>xmlValidator.exe shiporder.xml shiporder.xsd
shiporder.xml validates
</pre>
 
=={{header|C sharp}}==
<langsyntaxhighlight lang="csharp">
using System;
using System.Xml;
Line 34 ⟶ 107:
}
}
</syntaxhighlight>
</lang>
 
=={{header|FreeBASIC}}==
{{libheader|libxml2}}
<syntaxhighlight lang="vbnet">#include once "crt/stdio.bi"
#include once "crt/stdlib.bi"
#include once "libxml/tree.bi"
#include once "libxml/parser.bi"
 
'' Load the XML document
dim as xmlDocPtr doc = xmlReadFile("document.xml", NULL, 0)
if doc = NULL then
print "Error opening XML document."
end 1
end if
 
'' Load the XSD schema
dim as xmlSchemaParserCtxtPtr ctxt = xmlSchemaNewParserCtxt("schema.xsd")
if ctxt = NULL then
print "Error opening XSD schema."
xmlFreeDoc(doc)
end 1
end if
 
'' Parse the XSD schema
dim as xmlSchemaPtr schema = xmlSchemaParse(ctxt)
if schema = NULL then
print "Error parsing XSD schema."
xmlSchemaFreeParserCtxt(ctxt)
xmlFreeDoc(doc)
end 1
end if
 
'' Create a validation context
dim as xmlSchemaValidCtxtPtr vctxt = xmlSchemaNewValidCtxt(schema)
if vctxt = NULL then
print "Error creating validation context."
xmlSchemaFree(schema)
xmlSchemaFreeParserCtxt(ctxt)
xmlFreeDoc(doc)
end 1
end if
 
'' Validate the XML document against the XSD schema
if xmlSchemaValidateDoc(vctxt, doc) = 0 then
print "The XML document is valid according to the XSD schema."
else
print "The XML document is not valid according to the XSD schema."
end if
 
'' Free resources
xmlSchemaFreeValidCtxt(vctxt)
xmlSchemaFree(schema)
xmlSchemaFreeParserCtxt(ctxt)
xmlFreeDoc(doc)
xmlCleanupParser()</syntaxhighlight>
 
=={{header|F_Sharp|F#}}==
<p>Using an inline stylesheet:</p>
<syntaxhighlight lang="fsharp">open System.Xml
open System.Xml.Schema
open System.IO
 
let xml = @"<root>
<!--Start of schema-->
<xs:schema id='an-element' targetNamespace='example' xmlns:mstns='example' xmlns='example' xmlns:xs='http://www.w3.org/2001/XMLSchema' attributeFormDefault='unqualified' elementFormDefault='qualified'>
<xs:element name='an-element'>
<xs:complexType>
<xs:sequence minOccurs='0' maxOccurs='unbounded'>
<xs:element name='another-element' nillable='true'>
<xs:complexType>
<xs:simpleContent>
<xs:extension base='xs:string'>
<xs:attribute name='an-attribute' form='unqualified' type='xs:boolean' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
<!--End of schema-->
<an-element xmlns='example'>
<another-element an-attribute='false'>...</another-element>
<another-element an-attribute='wrong'>123</another-element>
</an-element>
</root>"
 
let validationData withWarnings =
let errors = ref 0
let warnings = ref 0
fun input ->
match input with
| Some(msg, severity) ->
if severity = XmlSeverityType.Error then
errors := !errors + 1
printfn "Validation error: %s" msg
elif withWarnings then
warnings := !warnings + 1
printfn "Validation warning: %s" msg
None
| None ->
if withWarnings then
Some(dict[XmlSeverityType.Error, !errors; XmlSeverityType.Warning, !warnings])
else
Some(dict[XmlSeverityType.Error, !errors])
 
[<EntryPoint>]
let main argv =
let withWarnings = argv.Length > 0 && argv.[0] = "-w"
let vData = validationData withWarnings
let validationEvent = new ValidationEventHandler(fun _ e ->
vData (Some(e.Message, e.Severity)) |> ignore)
let settings = new XmlReaderSettings()
settings.ValidationType <- ValidationType.Schema
settings.ValidationEventHandler.AddHandler(validationEvent)
settings.ValidationFlags <- settings.ValidationFlags ||| XmlSchemaValidationFlags.ProcessInlineSchema ||| XmlSchemaValidationFlags.ReportValidationWarnings
let reader = XmlReader.Create(new StringReader(xml), settings);
while reader.Read() do ()
printfn "%A" (Seq.toList (vData None).Value)
0
</syntaxhighlight>
{{out}}
<pre style="white-space:pre-wrap">>RosettaCode
Validation error: The 'an-attribute' element is invalid - The value 'wrong' is invalid according to its datatype 'http://www.w3.org/2001/XMLSchema:boolean' - The string 'wrong' is not a valid boolean value.
[[Error, 1]]
 
>RosettaCode -w
Validation warning: Could not find schema information for the element 'root'.
Validation error: The 'an-attribute' element is invalid - The value 'wrong' is invalid according to its datatype 'http://www.w3.org/2001/XMLSchema:boolean' - The string 'wrong' is not a valid boolean value.
[[Error, 1]; [Warning, 1]]
 
</pre>
<p>Changing <code>wrong</code> to a boolean, e. g. <code>true</code>, The result (without -w) is <pre>[[Error, 0]]</pre>
 
=={{header|FutureBasic}}==
FB has native XML validators.
<syntaxhighlight lang="futurebasic">
include "NSLog.incl"
include "Tlbx XML.incl"
 
// Sample XML courtesy https://www.w3schools.com/xml/schema_example.asp
local fn Sample1XMLDocument as CFStringRef
CFStringRef xmlDoc = @"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n¬
<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n¬
<xs:element name=\"shiporder\">\n¬
<xs:complexType>\n¬
<xs:sequence>\n¬
<xs:element name=\"orderperson\" type=\"xs:string\"/>\n¬
<xs:element name=\"shipto\">\n¬
<xs:complexType>\n¬
<xs:sequence>\n¬
<xs:element name=\"name\" type=\"xs:string\"/>\n¬
<xs:element name=\"address\" type=\"xs:string\"/>\n¬
<xs:element name=\"city\" type=\"xs:string\"/>\n¬
<xs:element name=\"country\" type=\"xs:string\"/>\n¬
</xs:sequence>\n¬
</xs:complexType>\n¬
</xs:element>\n¬
<xs:element name=\"item\" maxOccurs=\"unbounded\">\n¬
<xs:complexType>\n¬
<xs:sequence>\n¬
<xs:element name=\"title\" type=\"xs:string\"/>\n¬
<xs:element name=\"note\" type=\"xs:string\" minOccurs=\"0\"/>\n¬
<xs:element name=\"quantity\" type=\"xs:positiveInteger\"/>\n¬
<xs:element name=\"price\" type=\"xs:decimal\"/>\n¬
</xs:sequence>\n¬
</xs:complexType>\n¬
</xs:element>\n¬
</xs:sequence>\n¬
<xs:attribute name=\"orderid\" type=\"xs:string\" use=\"required\"/>\n¬
</xs:complexType>\n¬
</xs:element>\n¬
</xs:schema>"
end fn = xmlDoc
 
local fn ValidateXML( string as CFStringRef ) as BOOL
ErrorRef err = NULL
XMLDocumentRef xmlDoc = fn XMLDocumentWithXMLString( string, NSXMLDocumentValidate + NSXMLNodePreserveAll, err )
if err then NSLog( @"Error: %@", fn ErrorLocalizedDescription( err ) ) : exit fn
BOOL validXML = fn XMLDocumentValidate( xmlDoc, err )
if err then NSLog( @"Error: %@", fn ErrorLocalizedDescription( err ) ) else exit fn = validXML
end fn = NO
 
CFStringRef xmlDoc, xmlName
BOOL success
 
xmlDoc = fn Sample1XMLDocument
success = fn ValidateXML( xmlDoc )
xmlName = @"XML Sample No. 1"
if success then NSLog( @"%@: XML document is valid.\n", xmlName ) else NSLog( @"%@ XML document is invalid.\n", xmlName )
 
HandleEvents
</syntaxhighlight>
{{output}}
<pre>
XML Sample No. 1: XML document is valid.
</pre>
 
=={{header|Go}}==
{{libheader|libxml2(Go)}}
<br>
This uses the w3schools test data linked to above.
<syntaxhighlight lang="go">package main
 
import (
"fmt"
"github.com/lestrrat-go/libxml2"
"github.com/lestrrat-go/libxml2/xsd"
"io/ioutil"
"log"
"os"
)
 
func check(err error) {
if err != nil {
log.Fatal(err)
}
}
 
func main() {
xsdfile := "shiporder.xsd"
f, err := os.Open(xsdfile)
check(err)
defer f.Close()
 
buf, err := ioutil.ReadAll(f)
check(err)
 
s, err := xsd.Parse(buf)
check(err)
defer s.Free()
 
xmlfile := "shiporder.xml"
f2, err := os.Open(xmlfile)
check(err)
defer f2.Close()
 
buf2, err := ioutil.ReadAll(f2)
check(err)
 
d, err := libxml2.Parse(buf2)
check(err)
 
if err := s.Validate(d); err != nil {
for _, e := range err.(xsd.SchemaValidationError).Errors() {
log.Printf("error: %s", e.Error())
}
return
}
 
fmt.Println("Validation of", xmlfile, "against", xsdfile, "successful!")
}</syntaxhighlight>
 
{{out}}
<pre>
Validation of shiporder.xml against shiporder.xsd successful!
</pre>
 
=={{header|Groovy}}==
{{trans|Java}}
 
Solution:
<syntaxhighlight lang="groovy">import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI
import javax.xml.transform.stream.StreamSource
import javax.xml.validation.SchemaFactory
import org.xml.sax.SAXParseException
 
def factory = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI)
def validate = { schemaURL, docURL ->
try {
factory.newSchema(schemaURL.toURL()).newValidator().validate(new StreamSource(docURL))
true
} catch (SAXParseException e) {
false
}
}</syntaxhighlight>
 
Test:
<syntaxhighlight lang="groovy">def schemaLoc = "http://venus.eas.asu.edu/WSRepository/xml/Courses.xsd"
def docLoc = "http://venus.eas.asu.edu/WSRepository/xml/Courses.xml"
println "Document is ${validate(schemaLoc, docLoc)? 'valid' : 'invalid'}"</syntaxhighlight>
 
=={{header|Java}}==
<langsyntaxhighlight lang="java">import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
 
import java.net.MalformedURLException;
Line 62 ⟶ 417:
}
 
// The least code you need for validation
public static boolean minimalValidate(URL schemaLocation, URL documentLocation) {
SchemaFactory factory = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI);
try {
Validator validator = factory.newSchema(schemaLocation).newValidator();
validator.validate(new StreamSource(documentLocation.toString()));
return true;
} catch (Exception e) {
return false;
}
}
 
// A more complete validator
public static boolean validate(URL schemaLocation, URL documentLocation) {
SchemaFactory factory = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI);
Line 96 ⟶ 464:
}
}
}</langsyntaxhighlight>
 
=={{header|Julia}}==
<syntaxhighlight lang="julia">using LightXML
 
const Xptr = LightXML.Xptr
 
function validate(url::String, schemafile::String)
ctxt = ccall((:xmlSchemaNewParserCtxt, LightXML.libxml2), Xptr, (Cstring,), schemafile)
ctxt != C_NULL || throw(LightXML.XMLNoRootError())
schema = ccall((:xmlSchemaParse, LightXML.libxml2), Xptr, (Xptr,), ctxt)
schema != C_NULL || throw(LightXML.XMLNoRootError())
ccall((:xmlSchemaFreeParserCtxt, LightXML.libxml2), Cvoid, (Xptr,), ctxt)
ctxt = ccall((:xmlSchemaNewValidCtxt, LightXML.libxml2), Xptr, (Xptr,), schema)
err = ccall((:xmlSchemaValidateFile, LightXML.libxml2),
Cint, (Ptr{LightXML.xmlBuffer}, Cstring), ctxt, url)
return err == 0 ? true : false
end
 
function xsdvalidatexml()
if length(ARGS) != 2
println(" Usage: julia ", PROGRAM_FILE, ", xmlfilename xsdfilename")
elseif validate(ARGS[1], ARGS[2])
println("File ", ARGS[1], " validates as correct XML using the XSD file ", ARGS[2], ".")
else
println("File ", ARGS[1]. "does not validate.")
end
end
 
xsdvalidatexml()
</syntaxhighlight>
 
=={{header|Kotlin}}==
{{trans|C}}
{{libheader|libxml2}}
{{works with|Ubuntu 14.04}}
Assuming that libxml2 is already installed on your system in the default location(s), you first need to build libxml_schemas.klib using the following .def file and the cinterop tool:
<pre>
// libxml_schemas.def
headers = /usr/include/libxml2/libxml/xmlschemastypes.h
compilerOpts = -I/usr/include/libxml2
linkerOpts = -L/usr/lib/x86_64-linux-gnu -lxml2
</pre>
Next, you need to compile the following Kotlin program, linking against libxml_schemas.klib.
<syntaxhighlight lang="scala">// Kotlin Native v0.6
 
import kotlinx.cinterop.*
import platform.posix.*
import libxml_schemas.*
 
fun err(ctx: COpaquePointer?, msg: CPointer<ByteVar>?, extra: CPointer<ByteVar>?) {
val fp = ctx?.reinterpret<FILE>()
fprintf(fp, msg?.toKString(), extra?.toKString())
}
 
fun warn(ctx: COpaquePointer?, msg: CPointer<ByteVar>?, extra: CPointer<ByteVar>?) {
err(ctx, msg, extra)
}
 
fun main(args: Array<String>) {
if (args.size != 2) {
println("You need to pass exactly 2 command line arguments, namely:")
println(" <XML Document Name> <XSD Document Name>")
return
}
 
val xmlFileName = args[0]
val xsdFileName = args[1]
xmlLineNumbersDefault(1)
val ctxt = xmlSchemaNewParserCtxt(xsdFileName)
 
xmlSchemaSetParserErrors(
ctxt,
staticCFunction(::err) as xmlSchemaValidityErrorFunc?,
staticCFunction(::warn) as xmlSchemaValidityWarningFunc?,
stderr
)
 
val schema = xmlSchemaParse(ctxt)
xmlSchemaFreeParserCtxt(ctxt)
 
val doc = xmlReadFile(xmlFileName, null, 0)
if (doc == null) {
println("Could not parse $xmlFileName")
}
else {
val ctxt2 = xmlSchemaNewValidCtxt(schema)
 
xmlSchemaSetValidErrors(
ctxt2,
staticCFunction(::err) as xmlSchemaValidityErrorFunc?,
staticCFunction(::warn) as xmlSchemaValidityWarningFunc?,
stderr
)
 
val ret = xmlSchemaValidateDoc(ctxt2, doc)
if (ret == 0)
println("$xmlFileName validates")
else if (ret > 0)
println("$xmlFileName fails to validate")
else
println("$xmlFileName generated an internal error")
xmlSchemaFreeValidCtxt(ctxt2)
xmlFreeDoc(doc)
}
 
if (schema != null) xmlSchemaFree(schema)
xmlSchemaCleanupTypes()
xmlCleanupParser()
xmlMemoryDump()
}</syntaxhighlight>
Finally, the resulting .kexe file should be executed passing it similar command line arguments to the C entry to produce the following output.
<pre>
$ ./xmlval.kexe shiporder.xml shiporder.xsd
shiporder.xml validates
</pre>
 
=={{header|Nim}}==
{{libheader|libxml2}}
As in the C version, we use “libxml2” for the validation. As there is no Nim binding for this library, we provide the necessary definitions in our program (three types and six procedures). There is nothing more to do. In Nim, interfacing with C is often very easy.
 
Our program is based on the C version with many differences. In particular, we use the function “xmlSchemaValidateFile” rather than the function “xmlSchemaValidateDoc”.
 
<syntaxhighlight lang="nim">import os, strformat
 
const LibXml = "libxml2.so"
 
type
XmlSchemaParserCtxtPtr = pointer
XmlSchemaPtr = pointer
XmlSchemaValidCtxtPtr = pointer
 
 
# Declaration of needed "libxml2" procedures.
 
proc xmlSchemaNewParserCtxt(url: cstring): XmlSchemaParserCtxtPtr
{.cdecl, dynlib: LibXml, importc: "xmlSchemaNewParserCtxt".}
 
proc xmlSchemaParse(ctxt: XmlSchemaParserCtxtPtr): XmlSchemaPtr
{.cdecl, dynlib: LibXml, importc: "xmlSchemaParse".}
 
proc xmlSchemaFreeParserCtxt(ctxt: XmlSchemaParserCtxtPtr)
{.cdecl, dynlib: LibXml, importc: "xmlSchemaFreeParserCtxt".}
 
proc xmlSchemaNewValidCtxt(schema: XmlSchemaPtr): XmlSchemaValidCtxtPtr
{.cdecl, dynlib: LibXml, importc: "xmlSchemaNewValidCtxt".}
 
proc xmlSchemaValidateFile(ctxt: XmlSchemaValidCtxtPtr; filename: cstring; options: cint): cint
{.cdecl, dynlib: LibXml, importc: "xmlSchemaValidateFile".}
 
proc xmlSchemaFreeValidCtxt(ctxt: XmlSchemaValidCtxtPtr)
{.cdecl, dynlib: LibXml, importc: "xmlSchemaFreeValidCtxt".}
 
 
if paramCount() != 2:
quit &"Usage: {getAppFilename().lastPathPart} <XML Document Name> <XSD Document Name", QuitFailure
 
let xmlFilename = paramStr(1)
let xsdFilename = paramStr(2)
 
# Parse XML schema file.
let parserCtxt = xmlSchemaNewParserCtxt(xsdFilename)
let schema = parserCtxt.xmlSchemaParse()
parserCtxt.xmlSchemaFreeParserCtxt()
 
# Validate XML file using XML schema.
let validCtxt = schema.xmlSchemaNewValidCtxt()
case validCtxt.xmlSchemaValidateFile(xmlFilename, 0)
of 0:
echo &"“{xmlFilename}” validates."
of -1:
echo &"“{xmlFilename}” validation generated an internal error."
else:
echo &"“{xmlFilename}” fails to validate."
validCtxt.xmlSchemaFreeValidCtxt()</syntaxhighlight>
 
{{out}}
Using command <code>./xml_validate shiporder.xml shiporder.xsd</code>:
<pre>“shiporder.xml” validates.</pre>
Using a modified file “shiporder1.xml” where tag “orderperson” has been replaced by “orderperson1”:
<pre>Entity: line 6: Schemas validity error : Element 'orderperson1': This element is not expected. Expected is ( orderperson ).
“shiporder1.xml” fails to validate.</pre>
 
=={{header|Perl}}==
 
<syntaxhighlight lang="perl">#!/usr/bin/env perl -T
use 5.018_002;
use warnings;
use Try::Tiny;
use XML::LibXML;
 
our $VERSION = 1.000_000;
 
my $parser = XML::LibXML->new();
 
my $good_xml = '<a>5</a>';
my $bad_xml = '<a>5<b>foobar</b></a>';
my $xmlschema_markup = <<'END';
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="a" type="xsd:integer"/>
</xsd:schema>
END
 
my $xmlschema = XML::LibXML::Schema->new( string => $xmlschema_markup );
 
for ( $good_xml, $bad_xml ) {
my $doc = $parser->parse_string($_);
try {
$xmlschema->validate($doc);
}
finally {
if (@_) {
say "Not valid: @_";
}
else {
say 'Valid';
}
};
}</syntaxhighlight>
 
{{out}}
<pre>Valid
Not valid: unknown-7fe99976a9a0:0: Schemas validity error :
Element 'a': Element content is not allowed, because the type definition is simple.</pre>
 
=={{header|Phix}}==
{{trans|C}}
Note that error handling has been delegated to within libxml.e, specifically
xmlSchemaNewParserCtxt() and xmlSchemaNewValidCtxt() assign an internal handler,
which resorts to xmlGetLastError() and therefore needs to use a bit of cffi,
that is rather than using the (odd-looking) error it is actually passed.
The libxml.e wrapper was penned specifically for this task and is just about as
bare-bones as it could ever possibly be, and win32-only, for now.
<!--<syntaxhighlight lang="phix">(notonline)-->
<span style="color: #000080;font-style:italic;">--
-- demo\rosetta\Validate_XML.exw
-- =============================
--</span>
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span>
<span style="color: #7060A8;">requires</span><span style="color: #0000FF;">(</span><span style="color: #000000;">32</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- let me know if you can get this to work on 64bit</span>
<span style="color: #7060A8;">requires</span><span style="color: #0000FF;">(</span><span style="color: #004600;">WINDOWS</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- "" if you can get this to work on linux</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">dl</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">`Download rosetta\libxml\ from http://phix.x10.mx/pmwiki/pmwiki.php?n=Main.libxml`</span>
<span style="color: #7060A8;">assert</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">get_file_type</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"libxml"</span><span style="color: #0000FF;">)=</span><span style="color: #004600;">FILETYPE_DIRECTORY</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dl</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">libxml</span><span style="color: #0000FF;">\</span><span style="color: #000000;">libxml</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">XSDFileName</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">`libxml\shiporder.xsd`</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (versions 2 & 3 also included in "")</span>
<span style="color: #000000;">XMLFileName</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">`libxml\shiporder.xml`</span>
<span style="color: #000000;">xmlLineNumbersDefault</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">pctxt</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">xmlSchemaNewParserCtxt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">XSDFileName</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">schema</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">xmlSchemaParse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pctxt</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">xmlSchemaFreeParserCtxt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pctxt</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">doc</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">xmlReadFile</span><span style="color: #0000FF;">(</span><span style="color: #000000;">XMLFileName</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">NULL</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">doc</span><span style="color: #0000FF;">=</span><span style="color: #004600;">NULL</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Could not parse %s\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">XMLFileName</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">else</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">vctxt</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">xmlSchemaNewValidCtxt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">schema</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">ret</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">xmlSchemaValidateDoc</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vctxt</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">doc</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">ret</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s validates\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">XMLFileName</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">elsif</span> <span style="color: #000000;">ret</span><span style="color: #0000FF;">></span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s fails to validate\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">XMLFileName</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">else</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s validation generated an internal error\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">XMLFileName</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">xmlSchemaFreeValidCtxt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vctxt</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">xmlFreeDoc</span><span style="color: #0000FF;">(</span><span style="color: #000000;">doc</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">schema</span><span style="color: #0000FF;">!=</span><span style="color: #004600;">NULL</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">xmlSchemaFree</span><span style="color: #0000FF;">(</span><span style="color: #000000;">schema</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">xmlSchemaCleanupTypes</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">xmlCleanupParser</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">xmlMemoryDump</span><span style="color: #0000FF;">()</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
libxml\shiporder.xml validates
</pre>
Performing the same error handling check as Nim, ie changing orderperson to orderperson1 (twice) results in:
<pre>
Error/Warning in line 6
Element 'orderperson1': This element is not expected. Expected is ( orderperson ).
libxml\shiporder.xml fails to validate
</pre>
All three formats of the xsd file as given on the W3 page give identical results, for both with and without that error.
 
=={{header|PHP}}==
<syntaxhighlight lang="php">
libxml_use_internal_errors(true);
 
$xml = new DOMDocument();
$xml->load('shiporder.xml');
 
if (!$xml->schemaValidate('shiporder.xsd')) {
var_dump(libxml_get_errors()); exit;
} else {
echo 'success';
}
</syntaxhighlight>
{{out}}
<pre>
using valid shiporder.xml and shiporder.xsd:
success
Done.
using invalid shiporder.xml and valid shiporder.xsd:
array(1) {
[0] =>
class LibXMLError#2 (6) {
public $level =>
int(2)
public $code =>
int(1871)
public $column =>
int(0)
public $message =>
string(74) "Element 'foo': This element is not expected. Expected is ( orderperson ).
"
public $file =>
string(43) "file:/C:/xampp/htdocs/rosetta/shiporder.xml"
public $line =>
int(4)
}
}
Done.
</pre>
 
=={{header|Python}}==
 
<syntaxhighlight lang="python">#!/bin/python
from __future__ import print_function
import lxml
from lxml import etree
 
if __name__=="__main__":
 
parser = etree.XMLParser(dtd_validation=True)
schema_root = etree.XML('''\
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="a" type="xsd:integer"/>
</xsd:schema>
''')
schema = etree.XMLSchema(schema_root)
 
#Good xml
parser = etree.XMLParser(schema = schema)
try:
root = etree.fromstring("<a>5</a>", parser)
print ("Finished validating good xml")
except lxml.etree.XMLSyntaxError as err:
print (err)
 
#Bad xml
parser = etree.XMLParser(schema = schema)
try:
root = etree.fromstring("<a>5<b>foobar</b></a>", parser)
except lxml.etree.XMLSyntaxError as err:
print (err)</syntaxhighlight>
 
{{out}}
<pre>Finished validating good xml
Element 'a': Element content is not allowed, because the type definition is simple.</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
{{trans|Perl}}
<syntaxhighlight lang="raku" line>
# Reference: https://github.com/libxml-raku/LibXML-raku
 
use v6.d;
use LibXML;
use LibXML::Schema;
 
my $good_xml = '<a>5</a>';
my $bad_xml = '<a>5<b>foobar</b></a>';
 
my $xsdschema = q:to<EOF>;
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="a" type="xsd:integer"/>
</xsd:schema>
EOF
 
my LibXML $p .= new();
 
for ( $good_xml, $bad_xml ) {
my $x = $p.parse: :string($_);
try { LibXML::Schema.new( string => $xsdschema ).validate( $x ) }
!$! ?? say "Valid." !! say $!.message() ;
}</syntaxhighlight>
{{out}}
<pre>Valid.
Schemas validity error : Element 'a': Element content is not allowed, because the type definition is simple.
</pre>
 
=={{header|Scala}}==
<syntaxhighlight lang="scala">import java.net.URL
 
import javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI
import javax.xml.transform.stream.StreamSource
import javax.xml.validation.SchemaFactory
import javax.xml.ws.Holder
import org.xml.sax.{ErrorHandler, SAXException, SAXParseException}
 
object XmlValidation extends App {
val (schemaLocation, documentLocation) = (new URL("http://venus.eas.asu.edu/WSRepository/xml/Courses.xsd")
, new URL("http://venus.eas.asu.edu/WSRepository/xml/Courses.xml"))
 
println(s"Document is ${if (validate(schemaLocation, documentLocation)) "valid" else "invalid"}.")
 
// A more complete validator
def validate(schemaLocation: URL, documentLocation: URL): Boolean = {
val factory = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI)
val valid = new Holder[Boolean](true)
try {
val validator = factory.newSchema(schemaLocation).newValidator
// Get some better diagnostics out
validator.setErrorHandler(new ErrorHandler() {
override def warning(exception: SAXParseException) = println("warning: " + exception.getMessage)
 
override def error(exception: SAXParseException) = {
println("error: " + exception.getMessage)
valid.value = false
}
 
override def fatalError(exception: SAXParseException) = {
println("fatal error: " + exception.getMessage)
throw exception
}
})
validator.validate(new StreamSource(documentLocation.toString))
valid.value
} catch {
case _: SAXException =>
// Already reported above
false
case e: Exception =>
// If this is the only thing that throws, it's a gross error
println(e)
false
}
}
}</syntaxhighlight>
 
=={{header|Sidef}}==
{{trans|Perl}}
<syntaxhighlight lang="ruby">require('XML::LibXML')
 
func is_valid_xml(str, schema) {
 
var parser = %O<XML::LibXML>.new
var xmlschema = %O<XML::LibXML::Schema>.new(string => schema)
 
try {
xmlschema.validate(parser.parse_string(str))
true
} catch {
false
}
}
 
var good_xml = '<a>5</a>'
var bad_xml = '<a>5<b>foobar</b></a>'
 
var xmlschema_markup = <<'END'
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="a" type="xsd:integer"/>
</xsd:schema>
END
 
[good_xml, bad_xml].each { |xml|
say "is_valid_xml(#{xml.dump}) : #{is_valid_xml(xml, xmlschema_markup)}"
}</syntaxhighlight>
{{out}}
<pre>
is_valid_xml("<a>5</a>") : true
is_valid_xml("<a>5<b>foobar</b></a>") : false
</pre>
 
=={{header|VBScript}}==
<syntaxhighlight lang="vb">
Option explicit
 
Function fileexists(fn)
fileexists= CreateObject("Scripting.FileSystemObject").FileExists(fn)
End Function
 
Function xmlvalid(strfilename)
Dim xmldoc,xmldoc2,objSchemas
Set xmlDoc = CreateObject("Msxml2.DOMDocument.6.0")
If fileexists(Replace(strfilename,".xml",".dtd")) Then
xmlDoc.setProperty "ProhibitDTD", False
xmlDoc.setProperty "ResolveExternals", True
xmlDoc.validateOnParse = True
xmlDoc.async = False
xmlDoc.load(strFileName)
ElseIf fileexists(Replace(strfilename,".xml",".xsd")) Then
xmlDoc.setProperty "ProhibitDTD", True
xmlDoc.setProperty "ResolveExternals", True
xmlDoc.validateOnParse = True
xmlDoc.async = False
xmlDoc.load(strFileName)
'import xsd
Set xmlDoc2 = CreateObject("Msxml2.DOMDocument.6.0")
xmlDoc2.validateOnParse = True
xmlDoc2.async = False
xmlDoc2.load(Replace (strfilename,".xml",".xsd"))
'cache xsd
Set objSchemas = CreateObject("MSXML2.XMLSchemaCache.6.0")
objSchemas.Add "", xmlDoc2
Else
Set xmlvalid= Nothing:Exit Function
End If
Set xmlvalid=xmldoc.parseError
End Function
 
 
 
Sub displayerror (parserr) 'display the info returned by Msxml2
Dim strresult
If parserr is Nothing Then
strresult= "could not find dtd or xsd for " & strFileName
Else
With parserr
Select Case .errorcode
Case 0
strResult = "Valid: " & strFileName & vbCr
Case Else
strResult = vbCrLf & "ERROR! Failed to validate " & _
strFileName & vbCrLf &.reason & vbCr & _
"Error code: " & .errorCode & ", Line: " & _
.line & ", Character: " & _
.linepos & ", Source: """ & _
.srcText & """ - " & vbCrLf
End Select
End With
End If
WScript.Echo strresult
End Sub
 
'main
Dim strfilename
 
'testing validation with dtd
'strfilename="books.xml"
'displayerror xmlvalid (strfilename)
 
'testing validation with xsd
strfilename="shiporder.xml"
displayerror xmlvalid (strfilename)
</syntaxhighlight>
{{out}}
<small>
<pre>
Valid: shiporder.xml
</pre>
</small>
 
=={{header|Visual Basic .NET}}==
'''Compiler:''' Roslyn Visual Basic (language version >= 14, e.g. with Visual Studio 2015)
{{works with|.NET Core|2.1}}
 
<syntaxhighlight lang="vbnet">Option Compare Binary
Option Explicit On
Option Infer On
Option Strict On
 
Imports System.Xml
Imports System.Xml.Schema
 
Module Program
Function GetValidationErrors(doc As XDocument, schemaSet As XmlSchemaSet) As IList(Of ValidationEventArgs)
GetValidationErrors = New List(Of ValidationEventArgs)
doc.Validate(schemaSet, Sub(sender, e) GetValidationErrors.Add(e))
End Function
 
Sub Main()
' These functions are declared in another module found below.
Dim schema = GetSchema()
Dim document = GetDocument()
 
Dim schemaSet As New XmlSchemaSet()
schemaSet.Add(XmlSchema.Read(schema.CreateReader(), Nothing))
 
Dim errors = GetValidationErrors(document, schemaSet)
For Each e In errors
Console.WriteLine($"Validation {e.Severity}:{vbCrLf}{e.Message}")
Next
 
If errors.Count = 0 Then Console.WriteLine("The document is valid.")
End Sub
End Module</syntaxhighlight>
 
{{out}}
<pre>Validation Error:
The 'an-attribute' attribute is invalid - The value 'wrong' is invalid according to its datatype 'http://www.w3.org/2001/XMLSchema:boolean' - The string 'wrong' is not a valid Boolean value.</pre>
 
An alternative is to use XmlReader (like the C# and F# examples [as of 2019-08-06]).
 
<syntaxhighlight lang="vbnet"> Function GetValidationErrorsXmlReader(doc As XDocument, schemaSet As XmlSchemaSet, warnings As Boolean) As IList(Of ValidationEventArgs)
GetValidationErrorsReader = New List(Of ValidationEventArgs)
 
Dim settings As New XmlReaderSettings()
With settings
.ValidationType = ValidationType.Schema
.Schemas = schemaSet
If warnings Then .ValidationFlags = .ValidationFlags Or XmlSchemaValidationFlags.ReportValidationWarnings
End With
 
AddHandler settings.ValidationEventHandler, Sub(sender, e) GetValidationErrorsReader.Add(e)
 
Using reader = XmlReader.Create(doc.CreateReader(), settings)
Do While reader.Read() : Loop
End Using
End Function</syntaxhighlight>
 
Creating the documents (same as F#) from strings (does not handle syntax errors):
 
<syntaxhighlight lang="vbnet">Module Constants
Const SCHEMA As String =
"<?xml version='1.0'?>
<xs:schema id='an-element' targetNamespace='example' xmlns:mstns='example' xmlns='example' xmlns:xs='http://www.w3.org/2001/XMLSchema' attributeFormDefault='unqualified' elementFormDefault='qualified'>
<xs:element name='an-element'>
<xs:complexType>
<xs:sequence minOccurs='0' maxOccurs='unbounded'>
<xs:element name='another-element' nillable='true'>
<xs:complexType>
<xs:simpleContent>
<xs:extension base='xs:string'>
<xs:attribute name='an-attribute' form='unqualified' type='xs:boolean'/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>"
 
Const DOCUMENT As String =
"<?xml version='1.0'?>
<an-element xmlns='example'>
<another-element an-attribute='false'>...</another-element>
<another-element an-attribute='wrong'>123</another-element>
</an-element>"
 
Function GetSchema() As XDocument
Return XDocument.Parse(SCHEMA)
End Function
 
Function GetDocument() As XDocument
Return XDocument.Parse(DOCUMENT)
End Function
End Module</syntaxhighlight>
 
Alternatively, we can be cheeky and use VB's XML literals...
 
<syntaxhighlight lang="vbnet">Module Constants
Function GetDocument() As XDocument
Return _
<?xml version="1.0"?>
<an-element xmlns="example">
<another-element an-attribute="false">...</another-element>
<another-element an-attribute="wrong"> 123</another-element>
</an-element>
End Function
 
Function GetSchema() As XDocument
Return _
<?xml version="1.0"?>
<xs:schema id="an-element" targetNamespace="example" xmlns:mstns="example" xmlns="example" xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified">
<xs:element name="an-element">
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="another-element" nillable="true">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="an-attribute" form="unqualified" type="xs:boolean"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
End Function
End Module</syntaxhighlight>
 
=={{header|Wren}}==
{{trans|Nim}}
{{libheader|libxml2}}
Although Wren has third party support for XML, it does not support validation against an XSD schema. We therefore use an
embedded program so we can ask the C host to communicate with Libxml2 for us.
<syntaxhighlight lang="wren">/* XML_validation.wren */
 
class Args {
foreign static xmlFilename
 
foreign static xsdFilename
}
 
foreign class XmlSchemaPtr {
construct new() {}
}
 
foreign class XmlSchemaParserCtxtPtr {
construct new(url) {}
 
foreign parse(schema)
 
foreign freeParserCtxt()
}
 
foreign class XmlSchemaValidCtxtPtr {
construct new(schema) {}
 
foreign validateFile(filename, options)
 
foreign freeValidCtxt()
}
 
var xmlFilename = Args.xmlFilename
var xsdFilename = Args.xsdFilename
 
// parse xml schema file
var parserCtxt = XmlSchemaParserCtxtPtr.new(xsdFilename)
var schema = XmlSchemaPtr.new()
parserCtxt.parse(schema)
parserCtxt.freeParserCtxt()
 
// validate xml file using schema
var validCtxt = XmlSchemaValidCtxtPtr.new(schema)
var res = validCtxt.validateFile(xmlFilename, 0)
if (res == 0) {
System.print("'%(xmlFilename)' validates.")
} else if (res == -1) {
System.print("'%(xmlFilename)' validation generated an internal error.")
} else {
System.print("'%(xmlFilename)' fails to validate.")
}
validCtxt.freeValidCtxt()</syntaxhighlight>
<br>
We now embed this in the following C program, compile and run it.
<syntaxhighlight lang="c">/* built with: gcc XML_validation.c -o XML_validation -I/usr/include/libxml2 -lxml2 -lwren -lm */
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libxml2/libxml/xmlschemastypes.h>
#include "wren.h"
 
/* C <=> Wren interface functions */
 
char *xmlFilename, *xsdFilename;
 
void C_xmlFilename(WrenVM* vm) {
wrenSetSlotString(vm, 0, xmlFilename);
}
 
void C_xsdFilename(WrenVM* vm) {
wrenSetSlotString(vm, 0, xsdFilename);
}
 
void C_xmlSchemaPtrAllocate(WrenVM* vm) {
wrenSetSlotNewForeign(vm, 0, 0, sizeof(xmlSchemaPtr));
}
 
void C_xmlSchemaParserCtxtPtrAllocate(WrenVM* vm) {
xmlSchemaParserCtxtPtr* pctxt = (xmlSchemaParserCtxtPtr*)wrenSetSlotNewForeign(vm, 0, 0, sizeof(xmlSchemaParserCtxtPtr));
const char *url = wrenGetSlotString(vm, 1);
*pctxt = xmlSchemaNewParserCtxt(url);
}
 
void C_xmlSchemaValidCtxtPtrAllocate(WrenVM* vm) {
xmlSchemaValidCtxtPtr* pctxt = (xmlSchemaValidCtxtPtr*)wrenSetSlotNewForeign(vm, 0, 0, sizeof(xmlSchemaValidCtxtPtr));
xmlSchemaPtr schema = *(xmlSchemaPtr*)wrenGetSlotForeign(vm, 1);
*pctxt = xmlSchemaNewValidCtxt(schema);
}
 
void C_parse(WrenVM* vm) {
xmlSchemaParserCtxtPtr ctxt = *(xmlSchemaParserCtxtPtr*)wrenGetSlotForeign(vm, 0);
xmlSchemaPtr* pschema = (xmlSchemaPtr*)wrenGetSlotForeign(vm, 1);
*pschema = xmlSchemaParse(ctxt);
}
 
void C_freeParserCtxt(WrenVM* vm) {
xmlSchemaParserCtxtPtr ctxt = *(xmlSchemaParserCtxtPtr*)wrenGetSlotForeign(vm, 0);
xmlSchemaFreeParserCtxt(ctxt);
}
 
void C_validateFile(WrenVM* vm) {
xmlSchemaValidCtxtPtr ctxt = *(xmlSchemaValidCtxtPtr*)wrenGetSlotForeign(vm, 0);
const char *filename = wrenGetSlotString(vm, 1);
int options = (int)wrenGetSlotDouble(vm, 2);
int res = xmlSchemaValidateFile(ctxt, filename, options);
wrenSetSlotDouble(vm, 0, (double)res);
}
 
void C_freeValidCtxt(WrenVM* vm) {
xmlSchemaValidCtxtPtr ctxt = *(xmlSchemaValidCtxtPtr*)wrenGetSlotForeign(vm, 0);
xmlSchemaFreeValidCtxt(ctxt);
}
 
WrenForeignClassMethods bindForeignClass(WrenVM* vm, const char* module, const char* className) {
WrenForeignClassMethods methods;
methods.allocate = NULL;
methods.finalize = NULL;
if (strcmp(module, "main") == 0) {
if (strcmp(className, "XmlSchemaPtr") == 0) {
methods.allocate = C_xmlSchemaPtrAllocate;
} else if (strcmp(className, "XmlSchemaParserCtxtPtr") == 0) {
methods.allocate = C_xmlSchemaParserCtxtPtrAllocate;
} else if (strcmp(className, "XmlSchemaValidCtxtPtr") == 0) {
methods.allocate = C_xmlSchemaValidCtxtPtrAllocate;
}
}
return methods;
}
 
WrenForeignMethodFn bindForeignMethod(
WrenVM* vm,
const char* module,
const char* className,
bool isStatic,
const char* signature) {
if (strcmp(module, "main") == 0) {
if (strcmp(className, "Args") == 0) {
if (isStatic && strcmp(signature, "xmlFilename") == 0) return C_xmlFilename;
if (isStatic && strcmp(signature, "xsdFilename") == 0) return C_xsdFilename;
} else if (strcmp(className, "XmlSchemaParserCtxtPtr") == 0) {
if (!isStatic && strcmp(signature, "parse(_)") == 0) return C_parse;
if (!isStatic && strcmp(signature, "freeParserCtxt()") == 0) return C_freeParserCtxt;
} else if (strcmp(className, "XmlSchemaValidCtxtPtr") == 0) {
if (!isStatic && strcmp(signature, "validateFile(_,_)") == 0) return C_validateFile;
if (!isStatic && strcmp(signature, "freeValidCtxt()") == 0) return C_freeValidCtxt;
}
}
return NULL;
}
 
static void writeFn(WrenVM* vm, const char* text) {
printf("%s", text);
}
 
void errorFn(WrenVM* vm, WrenErrorType errorType, const char* module, const int line, const char* msg) {
switch (errorType) {
case WREN_ERROR_COMPILE:
printf("[%s line %d] [Error] %s\n", module, line, msg);
break;
case WREN_ERROR_STACK_TRACE:
printf("[%s line %d] in %s\n", module, line, msg);
break;
case WREN_ERROR_RUNTIME:
printf("[Runtime Error] %s\n", msg);
break;
}
}
 
char *readFile(const char *fileName) {
FILE *f = fopen(fileName, "r");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
rewind(f);
char *script = malloc(fsize + 1);
fread(script, 1, fsize, f);
fclose(f);
script[fsize] = 0;
return script;
}
 
int main(int argc, char **argv) {
if (argc <= 2) {
printf("Usage: %s <XML Document Name> <XSD Document Name>\n", argv[0]);
return 0;
}
xmlFilename = argv[1];
xsdFilename = argv[2];
WrenConfiguration config;
wrenInitConfiguration(&config);
config.writeFn = &writeFn;
config.errorFn = &errorFn;
config.bindForeignClassFn = &bindForeignClass;
config.bindForeignMethodFn = &bindForeignMethod;
WrenVM* vm = wrenNewVM(&config);
const char* module = "main";
const char* fileName = "XML_validation.wren";
char *script = readFile(fileName);
WrenInterpretResult result = wrenInterpret(vm, module, script);
switch (result) {
case WREN_RESULT_COMPILE_ERROR:
printf("Compile Error!\n");
break;
case WREN_RESULT_RUNTIME_ERROR:
printf("Runtime Error!\n");
break;
case WREN_RESULT_SUCCESS:
break;
}
wrenFreeVM(vm);
free(script);
return 0;
}</syntaxhighlight>
 
{{out}}
Using command <code>./XML_validation shiporder.xml shiporder.xsd</code>:
<pre>'shiporder.xml' validates.</pre>
Using a modified file “shiporder1.xml” where tag “orderperson” has been replaced by “orderperson1”:
<pre>Entity: line 6: Schemas validity error : Element 'orderperson1': This element is not expected. Expected is ( orderperson ).
'shiporder1.xml' fails to validate.</pre>
2,130

edits