Project

Profile

Help

Support #6300

closed

Howto correctly validate a xml-file against a xslt file in Saxon version 10

Added by Michael Eriksen 4 months ago. Updated 2 months ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Category:
-
Sprint/Milestone:
-
Start date:
2023-12-20
Due date:
% Done:

0%

Estimated time:
Legacy ID:
Applies to branch:
10
Fix Committed on Branch:
Fixed in Maintenance Release:
Platforms:

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

MCE-Invoice.xml (277 KB) MCE-Invoice.xml Michael Eriksen, 2023-12-21 15:13
OIOUBL_Invoice_Schematron.xsl (2.06 MB) OIOUBL_Invoice_Schematron.xsl Michael Eriksen, 2023-12-21 15:14
Actions #1

Updated by Michael Kay 4 months ago

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.

Actions #2

Updated by Michael Kay 4 months ago

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".

Actions #3

Updated by Michael Eriksen 4 months ago

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

Actions #4

Updated by Martin Honnen 4 months ago

@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.

Actions #5

Updated by Michael Kay 4 months ago

Can you perhaps attach the XML, XSLT, and the result of the transformation?

Actions #6

Updated by Michael Eriksen 4 months ago

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

Actions #7

Updated by Michael Kay 4 months ago

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.

Actions #8

Updated by Michael Eriksen 4 months ago

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

Actions #9

Updated by Martin Honnen 4 months ago

@Michael Eriksen,

have you had a look at the C# samples on using Saxon 10 .NET in the resources download for Saxon 10 you can find at https://github.com/Saxonica/Saxon-HE/tree/main/10/resources?

They are also online, the complete file is https://saxonica.plan.io/projects/saxonmirrorhe/repository/he/revisions/he_mirror_saxon_10_9/entry/src/samples/cs/ExamplesHE.cs and has various examples on how to use XSLT, XPath and XQuery with Saxon 10 .NET, you might want to look into examples like https://saxonica.plan.io/projects/saxonmirrorhe/repository/he/revisions/he_mirror_saxon_10_9/entry/src/samples/cs/ExamplesHE.cs#L416 that run a transformation to the Console or like https://saxonica.plan.io/projects/saxonmirrorhe/repository/he/revisions/he_mirror_saxon_10_9/entry/src/samples/cs/ExamplesHE.cs#L721 that creates the result as an XdmDestination, on that you could then use XPath evaluation to count and/or output the Error elements in the result.

Actions #10

Updated by Martin Honnen 4 months ago

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] + ".");
            }
        }
    }
}
Actions #11

Updated by Michael Eriksen 4 months ago

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

Actions #12

Updated by Michael Eriksen 4 months ago

@Martin Honnen

Thank you very much for this sample - I will take a deep look into it.

Thanks again :-)

Regards Michael

Actions #13

Updated by Michael Eriksen 4 months ago

Thank you very much for this codesample - I have now got it to work exactly as I wish :-) So Thanks again... Regards Michael

Actions #14

Updated by Michael Kay 2 months ago

  • 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