我正在为我的java项目构建一个xml验证器 xerces-2_11_0-xml-schema-1.1-beta库,以支持XSD 1.1特定功能,如断言。
考虑此架构
<?xml version="1.1" encoding="UTF-8"?>
<schema targetNamespace="http://www.example.org/Example" elementFormDefault="qualified" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.example.org/Example">
<complexType name="NodeType">
<sequence>
<element name="Node" type="tns:NodeType"
maxOccurs="unbounded" minOccurs="0">
</element>
</sequence>
<attribute name="partnumber">
<simpleType>
<restriction base="string">
<pattern value="[A-Z0-9_\-]+"></pattern>
</restriction>
</simpleType>
</attribute>
<assert test="starts-with(@partnumber,../@partnumber)"/>
</complexType>
<element name="Node" type="tns:NodeType"></element>
</schema>
我开始使用&#34; javax.xml.validation.Validator&#34;类
...
StreamSource xmlSource = new StreamSource(new File("example.xml"));
SchemaFactory sf = SchemaFactory.newInstance("http://www.w3.org/XML/XMLSchema/v1.1");
Schema s = sf.newSchema(new File("example.xsd"));
Validator v = s.newValidator();
v.setErrorHandler(new MyErrorHandler())
v.validate(xmlSource)
...
private static class MyErrorHandler extends DefaultHandler {
...
public void error(SAXParseException e) throws SAXException {
System.out.println("Error: ");
System.out.println(" Public ID: "+e.getPublicId());
System.out.println(" System ID: "+e.getSystemId());
System.out.println(" Line number: "+e.getLineNumber());
System.out.println(" Column number: "+e.getColumnNumber());
System.out.println(" Message: "+e.getMessage());;
}
...
}
此解决方案有效:example.xsd中的断言测试得到正确处理,xml文件的验证运行顺利(正确评估断言测试)
然后我用SAXParser替换了Validator(原因:可以更好地控制sax解析阶段)
...
SchemaFactory sf = SchemaFactory.newInstance("http://www.w3.org/XML/XMLSchema/v1.1");
Schema s = sf.newSchema(new File("example.xsd"));
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setSchema(s);
spf.setNamespaceAware(true);
spf.setValidating(true);
spf.setFeature("http://apache.org/xml/features/validation/schema", true);
SAXParser parser = spf.newSAXParser();
XMLReader r = parser.getXMLReader();
r.setErrorHandler(new MyErrorHandler())
r.parse("example.xml");
...
在第二种情况下,解析阶段在xsd&#34;断言&#34;上遇到错误。子句,带有这条消息:
s4s-elt-invalid-content.1: The content of 'NodeType' is invalid. Element 'assert' is invalid, misplaced, or occurs too often.
如果我删除example.xsd中的assert子句(从而使其符合1.0),验证运行正确,所以我认为SAXParser仍在使用1.0规范。
我是否遗漏了配置SAXParserFactory或SAXParser本身以便遵守1.1架构规则的内容?
答案 0 :(得分:1)
我认为您的项目中缺少XPATH 2.0依赖性。请检查一下!
XML Schema 1.1'断言'和'类型替代'需要XPath 用于评估的2.0处理器。对于XSD 1.1断言,需要完整的XPath 2.0支持。对于XSD 1.1类型替代,XML模式引擎 可以提供完整的XPath 2.0支持,也可以实现更小的支持 XPath 2.0子集,由XSD 1.1语言定义。