求助:使用C#验证ISO版Schematron XML失败,已试Saxon-HE等工具
C# 验证XML符合ISO Schematron规则的可行方案
方案一:正确配置Saxon-HE实现验证
Saxon-HE支持ISO Schematron验证,但需要先将Schematron规则编译为XSLT,再用XSLT转换XML获取验证结果。以下是完整实现步骤:
- 安装Saxon-HE NuGet包:
Install-Package Saxon-HE - 下载ISO Schematron官方骨架样式表
iso_schematron_skeleton.xsl,用于将Schematron转换为可执行的XSLT - 编写验证代码:
using Saxon.Api; public class IsoSchematronValidator { public static bool ValidateXml(string xmlFilePath, string schematronFilePath, string skeletonXslPath, out string errorMessages) { errorMessages = string.Empty; var processor = new Processor(); var xsltCompiler = processor.NewXsltCompiler(); // 编译Schematron为验证用XSLT var skeletonXslt = xsltCompiler.Compile(new Uri(skeletonXslPath)); var schematronTransformer = skeletonXslt.Load(); schematronTransformer.InitialContextNode = processor.NewDocumentBuilder().Build(new Uri(schematronFilePath)); var compiledXsltDest = new XdmDestination(); schematronTransformer.Run(compiledXsltDest); // 使用生成的XSLT验证XML var validatorXslt = xsltCompiler.Compile(compiledXsltDest.XdmNode); var validationTransformer = validatorXslt.Load(); validationTransformer.InitialContextNode = processor.NewDocumentBuilder().Build(new Uri(xmlFilePath)); var validationResultDest = new XdmDestination(); validationTransformer.Run(validationResultDest); // 提取验证错误信息 var resultDoc = validationResultDest.XdmNode; var failedAsserts = resultDoc.SelectNodes("//svrl:failed-assert"); foreach (var assert in failedAsserts) { var text = assert.SelectSingleNode(".//svrl:text")?.ToString(); var location = assert.Attribute(new QName("location"))?.Value; errorMessages += $"验证失败 [{location}]: {text}\n"; } return string.IsNullOrWhiteSpace(errorMessages); } }
注意事项
- 确保你的Schematron文件是ISO标准格式,根元素需带有
http://purl.oclc.org/dsdl/schematron命名空间 - 骨架样式表需与你的Schematron版本匹配,建议使用最新版的ISO骨架文件
方案二:使用Schematron.NET原生验证
如果Saxon-HE的配置过于繁琐,可以尝试Schematron.NET,它原生支持ISO Schematron,无需手动转换XSLT:
- 安装NuGet包:
Install-Package Schematron.NET - 验证代码示例:
using Schematron; public static bool ValidateWithSchematronNet(string xmlPath, string schematronPath, out string validationMessages) { validationMessages = string.Empty; var validator = new Validator(); validator.LoadSchematron(schematronPath); var validationResults = validator.Validate(xmlPath); foreach (var result in validationResults) { validationMessages += $"{result.Message} (上下文路径: {result.Context})\n"; } return validationResults.Count == 0; }
常见问题排查
- 放弃NMatrix.Schematron:该库已停止维护,对新版ISO Schematron支持不足,容易出现兼容性问题
- 检查命名空间:Schematron文件中必须正确声明ISO命名空间,否则验证会失败
- Saxon版本:使用最新稳定版的Saxon-HE,旧版本可能存在ISO Schematron解析bug
内容的提问来源于stack exchange,提问作者Manu
相关产品推荐
相关产品推荐

