使用 Schematron 进行 XML 验证

问题描述 投票:0回答:2

你知道有什么 C#/NET 库可以用 Schematron 验证 XML 文件吗?

我搜索了但找不到任何东西。

感谢您的帮助。

安东尼

我尝试使用 Schematron.NET 库,但验证不起作用。

我试过这段代码:

try
            {                       
                using (var xrXML = XmlReader.Create("xmlData.xml"))                                
                {
                    using (var xrSch = XmlReader.Create("schematron.sch"))
                    {
                        Validator vld = new Validator();
                        var schema = new Schema();
                        schema.Load(xrSch);
                        vld.AddSchema(schema);
                        var path = vld.Validate(xrXML);
                        vld.ValidateSchematron(path);                          
                    }
                }
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

即使插入无效的 xml 也不会返回错误。

c# xml xsd schematron
2个回答
1
投票

执行 Schematron 验证的一种既定方法是使用 XSLT 将 Schematron 模式编译/转换为中间 XSLT,然后可将其用于验证输入 XML 实例文档,生成 SVRL 输出。 Schematron 已建立的现代 XSLT 2/3 实现称为 Schxslt,可在 Github 上获得,网址为 https://github.com/schxslt/schxslt,当前版本为 1.9.5 https://github.com /schxslt/schxslt/releases/tag/v1.9.5.

在 .NET 世界中,要使用 XSLT 2/3 版本 Schxslt,您需要使用像 Saxon 这样的 XSLT 2.0 或 3.0 处理器,可用于 Saxonica 的 NuGet 上的 .NET 框架,网址为 https://www.nuget。 org/packages/Saxon-HE 和 .NET 6/7(又名 .NET Core)作为商业 SaxonCS https://www.nuget.org/packages/SaxonCS 和(在开源 IKVM 交叉-编译版本(免责声明:我创建了那个包))与 NuGet 包https://www.nuget.org/packages/SaxonHE11s9apiExtensions.

使用 Saxon,您将使用 Schxslt XSLT 文件将 Schematron 模式本身转换为中间 XSLT,然后在实例 XML 上运行以验证它。使用包 https://www.nuget.org/packages/SaxonHE11s9apiExtensions 并直接从 Maven 中提取 Schxslt 的完整命令行示例如下:

using net.sf.saxon.s9api;
using net.liberty_development.SaxonHE11s9apiExtensions;
using System.Reflection;
using System.Diagnostics;
using net.sf.saxon.lib;

namespace SchematronSchxsltSaxonHE11Net
{
    internal class Program
    {
        static string schxsltSvrlXsltResource = "/xslt/2.0/pipeline-for-svrl.xsl";

        static void Main(string[] args)
        {
            Console.WriteLine($"Schematron Schxslt Validator using Schxslt 1.9.5 and Saxon HE 11.5 under {Environment.Version} {Environment.OSVersion}");

            if (args.Length != 2)
            {
                Console.WriteLine($"Usage: SchematronSchxsltSaxonHE11Net schema.sch input.xml");
                return;
            }

            var stopWatch = new Stopwatch();
            stopWatch.Start();
            // load Schxslt assembly
            var schxsltAssembly = Assembly.Load("schxslt");
            ikvm.runtime.Startup.addBootClassPathAssembly(schxsltAssembly);

            // force loading of updated xmlresolver, not necessary with Saxon 11.5
            //ikvm.runtime.Startup.addBootClassPathAssembly(Assembly.Load("org.xmlresolver.xmlresolver"));
            //ikvm.runtime.Startup.addBootClassPathAssembly(Assembly.Load("org.xmlresolver.xmlresolver_data"));

            var processor = new Processor(false);

            var xsltCompiler = processor.newXsltCompiler();

            var jarResolver = new JarResolver();

            xsltCompiler.setResourceResolver(jarResolver);

            var compiledSchxslt = xsltCompiler.compile(jarResolver.resolve(new ResourceRequest() { baseUri = "schxslt", relativeUri = schxsltSvrlXsltResource })).load30();

            var compiledSchematron = new XdmDestination();
            compiledSchematron.setBaseURI(new Uri(new FileInfo(args[0]).FullName).ToURI());

            compiledSchxslt.Transform(new FileInfo(args[0]), compiledSchematron);

            var xsltCompiler2 = processor.newXsltCompiler();

            var schematronValidator = xsltCompiler2.compile(compiledSchematron.getXdmNode().asSource()).load30();

            var svrlResult = new XdmDestination();

            schematronValidator.Transform(new FileInfo(args[1]), svrlResult);

            var valid = processor.newXPathCompiler().evaluateSingle("not((/Q{http://purl.oclc.org/dsdl/svrl}schematron-output!(Q{http://purl.oclc.org/dsdl/svrl}failed-assert , Q{http://purl.oclc.org/dsdl/svrl}successful-report)))", svrlResult.getXdmNode()).getUnderlyingValue().effectiveBooleanValue();

            Console.WriteLine($"XML document {args[1]} is {(valid ? "" : "not ")}valid against Schematron schema {args[0]}.");

            if (!valid)
            {
                Console.WriteLine($"{Environment.NewLine}Validation report:{Environment.NewLine}{svrlResult.getXdmNode()}");
            }

            stopWatch.Stop();

            Console.WriteLine($"Elapsed time: {stopWatch.Elapsed}");
        }
    }
}

示例项目位于https://github.com/martin-honnen/SchematronSchxsltSaxonHE11Net.

当然可以使用 Saxonica 的用于 .NET 框架的 Saxon-HE NuGet 包或用于 .NET 6/7 的 Saxonica 的商业 SaxonCS 编写类似的代码。

最后,如果您使用像 Schxslt 这样基于 XSLT 的实现,您需要一个 XSLT 2/3 处理器来执行 Schematron 验证。


0
投票

我试过你给我的代码,但它返回错误类 JarResolver。

var jarResolver = new JarResolver();

你还有其他图书馆要用吗?

谢谢

© www.soinside.com 2019 - 2024. All rights reserved.