xml-model处理指令不直接指向.sch文件,而应指向由schematron编译生成的xslt文件;2. schematron是声明性规则语言,需通过xslt处理器编译为xslt样式表才能执行;3. xml-model通过schematypens属性标识模式类型,href指向可执行的验证器文件;4. 常见错误是将href指向原始.sch文件,导致验证无法进行;5. xml-model支持多种模式语言,包括dtd、xsd、relax ng等,需正确设置type和schematypens属性以实现关联;6. 该机制依赖工具支持,主要用于提供验证提示而非强制执行。
当你需要让XML文档本身“知道”它应该遵循哪些验证规则时,
xml-model
处理指令(Processing Instruction, PI)是一个非常实用的机制。它本质上是一个给解析器或工具的提示,告诉它们去哪里找到与当前XML文档相关的模式定义,包括Schematron规则。简单来说,就是通过这个指令,你的XML文件可以“指引”外部工具去执行相应的Schematron验证。
解决方案
要将
xml-model
处理指令与Schematron规则关联起来,核心在于理解Schematron通常需要被“编译”成XSLT才能执行。因此,
xml-model
指令的
href
属性不会直接指向原始的
.sch
文件,而是指向一个由Schematron编译生成的XSLT样式表。
这是它的基本结构:
<?xml version="1.0" encoding="UTF-8"?> <?xml-model href="your-schematron-compiled.xsl" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?> <!-- 你的XML文档内容 --> <root> <element>一些数据</element> </root>
这里有几个关键点:
-
href
: 这个属性指向的是你经过编译后的Schematron XSLT文件。比如,你可能用
xsltproc
或者其他工具,将一个
.sch
文件转换成了一个
.xsl
文件。这个
.xsl
文件就是实际执行Schematron规则的验证器。
-
type
: 通常设为
application/xml
或者
text/xsl
(虽然
application/xml
更通用,因为它指明了这是一个XML文档,具体类型由
schematypens
进一步限定)。
-
schematypens
: 这是最重要的部分,它明确告诉处理工具,
href
指向的这个资源,其模式语言是Schematron。它的固定值是
http://purl.oclc.org/dsdl/schematron
。
所以,整个流程是:先编写Schematron规则(
.sch
文件),然后使用Schematron处理器(如Saxon、xsltproc配合ISO Schematron XSLT)将其编译成一个可执行的XSLT样式表,最后在你的XML文档中用
xml-model
指令指向这个编译后的XSLT文件。这样,任何支持
xml-model
指令的XML工具在打开或处理你的XML文档时,就有可能自动找到并应用这些Schematron规则进行验证。
Schematron和XSLT之间究竟有什么关系?
这绝对是初学者最容易感到困惑的地方,甚至一些有经验的开发者也会时不时地在这里打个问号。简单来说,Schematron本身并不是一个执行引擎,它更像是一种“声明性”的语言,用来描述你的XML文档应该满足哪些业务规则和结构约束。它定义了断言(assert)、报告(report)等概念,让你能以一种非常直观的方式写出“如果这个条件成立,那么就报告一个错误”这样的规则。
而XSLT(eXtensible Stylesheet Language Transformations)则是一种真正的“处理”语言,它能够转换XML文档。Schematron之所以能工作,很大程度上是因为它被设计成可以方便地转换为XSLT。主流的Schematron处理器,比如ISO Schematron实现,就是通过一系列XSLT样式表将你的
.sch
文件转换成一个能够对目标XML文档执行验证并生成报告的XSLT样式表。
所以,当你写好一个Schematron文件(例如
my-rules.sch
),你需要运行一个“编译”步骤,比如使用
xsltproc
加上ISO Schematron提供的骨架样式表(如
iso_schematron_skeleton_for_saxon.xsl
),来生成一个实际的XSLT验证器(例如
my-rules-compiled.xsl
)。这个
my-rules-compiled.xsl
才是真正意义上的“Schematron验证器”,它能被任何标准的XSLT处理器执行。
xml-model
指令正是指向这个编译后的XSLT文件。
这种设计的好处在于,Schematron不需要自己实现一套复杂的执行逻辑,它直接复用了成熟且高效的XSLT处理器生态。对于我们使用者而言,这意味着Schematron的验证能力可以无缝集成到各种支持XSLT的工具和环境中。
为什么我的
<?xml-model?>
<?xml-model?>
指向Schematron文件却不工作?
这是一个非常常见的问题,几乎可以肯定地说,你犯了那个经典的错误:直接把
href
指向了原始的
.sch
文件。
xml-model
处理指令,以及大多数支持它的工具,期望
href
指向的是一个可执行的样式表或者一个可以直接解析的模式定义文件。原始的
.sch
文件,就像我们前面讨论的,它只是Schematron规则的声明,它本身不是一个可直接运行的程序。它需要经过一个“编译”步骤,被转换成XSLT样式表后,才能被XSLT处理器执行。
所以,如果你的
<?xml-model href="my-rules.sch" ...?>
不工作,那几乎可以确定是因为
my-rules.sch
是一个原始的Schematron文件,而不是一个编译后的XSLT文件。
另一个可能的原因是,你使用的工具或浏览器根本就不支持
xml-model
处理指令,或者它支持但没有实现Schematron的自动发现和执行。
xml-model
更多的是一种“提示”机制,而不是一个强制性的、所有XML解析器都必须实现的规范。它主要用于某些特定的XML编辑器、ide或浏览器(例如firefox在某些情况下可以利用它来应用XSLT样式表)来提供辅助功能。在服务器端或自动化脚本中进行验证时,我们通常还是会明确地调用一个Schematron处理器来执行验证,而不是依赖
xml-model
。
因此,解决办法很简单:
- 确保你的
.sch
文件已经被编译成了XSLT。
- 将
xml-model
的
href
属性指向那个编译后的XSLT文件。
- 检查你使用的工具是否真的支持
xml-model
指令来自动触发Schematron验证。
如果不支持,你可能需要在你的工作流中明确地添加一个Schematron验证步骤。
除了Schematron,
xml-model
xml-model
还能关联其他XML模式语言吗?
当然可以!
xml-model
指令设计得非常通用,它不仅仅局限于Schematron。它旨在提供一种统一的方式来声明XML文档所遵循的各种模式定义。常见的XML模式语言,如DTD(Document Type Definition)、XML Schema(XSD)和Relax NG,都可以通过
xml-model
指令来关联。
关键在于正确使用
type
和
schematypens
这两个属性来告诉处理工具,
href
指向的资源是什么类型的模式:
-
DTD (Document Type Definition) DTD是XML最早的模式语言。
<?xml-model href="your-dtd.dtd" type="application/xml-dtd"?>
或者,如果DTD是内部子集,则不需要
xml-model
,直接在
DOCTYPE
声明中引用即可。
-
XML Schema (XSD) XML Schema是W3C推荐的强大模式语言,通常用于定义复杂的XML结构和数据类型。
<?xml-model href="your-schema.xsd" type="application/xml" schematypens="http://www.w3.org/2001/XMLSchema"?>
这里
type
设置为
application/xml
,
schematypens
则明确指出这是一个XML Schema。
-
Relax NG (RELAX NG) Relax NG是一种简洁且强大的模式语言,通常有两种语法:XML语法和紧凑语法。
- XML 语法:
<?xml-model href="your-relaxng-xml.rng" type="application/relax-ng+xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
- 紧凑语法:
<?xml-model href="your-relaxng-compact.rnc" type="application/relax-ng-compact-syntax" schematypens="http://relaxng.org/ns/structure/1.0"?>
schematypens
对于Relax NG也是固定的。
- XML 语法:
xml-model
指令的灵活性在于,它提供了一个标准化的方式来让XML文档“自描述”其验证需求。这对于开发工具、IDE和任何需要理解XML文档结构的应用来说,都是一个非常有用的提示。它简化了验证配置,使得文档本身就包含了如何被验证的信息,而不是依赖于外部的、可能容易出错的配置。