Schematron是一种基于断言规则的XML验证语言,它不定义XML的文档结构,而是通过编写业务规则来检查XML内容是否符合预期。和XSD侧重结构约束不同,Schematron更关注内容之间的逻辑关系,能处理很多XSD无法覆盖的复杂验证场景。

Schematron的核心概念
Schematron的核心由几个关键元素组成,理解这些元素是编写验证规则的基础:
- schema:Schematron规则文件的根元素,包含所有验证规则
- pattern:一组相关的规则集合,用于对某一类场景做统一校验
- rule:具体的验证规则,通过上下文指定规则作用的XML节点
- assert:正向断言,当条件不满足时输出错误信息
- report:反向报告,当条件满足时输出提示信息
Schematron与XSD的能力差异
XSD主要用来定义XML的元素、属性、数据类型、层级结构等静态约束,比如某个元素是否必填、数据类型是不是整数、子元素的出现顺序等。但遇到以下场景时,XSD就很难处理了:
- 某个元素的值需要和另一个元素的值做比较,比如订单的付款金额不能大于订单总金额
- 某个元素是否必填取决于另一个元素的值,比如选择快递配送时,收货地址必填
- 需要校验内容是否符合特定业务规则,比如员工年龄不能小于18岁且大于60岁
而Schematron基于XPath表达式做规则判断,天然支持上下文关联的内容校验,正好可以弥补XSD的短板。实际使用中通常会把XSD和Schematron结合,XSD做结构校验,Schematron做业务规则校验。
Schematron验证示例
下面通过一个订单XML的验证场景,展示Schematron如何实现比XSD更灵活的校验。
待验证的XML示例
<order>
<orderId>10001</orderId>
<totalAmount>500</totalAmount>
<paidAmount>600</paidAmount>
<deliveryType>express</deliveryType>
<address></address>
</order>
编写Schematron规则文件
我们需要校验两个规则:一是付款金额不能大于订单总金额,二是选择快递配送时收货地址不能为空。
<schema xmlns="http://purl.oclc.org/dsdl/schematron">
<pattern id="orderRule">
<rule context="order">
<assert test="paidAmount <= totalAmount">
付款金额不能大于订单总金额,当前付款金额:<value-of select="paidAmount"/>,订单总金额:<value-of select="totalAmount"/>
</assert>
<assert test="not(deliveryType='express') or normalize-space(address) != ''">
选择快递配送时,收货地址不能为空
</assert>
</rule>
</pattern>
</schema>
Java中执行Schematron验证的代码示例
可以使用Schematron的Java实现库来执行验证,以下是完整的验证代码:
import org.schematron.svrl.SVRLWriter;
import org.schematron.util.SchematronResource;
import org.xml.sax.InputSource;
import java.io.StringReader;
import java.io.StringWriter;
public class SchematronDemo {
public static void main(String[] args) throws Exception {
// Schematron规则文件内容
String schematronContent = "<schema xmlns="http://purl.oclc.org/dsdl/schematron">n" +
" <pattern id="orderRule">n" +
" <rule context="order">n" +
" <assert test="paidAmount <= totalAmount">n" +
" 付款金额不能大于订单总金额,当前付款金额:<value-of select="paidAmount"/>,订单总金额:<value-of select="totalAmount"/>n" +
" </assert>n" +
" <assert test="not(deliveryType='express') or normalize-space(address) != ''">n" +
" 选择快递配送时,收货地址不能为空n" +
" </assert>n" +
" </rule>gt;n" +
" </pattern>n" +
"</schema>";
// 待验证的XML内容
String xmlContent = "<order>n" +
" <orderId>10001</orderId>n" +
" <totalAmount>500</totalAmount>n" +
" <paidAmount>600</paidAmount>n" +
" <deliveryType>express</deliveryType>n" +
" <address></address>n" +
"</order>";
// 加载Schematron规则
SchematronResource resource = SchematronResource.fromString(schematronContent);
// 执行验证
StringWriter writer = new StringWriter();
SVRLWriter svrlWriter = new SVRLWriter(writer);
resource.validate(new InputSource(new StringReader(xmlContent)), svrlWriter);
// 输出验证结果
System.out.println("验证结果:n" + writer.toString());
}
}
执行上面的代码后,会输出两条错误提示,分别对应付款金额超限和快递地址为空的问题,这正是XSD无法实现的业务逻辑校验。
Schematron的适用场景
Schematron适合用在需要复杂业务规则校验的XML处理场景,比如金融报文校验、行业规范XML校验、数据交换格式的业务规则校验等。它不是XSD的替代品,而是补充,两者结合可以覆盖从结构到内容的全维度XML验证需求。
SchematronXSDXML_validation规则验证修改时间:2026-07-02 18:09:36