我需要针对其XSD架构验证XML,我已经定义了几个“key / keyref”约束来确定所有现有的违规。但是,在首次确定此类keyref违规后,JAXP XML验证程序将跳过其他人,即使它们存在。
包含两个keyref违规的xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<relations>
<keys>
<key id="1"/>
<key id="2"/>
</keys>
<refs>
<ref to="2"/><!-- This is valid because key with id 2 present -->
<!-- This two xml elements have 'keyref' constraint violation because there aren't coresponding keys with id 3,4-->
<ref to="3"/>
<ref to="4"/>
</refs>
</relations>
xsd架构:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="relations">
<xs:complexType>
<xs:all>
<xs:element ref="keys"/>
<xs:element ref="refs"/>
</xs:all>
</xs:complexType>
<!-- Constraints Section -->
<xs:key name="key-pk">
<xs:selector xpath="keys/key" />
<xs:field xpath="@id" />
</xs:key>
<xs:keyref name="ref-key-pk" refer="key-pk">
<xs:selector xpath="refs/ref" />
<xs:field xpath="@to" />
</xs:keyref>
</xs:element>
<xs:element name="keys">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="key"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="refs">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="ref"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="key">
<xs:complexType>
<xs:attribute name="id" type="xs:long"/>
</xs:complexType>
</xs:element>
<xs:element name="ref">
<xs:complexType>
<xs:attribute name="to" type="xs:long"/>
</xs:complexType>
</xs:element>
</xs:schema>
执行此类验证的Java代码:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
public class LayoutXmlValidator {
private static final String XSD = "/examp.xsd";
private File xml = null;
private Validator validator;
private Schema schema;
private ErrorHandler errorHandler;
private static class ErrorReporter implements ErrorHandler{
private int errorCounter;
@Override
public void warning(SAXParseException exception) throws SAXException {
final String tag = "warning";
out(tag, exception);
}
@Override
public void fatalError(SAXParseException exception) throws SAXException {
final String tag = "fatal";
out(tag, exception);
}
@Override
public void error(SAXParseException exception) throws SAXException {
final String tag = "error";
out(tag, exception);
}
private void out(String tag, SAXParseException e){
errorCounter++;
String msg = e.getMessage()+"\n";
msg +=" "+tag+" at "+e.getSystemId()+":"+e.getLineNumber();
System.out.println(errorCounter+")"+msg);
}
}
public LayoutXmlValidator() {
try{
SchemaFactory factory =
SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
InputStream xsd = getClass().getResourceAsStream(XSD);
schema = factory.newSchema(new StreamSource(xsd));
validator = schema.newValidator();
errorHandler = new ErrorReporter();
}catch(Throwable e){
e.printStackTrace();
}
}
public void setErrorHandler(ErrorHandler errorHandler) {
this.errorHandler = errorHandler;
}
private void validate(){
try{
validator.setErrorHandler(errorHandler);
Source source = new StreamSource(xml);
try {
validator.validate(source);
}
catch (SAXException ex) {
System.out.println(xml + " is not valid because ");
System.out.println(ex.getMessage());
}
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] args) {
LayoutXmlValidator v = new LayoutXmlValidator();
v.xml = new File("examp.xml");
v.validate();
}
}
我预计<ref to="3"/>
和<ref to="4"/>
会出现2个错误,但验证者只能确定<ref to="3"/>
的第一个错误。当我将<ref to="3"/>
更改为<ref to="2"/>
时,将确定有问题的节点。如何在每个xml处理中获得所有此类引用错误?