目前,我正在使用PHSchematron库来验证Java中的schematron。如果我将<sch:p>
标记作为<sch:pattern>
的子代,则它将抛出NullPointerException,因为SchematronOutputType为null。
我尝试将<sch:p>
用作<sch:schema>
和<sch:rule>
的子元素,尽管XSD表示p
元素可以是schema
,phase
,pattern
的子元素。
我不确定问题是否出在PHSchematron的实现上。
我认为xmlns:sch指向1.5 schematron XSD版本。
schematron_1.5.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<!-- schemaVersion of 2001/02/15 -->
<xs:schema xmlns:sch="http://www.ascc.net/xml/schematron" xmlns="http://www.ascc.net/xml/schematron" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.ascc.net/xml/schematron" version="+//IDN sinica.edu.tw//SGML W3C XML Schema for Schematron 1.5//EN">
<xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd">
<xs:annotation>
<xs:documentation>
Get access to the xml: attribute groups for xml:lang
</xs:documentation>
</xs:annotation>
</xs:import>
<xs:annotation>
<xs:documentation source="http://www.ascc.net/xml/resource/schematron/schematron.html" xml:lang="en"/>
</xs:annotation>
<xs:element name="active">
<xs:complexType mixed="true">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="sch:dir"/>
<xs:element ref="sch:emph"/>
<xs:element ref="sch:span"/>
</xs:choice>
<xs:attribute name="pattern" type="xs:IDREF" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="assert">
<xs:complexType mixed="true">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="sch:name"/>
<xs:element ref="sch:emph"/>
<xs:element ref="sch:dir"/>
<xs:element ref="sch:span"/>
<xs:any namespace="##other" processContents="lax"/>
</xs:choice>
<xs:attribute name="test" type="xs:string" use="required"/>
<xs:attribute name="role" type="xs:NMTOKEN"/>
<xs:attribute name="id" type="xs:string"/>
<xs:attribute name="diagnostics" type="xs:IDREFS"/>
<xs:attribute name="icon" type="xs:anyURI"/>
<xs:attribute name="subject" type="xs:string" default="."/>
<xs:attribute ref="xml:lang"/>
<xs:anyAttribute namespace="##other" processContents="lax"/>
</xs:complexType>
</xs:element>
<xs:element name="diagnostic">
<xs:complexType mixed="true">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="sch:value-of"/>
<xs:element ref="sch:emph"/>
<xs:element ref="sch:dir"/>
<xs:element ref="sch:span"/>
<xs:any namespace="##other" processContents="lax"/>
</xs:choice>
<xs:attribute name="id" type="xs:ID" use="required"/>
<xs:attribute name="icon" type="xs:anyURI"/>
<xs:attribute ref="xml:lang"/>
<xs:anyAttribute namespace="##other" processContents="lax"/>
</xs:complexType>
</xs:element>
<xs:element name="diagnostics">
<xs:complexType>
<xs:sequence>
<xs:element ref="diagnostic" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="dir">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="value">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="ltr"/>
<xs:enumeration value="rtl"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="emph" type="xs:string"/>
<xs:element name="extends">
<xs:complexType>
<xs:attribute name="rule" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="key">
<xs:complexType>
<xs:attribute name="name" type="xs:NMTOKEN" use="required"/>
<xs:attribute name="path" type="xs:string" use="required"/>
<xs:attribute name="icon" type="xs:anyURI"/>
</xs:complexType>
</xs:element>
<xs:element name="name">
<xs:complexType>
<xs:attribute name="path" type="xs:string" default="."/>
</xs:complexType>
</xs:element>
<xs:element name="ns">
<xs:complexType>
<xs:attribute name="uri" type="xs:anyURI" use="required"/>
<xs:attribute name="prefix" type="xs:NCName"/>
</xs:complexType>
</xs:element>
<xs:element name="p">
<xs:complexType mixed="true">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="sch:dir"/>
<xs:element ref="sch:emph"/>
<xs:element ref="sch:span"/>
</xs:choice>
<xs:attribute name="id" type="xs:string"/>
<xs:attribute name="class" type="xs:string"/>
<xs:attribute name="icon" type="xs:anyURI"/>
<xs:attribute ref="xml:lang"/>
<xs:anyAttribute namespace="##other" processContents="lax"/>
</xs:complexType>
</xs:element>
<xs:element name="pattern">
<xs:complexType>
<xs:sequence>
<xs:element ref="p" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="sch:rule" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="see" type="xs:anyURI"/>
<xs:attribute name="id" type="xs:string"/>
<xs:attribute name="icon" type="xs:anyURI"/>
</xs:complexType>
</xs:element>
<xs:element name="phase">
<xs:complexType>
<xs:sequence>
<xs:element ref="sch:p" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="sch:active" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="fpi" type="xs:string"/>
<xs:attribute name="icon" type="xs:anyURI"/>
</xs:complexType>
</xs:element>
<xs:element name="report">
<xs:complexType mixed="true">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="sch:name"/>
<xs:element ref="sch:emph"/>
<xs:element ref="sch:dir"/>
<xs:element ref="sch:span"/>
<xs:any namespace="##other" processContents="lax"/>
</xs:choice>
<xs:attribute name="test" type="xs:string" use="required"/>
<xs:attribute name="role" type="xs:NMTOKEN"/>
<xs:attribute name="id" type="xs:string"/>
<xs:attribute name="diagnostics" type="xs:IDREFS"/>
<xs:attribute name="icon" type="xs:anyURI"/>
<xs:attribute name="subject" type="xs:string" default="."/>
<xs:attribute ref="xml:lang"/>
</xs:complexType>
</xs:element>
<xs:element name="rule">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element ref="sch:assert"/>
<xs:element ref="sch:report"/>
<xs:element ref="sch:key"/>
<xs:element ref="sch:extends"/>
</xs:choice>
<xs:attribute name="context" type="xs:string"/>
<xs:attribute name="abstract" type="xs:boolean" default="false"/>
<xs:attribute name="role" type="xs:NMTOKEN"/>
<xs:attribute name="id" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="schema">
<xs:complexType>
<xs:sequence>
<xs:element ref="sch:title" minOccurs="0"/>
<xs:element ref="sch:ns" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="sch:p" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="sch:phase" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="sch:pattern" maxOccurs="unbounded"/>
<xs:element ref="sch:p" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="sch:diagnostics" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="id" type="xs:ID"/>
<xs:attribute name="fpi" type="xs:string"/>
<xs:attribute name="schemaVersion" type="xs:string"/>
<xs:attribute name="defaultPhase" type="xs:string"/>
<xs:attribute name="icon" type="xs:anyURI"/>
<xs:attribute name="ns" type="xs:anyURI"/>
<xs:attribute name="version" type="xs:string" default="1.5"/>
<xs:attribute ref="xml:lang"/>
<xs:anyAttribute namespace="##other" processContents="lax"/>
</xs:complexType>
<xs:unique name="assertId">
<xs:selector xpath="sch:pattern/sch:rule/sch:assert"/>
<xs:field xpath="@id"/>
</xs:unique>
<xs:unique name="reportId">
<xs:selector xpath="sch:pattern/sch:rule/sch:report"/>
<xs:field xpath="@id"/>
</xs:unique>
<xs:unique name="ruleId">
<xs:selector xpath="sch:pattern/sch:rule"/>
<xs:field xpath="@id"/>
</xs:unique>
<xs:unique name="patternId">
<xs:selector xpath="sch:pattern"/>
<xs:field xpath="@id"/>
</xs:unique>
<xs:unique name="pId">
<xs:selector xpath=".//sch:p"/>
<xs:field xpath="@id"/>
</xs:unique>
<xs:key name="phaseId">
<xs:selector xpath="sch:phase"/>
<xs:field xpath="@id"/>
</xs:key>
<xs:keyref name="activePattern" refer="patternId">
<xs:selector xpath="sch:phase/sch:active"/>
<xs:field xpath="@pattern"/>
</xs:keyref>
<xs:keyref name="extendsRule" refer="ruleId">
<xs:selector xpath="sch:pattern/sch:rule/sch:extends"/>
<xs:field xpath="@rule"/>
</xs:keyref>
<xs:keyref name="defaultPhase" refer="phaseId">
<xs:selector xpath="."/>
<xs:field xpath="@defaultPhase"/>
</xs:keyref>
<!-- Define the identity constraints -->
</xs:element>
<xs:element name="span">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="class" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="title">
<xs:complexType mixed="true">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="sch:dir"/>
</xs:choice>
</xs:complexType>
</xs:element>
<xs:element name="value-of">
<xs:complexType>
<xs:attribute name="select" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>
sample_schematron.sch
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema
xmlns:sch="http://purl.oclc.org/dsdl/schematron"
queryBinding="xslt2"
xmlns="http://purl.oclc.org/dsdl/schematron"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://purl.oclc.org/dsdl/schematron">
<sch:pattern id="sampleValidation">
<sch:title>PatternTitle</sch:title>
<sch:p>A paragraph</sch:p>
<sch:rule context="CCC">
<assert test="normalize-space(.) and *">Source contains an empty element</assert>
</sch:rule>
</sch:pattern>
</sch:schema>
SchematronUtil.java:
public class SchematronUtil {
public static boolean validateXMLViaXSLTSchematron(@Nonnull final File aSchematronFile,
@Nonnull final File aXMLFile) throws Exception {
final ISchematronResource aResSCH = SchematronResourceSCH.fromFile(aSchematronFile);
if (!aResSCH.isValidSchematron())
throw new IllegalArgumentException("Invalid Schematron!");
return aResSCH.getSchematronValidity(new StreamSource(aXMLFile)).isValid();
}
public static SchematronOutputType validateXMLViaXSLTSchematronFull(@Nonnull final File aSchematronFile,
@Nonnull final File aXMLFile) throws Exception {
final ISchematronResource aResSCH = SchematronResourceSCH.fromFile(aSchematronFile);
if (!aResSCH.isValidSchematron())
throw new IllegalArgumentException("Invalid Schematron!");
return aResSCH.applySchematronValidationToSVRL(new StreamSource(aXMLFile));
}
public static boolean validateXMLViaPureSchematron(@Nonnull final File aSchematronFile,
@Nonnull final File aXMLFile) throws Exception {
final ISchematronResource aResPure = SchematronResourcePure.fromFile(aSchematronFile);
if (!aResPure.isValidSchematron())
throw new IllegalArgumentException("Invalid Schematron!");
return aResPure.getSchematronValidity(new StreamSource(aXMLFile)).isValid();
}
public static boolean validateXMLViaPureSchematron2(@Nonnull final File aSchematronFile,
@Nonnull final File aXMLFile) throws Exception {
// Read the schematron from file
final PSSchema aSchema = new PSReader(new FileSystemResource(aSchematronFile)).readSchema();
if (!aSchema.isValid(new DoNothingPSErrorHandler()))
throw new IllegalArgumentException("Invalid Schematron!");
// Resolve the query binding to use
final IPSQueryBinding aQueryBinding = PSQueryBindingRegistry
.getQueryBindingOfNameOrThrow(aSchema.getQueryBinding());
// Pre-process schema
final PSPreprocessor aPreprocessor = new PSPreprocessor(aQueryBinding);
aPreprocessor.setKeepTitles(true);
final PSSchema aPreprocessedSchema = aPreprocessor.getAsPreprocessedSchema(aSchema);
// Bind the pre-processed schema
final IPSBoundSchema aBoundSchema = aQueryBinding.bind(aPreprocessedSchema, null, null, null, null);
// Read the XML file
final Document aXMLNode = DOMReader.readXMLDOM(aXMLFile);
if (aXMLNode == null)
return false;
// Perform the validation
return aBoundSchema.validatePartially(aXMLNode).isValid();
}
public static boolean readModifyAndWrite(@Nonnull final File aSchematronFile) throws Exception {
final PSSchema aSchema = new PSReader(new FileSystemResource(aSchematronFile)).readSchema();
final PSTitle aTitle = new PSTitle();
aTitle.addText("Created by ph-schematron");
aSchema.setTitle(aTitle);
return MicroWriter.writeToFile(aSchema.getAsMicroElement(), aSchematronFile).isSuccess();
}
}
主要方法:
SchematronOutputType outputType = SchematronUtil.validateXMLViaXSLTSchematronFull(schematronFile, xmlFile);
if (outputType == null){
throw new Exception("SchematronOutputType null");
}
List<SVRLSuccessfulReport> succeededList = SVRLHelper.getAllSuccessfulReports(outputType);
for (SVRLSuccessfulReport succeededReport : succeededList){
System.out.println(succeededReport.getTest());
}
int i = 1;
List<SVRLFailedAssert> failedList = SVRLHelper.getAllFailedAssertions(outputType);
for (SVRLFailedAssert failedAssert : failedList) {
System.out.println(i++ + ". Location:" + failedAssert.getLocation());
System.out.println("Test: " + failedAssert.getTest());
System.out.println("Text: " + failedAssert.getText());
List<DiagnosticReference> diagnisticReferences = failedAssert.getDiagnisticReferences();
for (DiagnosticReference diagnisticRef : diagnisticReferences) {
System.out.println("Diag ref: " + diagnisticRef.getDiagnostic());
System.out.println("Diag text: " + diagnisticRef.getText());
}
}
if (failedList.isEmpty()){
System.out.println("PASS");
}
else{
System.out.println("FAIL");
}
最佳答案
根据一般的ISO Schematron规则进行测试,您的Schematron文档是正确的,除了targetNamespace
属性。在其中拥有默认名称空间xmlns="..."
也没有多大意义,因为所有元素都是前缀的。
Schematron
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
<sch:pattern id="sampleValidation">
<sch:title>PatternTitle</sch:title>
<sch:p>A paragraph</sch:p>
<sch:rule context="CCC">
<assert test="normalize-space(.) and *">Source contains an empty element</assert>
</sch:rule>
</sch:pattern>
</sch:schema>
然后,Schematron很好,但是XML Schema存在很多问题。首先,XML模式文档中的名称空间是不同的。 Schematron文件具有
http://purl.oclc.org/dsdl/schematron
,而在XSD中为http://www.ascc.net/xml/schematron
。这很可能是因为您将旧版本的XML模式用于Schematron的较旧版本。具有正确的名称空间应该可以解决
sch:p
内不允许使用sch:pattern
的问题。在XSD中解决名称空间问题之后,仍然存在以下问题:Attribute 'queryBinding' is not allowed to appear in element 'sch:schema'.
Attribute 'name' must appear on element 'sch:pattern'.
Invalid content was found starting with element '{"http://purl.oclc.org/dsdl/schematron":title}'. One of '{"http://purl.oclc.org/dsdl/schematron":p, "http://purl.oclc.org/dsdl/schematron":rule}' is expected.
所有这些都可以通过修改XML模式来解决,以下是一个有效的版本:
XML模式
<?xml version="1.0" encoding="UTF-8"?>
<!-- schemaVersion of 2001/02/15 -->
<xs:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" xmlns="http://purl.oclc.org/dsdl/schematron" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://purl.oclc.org/dsdl/schematron" version="+//IDN sinica.edu.tw//SGML W3C XML Schema for Schematron 1.5//EN">
<xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd">
<xs:annotation>
<xs:documentation>
Get access to the xml: attribute groups for xml:lang
</xs:documentation>
</xs:annotation>
</xs:import>
<xs:annotation>
<xs:documentation source="http://www.ascc.net/xml/resource/schematron/schematron.html" xml:lang="en"/>
</xs:annotation>
<xs:element name="active">
<xs:complexType mixed="true">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="sch:dir"/>
<xs:element ref="sch:emph"/>
<xs:element ref="sch:span"/>
</xs:choice>
<xs:attribute name="pattern" type="xs:IDREF" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="assert">
<xs:complexType mixed="true">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="sch:name"/>
<xs:element ref="sch:emph"/>
<xs:element ref="sch:dir"/>
<xs:element ref="sch:span"/>
<xs:any namespace="##other" processContents="lax"/>
</xs:choice>
<xs:attribute name="test" type="xs:string" use="required"/>
<xs:attribute name="role" type="xs:NMTOKEN"/>
<xs:attribute name="id" type="xs:string"/>
<xs:attribute name="diagnostics" type="xs:IDREFS"/>
<xs:attribute name="icon" type="xs:anyURI"/>
<xs:attribute name="subject" type="xs:string" default="."/>
<xs:attribute ref="xml:lang"/>
<xs:anyAttribute namespace="##other" processContents="lax"/>
</xs:complexType>
</xs:element>
<xs:element name="diagnostic">
<xs:complexType mixed="true">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="sch:value-of"/>
<xs:element ref="sch:emph"/>
<xs:element ref="sch:dir"/>
<xs:element ref="sch:span"/>
<xs:any namespace="##other" processContents="lax"/>
</xs:choice>
<xs:attribute name="id" type="xs:ID" use="required"/>
<xs:attribute name="icon" type="xs:anyURI"/>
<xs:attribute ref="xml:lang"/>
<xs:anyAttribute namespace="##other" processContents="lax"/>
</xs:complexType>
</xs:element>
<xs:element name="diagnostics">
<xs:complexType>
<xs:sequence>
<xs:element ref="diagnostic" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="dir">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="value">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="ltr"/>
<xs:enumeration value="rtl"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="emph" type="xs:string"/>
<xs:element name="extends">
<xs:complexType>
<xs:attribute name="rule" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="key">
<xs:complexType>
<xs:attribute name="name" type="xs:NMTOKEN" use="required"/>
<xs:attribute name="path" type="xs:string" use="required"/>
<xs:attribute name="icon" type="xs:anyURI"/>
</xs:complexType>
</xs:element>
<xs:element name="name">
<xs:complexType>
<xs:attribute name="path" type="xs:string" default="." />
</xs:complexType>
</xs:element>
<xs:element name="ns">
<xs:complexType>
<xs:attribute name="uri" type="xs:anyURI" use="required"/>
<xs:attribute name="prefix" type="xs:NCName"/>
</xs:complexType>
</xs:element>
<xs:element name="p">
<xs:complexType mixed="true">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="sch:dir"/>
<xs:element ref="sch:emph"/>
<xs:element ref="sch:span"/>
</xs:choice>
<xs:attribute name="id" type="xs:string"/>
<xs:attribute name="class" type="xs:string"/>
<xs:attribute name="icon" type="xs:anyURI"/>
<xs:attribute ref="xml:lang"/>
<xs:anyAttribute namespace="##other" processContents="lax"/>
</xs:complexType>
</xs:element>
<xs:element name="pattern">
<xs:complexType>
<xs:sequence>
<xs:element ref="sch:title" minOccurs="0"/>
<xs:element ref="sch:p" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="sch:rule" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="optional"/>
<xs:attribute name="see" type="xs:anyURI"/>
<xs:attribute name="id" type="xs:string"/>
<xs:attribute name="icon" type="xs:anyURI"/>
</xs:complexType>
</xs:element>
<xs:element name="phase">
<xs:complexType>
<xs:sequence>
<xs:element ref="sch:p" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="sch:active" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="fpi" type="xs:string"/>
<xs:attribute name="icon" type="xs:anyURI"/>
</xs:complexType>
</xs:element>
<xs:element name="report">
<xs:complexType mixed="true">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="sch:name"/>
<xs:element ref="sch:emph"/>
<xs:element ref="sch:dir"/>
<xs:element ref="sch:span"/>
<xs:any namespace="##other" processContents="lax"/>
</xs:choice>
<xs:attribute name="test" type="xs:string" use="required"/>
<xs:attribute name="role" type="xs:NMTOKEN"/>
<xs:attribute name="id" type="xs:string"/>
<xs:attribute name="diagnostics" type="xs:IDREFS"/>
<xs:attribute name="icon" type="xs:anyURI"/>
<xs:attribute name="subject" type="xs:string" default="."/>
<xs:attribute ref="xml:lang"/>
</xs:complexType>
</xs:element>
<xs:element name="rule">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element ref="sch:assert"/>
<xs:element ref="sch:report"/>
<xs:element ref="sch:key"/>
<xs:element ref="sch:extends"/>
</xs:choice>
<xs:attribute name="context" type="xs:string"/>
<xs:attribute name="abstract" type="xs:boolean" default="false"/>
<xs:attribute name="role" type="xs:NMTOKEN"/>
<xs:attribute name="id" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="schema">
<xs:complexType>
<xs:sequence>
<xs:element ref="sch:title" minOccurs="0"/>
<xs:element ref="sch:ns" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="sch:p" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="sch:phase" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="sch:pattern" maxOccurs="unbounded"/>
<xs:element ref="sch:p" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="sch:diagnostics" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="id" type="xs:ID"/>
<xs:attribute name="fpi" type="xs:string"/>
<xs:attribute name="schemaVersion" type="xs:string"/>
<xs:attribute name="defaultPhase" type="xs:string"/>
<xs:attribute name="icon" type="xs:anyURI"/>
<xs:attribute name="ns" type="xs:anyURI"/>
<xs:attribute name="version" type="xs:string" default="1.5"/>
<xs:attribute ref="xml:lang"/>
<xs:attribute name="queryBinding" type="xs:string"/>
<xs:anyAttribute namespace="##other" processContents="lax"/>
</xs:complexType>
<xs:unique name="assertId">
<xs:selector xpath="sch:pattern/sch:rule/sch:assert"/>
<xs:field xpath="@id"/>
</xs:unique>
<xs:unique name="reportId">
<xs:selector xpath="sch:pattern/sch:rule/sch:report"/>
<xs:field xpath="@id"/>
</xs:unique>
<xs:unique name="ruleId">
<xs:selector xpath="sch:pattern/sch:rule"/>
<xs:field xpath="@id"/>
</xs:unique>
<xs:unique name="patternId">
<xs:selector xpath="sch:pattern"/>
<xs:field xpath="@id"/>
</xs:unique>
<xs:unique name="pId">
<xs:selector xpath=".//sch:p"/>
<xs:field xpath="@id"/>
</xs:unique>
<xs:key name="phaseId">
<xs:selector xpath="sch:phase"/>
<xs:field xpath="@id"/>
</xs:key>
<xs:keyref name="activePattern" refer="patternId">
<xs:selector xpath="sch:phase/sch:active"/>
<xs:field xpath="@pattern"/>
</xs:keyref>
<xs:keyref name="extendsRule" refer="ruleId">
<xs:selector xpath="sch:pattern/sch:rule/sch:extends"/>
<xs:field xpath="@rule"/>
</xs:keyref>
<xs:keyref name="defaultPhase" refer="phaseId">
<xs:selector xpath="."/>
<xs:field xpath="@defaultPhase"/>
</xs:keyref>
<!-- Define the identity constraints -->
</xs:element>
<xs:element name="span">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="class" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="title">
<xs:complexType mixed="true">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="sch:dir"/>
</xs:choice>
</xs:complexType>
</xs:element>
<xs:element name="value-of">
<xs:complexType>
<xs:attribute name="select" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>
但是请记住:此XSD文档已过时,并且没有反映对Schematron规范的最新更改。很可能还会有其他问题。
或者,您可以使用最近的ISO Schematron and SQF schemas from Schematron Quickfix。确保下载所有架构组件,然后针对iso-schematron.xsd进行验证。