Support #6300
closed
Howto correctly validate a xml-file against a xslt file in Saxon version 10
Fixed in Maintenance Release:
Description
I am new to Saxon, and have tried to validate a xml-file against a xslt file (based on the samples that comes with Saxon 10) - but I can't understand why a non valid xml-file gives no errors with the following code - even I have expected some errors reported:
String xmlFile = "C:\\InvoiceStor_v2p2.xml";
String styleFile = "C:\\OIOUBL_Invoice_Schematron.xsl";
Processor processor = new Processor();
DocumentBuilder builder = processor.NewDocumentBuilder();
builder.BaseUri = new Uri(xmlFile);
XdmNode input = builder.Build(File.OpenRead(xmlFile));
XsltCompiler compiler = processor.NewXsltCompiler();
compiler.BaseUri = new Uri(styleFile);
Xslt30Transformer transformer = compiler.Compile(File.OpenRead(styleFile)).Load30();
transformer.GlobalContextItem = input;
Serializer serializer = processor.NewSerializer();
serializer.SetOutputWriter(Console.Out);
transformer.ApplyTemplates(input, serializer);
try
{
compiler.Compile(new Uri(styleFile));
Console.WriteLine("Stylesheet compilation succeeded");
}
catch (Exception)
{
IList<XmlProcessingError> xmlProcessingErrors = compiler.GetErrorList();
Console.WriteLine("Stylesheet compilation failed with " + xmlProcessingErrors.Count + " errors");
for (int i = 0; i <= xmlProcessingErrors.Count - 1; i++)
{
Console.WriteLine("Stylesheet compilation failed with " + xmlProcessingErrors.Count + " errors");
}
}
I really hope that it is okay to ask this question in this forum. The main reason is that I am new to Saxon - and I want to validate a xml-file against a xslt-file. Maybe it is not the right way to do the coding - but honestly, I do not know how to do it :-(
Thanks in advance.
Regards Michael
Files
Looks like you're trying to run a Schematron validation.
I'm no expert in Schematron, but I think (IIRC) the validation stylesheet is written to report validity errors in its normal output, rather than treating them as XSLT exceptions. That is, the XSLT should run successfully, and report any validation errors in its output file.
One little point about your code, though: you're compiling the stylesheet twice (the second time within the try/catch) which is of course quite unnecessary.
You could also save a few lines of code by using the Xslt30Transformer.Transform()
method which means you don't need to build the source tree "by hand".
Hello again
Thank you very much for commenting this - but I will be very glad if it is possible for someone to share a sample of howto make a xslt validating and then report the errors.
Thanks in advance,
Michael
@Michael Eriksen,
basically, assuming the XSLT is already some Schematron transpiled to XSLT, you would usually run it against the XML input to get an XdmDestination, and then you need to look into that result, an SVRL report, for anything you consider a validation error, so assuming any failed assert in Schematron for you is a validation error, with XPath you could check for /Q{http://purl.oclc.org/dsdl/svrl}schematron-output!(Q{http://purl.oclc.org/dsdl/svrl}failed-assert
. If there are none, the Schematron validation passed, if there are any, these are the failed validations and you could output them.
Can you perhaps attach the XML, XSLT, and the result of the transformation?
I have now attached 2 files which I assume I have to use for xslt-validation. But I do not understand "the result of the transformation" - I can not see how to find this. But with the attached xml-file i know there should be 28 errors in according to xslt-validation. The purpose for me is to find them in a way with xslt-validation and to report these errors.
Regards Michael
When I run the transformation from the command line like this:
java net.sf.saxon.Transform -xsl:OIOUBL_Invoice_schematron.xsl -s:MCE-Invoice.xml -t !indent=yes
I get output like this:
<?xml version="1.0" encoding="utf-8"?>
<Schematron xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns:ccts="urn:oasis:names:specification:ubl:schema:xsd:CoreComponentParameters-2"
xmlns:doc="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"
xmlns:iso="http://purl.oclc.org/dsdl/schematron"
xmlns:sch="http://www.ascc.net/xml/schematron"
xmlns:sdt="urn:oasis:names:specification:ubl:schema:xsd:SpecializedDatatypes-2"
xmlns:udt="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<Information>Checking OIOUBL-2.1 Invoice, 2023-02-06, Version 1.13.2.50919c6</Information>
<Error context="cac:OrderReference/cac:DocumentReference">
<Pattern>cac:Attachment/cbc:EmbeddedDocumentBinaryObject and cac:Attachment/cac:ExternalReference</Pattern>
<Description>[F-LIB171] Use either EmbeddedDocumentBinaryObject or ExternalReference</Description>
<Xpath>/Invoice[1]/cac:OrderReference[1]/cac:DocumentReference[1]</Xpath>
</Error>
<Error context="cac:BillingReference/cac:InvoiceDocumentReference">
<Pattern>cac:Attachment/cbc:EmbeddedDocumentBinaryObject and cac:Attachment/cac:ExternalReference</Pattern>
<Description>[F-LIB171] Use either EmbeddedDocumentBinaryObject or ExternalReference</Description>
<Xpath>/Invoice[1]/cac:BillingReference[1]/cac:InvoiceDocumentReference[1]</Xpath>
</Error>
....
The <Error>
elements in the output are your validation errors.
You can equally well run the transformation from your Java application using the s9api API if you prefer. The way you have written it, the transformation output is going to the Serializer
object, which is writing it to Console.Out
; but of course you can send it to a file if you prefer; or if you want to examine the validation report further in your Java application, you can send it to an XdmDestination
or DOMDestination
instead of to a Serializer
.
Thank you very much for this - but how to do this with Saxon 10 to C#/.NET ? Is there a way for this output via c# ?
Thanks in advance.
Regards Michael
Simple command line app accepting the XSLT and the XML file names as the command line arguments would be alike
using System;
using System.IO;
using Saxon.Api;
namespace SaxonHE10NetOIOUBLInvoiceValidation
{
internal class Program
{
static void Main(string[] args)
{
Processor processor = new Processor();
XsltCompiler xsltCompiler = processor.NewXsltCompiler();
XsltExecutable xsltExecutable = xsltCompiler.Compile(new Uri(Path.Combine(Environment.CurrentDirectory, args[0])));
Xslt30Transformer xslt30Transformer = xsltExecutable.Load30();
XdmDestination validationReport = new XdmDestination();
using (var inputStream = File.OpenRead(args[1]))
{
xslt30Transformer.Transform(inputStream, new Uri(Path.Combine(Environment.CurrentDirectory, args[1])), validationReport);
}
XPathCompiler xpathCompiler = processor.NewXPathCompiler();
var validationErrors = xpathCompiler.Evaluate("//Error", validationReport.XdmNode);
if (validationErrors.Count > 0)
{
Console.WriteLine("Validation failed with " + validationErrors.Count + " error(s):");
Console.WriteLine(validationErrors);
}
else
{
Console.WriteLine("Input file " + args[1] + " is valid against compiled Schematron " + args[0] + ".");
}
}
}
}
Thank you very much.
I have already taken a deep look into your samples and tried to make the abovementioned code based on these samples to Version 10 - but honestly I don't think I can understand what I need to do :-( So therefore I have tried to ask here in this forum - I really hope that it is okay...
So what I need do do in C#/.NET for reporting XLST errors in a XML-file - unfortunately I can't figure out :-(
Regards Michael
@Martin Honnen
Thank you very much for this sample - I will take a deep look into it.
Thanks again :-)
Regards Michael
Thank you very much for this codesample - I have now got it to work exactly as I wish :-)
So Thanks again...
Regards Michael
- Status changed from New to Closed
Closing because the conversation seems to have ended.
Please register to edit this issue
Also available in: Atom
PDF