Saxon 9.8.3中虚拟/实际URI流处理SVRL结果不一致问题咨询
我来帮你分析这个问题——你遇到的情况大概率和Saxon流处理模式下对Base URI的处理逻辑,以及你的SVRL规则的依赖有关,先梳理下关键信息和可能的操作/配置问题:
问题场景回顾
你在使用Saxon 9.8.3进行流处理时,发现设置虚拟Base URI(http://dummy.base.uri/)后,SVRL验证无法正确返回预期的<svrl:failed-assert>节点;但换成实际URI时,断言正常触发。你的核心代码如下:
Processor processor = new Processor(); // Load the source document var documentbuilder = processor.NewDocumentBuilder(); documentbuilder.BaseUri = new Uri("http://dummy.base.uri/"); XdmNode input = documentbuilder.Build(xmlstream); // Create a transformer for the stylesheet. var compiler = processor.NewXsltCompiler(); compiler.ErrorList = new System.Collections.Generic.List<Exception>(); XsltTransformer transformer = compiler.Compile(xsltStream).Load(); transformer.InitialContextNode = input;
预期的正确断言结果是:
<svrl:failed-assert test=". != ''" id="EHF-COMMON-R001" flag="fatal" location="/:CreditNote[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2'][1]/:CreditNoteLine[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2'][1]/*:Note[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2'][1]">
svrl:textDocument MUST not contain empty elements.</svrl:text>
</svrl:failed-assert>
可能的操作/配置问题分析
SVRL规则依赖文档Base URI
很多Schematron(SVRL)规则会隐式或显式依赖文档的Base URI:比如规则中使用了base-uri()、document-uri()函数进行条件判断,或者在位置匹配逻辑中关联了文档URI。如果你的SVRL样式表存在这类逻辑,虚拟URI会导致条件不满足,直接跳过断言。流处理模式下Base URI的传递缺陷
Saxon 9.8.3的流处理模块对文档节点元数据(包括Base URI)的处理存在已知的兼容性问题。你给DocumentBuilder设置的Base URI可能没有正确绑定到流处理的上下文节点中,导致SVRL规则中依赖节点Base URI的校验逻辑失效。虚拟URI的协议类型影响
你使用的是HTTP协议的虚拟URI(http://dummy.base.uri/),部分XML处理器对HTTP类型的虚拟URI会有特殊的解析或权限限制,而实际URI(比如本地文件URI)则没有这类限制,这可能导致流处理时节点的上下文信息异常。
建议的排查和修复步骤
- 检查SVRL样式表中的URI相关逻辑:搜索你的SVRL文件,确认是否存在
base-uri()、document-uri()的调用,或者基于URI的条件分支。如果有,调整逻辑以兼容虚拟URI,或者确保虚拟URI符合规则的预期。 - 验证Base URI的传递有效性:在构建
XdmNode后,打印input.BaseUri的值,确认虚拟URI是否被正确设置。如果流处理过程中Base URI丢失,尝试显式为上下文节点设置Base URI(部分Saxon版本支持通过API调整节点元数据)。 - 测试非流模式下的虚拟URI:暂时关闭流处理,用普通方式加载文档并执行SVRL验证。如果非流模式下虚拟URI能正常触发断言,说明问题是Saxon 9.8.3流处理的版本缺陷,建议升级到较新的Saxon版本(比如9.9或以上),后续版本修复了大量流处理相关的bug。
- 替换虚拟URI类型:尝试使用本地文件类型的虚拟URI(比如
file:///dummy/base/uri/)替代HTTP虚拟URI,看是否能触发预期的断言。
内容的提问来源于stack exchange,提问作者majid ismail

