Java の XSD 検証ライブラリによって提供されるエラー メッセージのテキストに問題があります。私の場合、Apache Xerces が内部で使用されているようです。私は、Java からのエラーが非常に誤解を招くと思います。
Javaから取得しているエラーは次のとおりです。
cvc-complex-type.2.4.b: 要素 'ルート' の内容が完全ではありません。「{subnode1, subnode2}」のいずれかが必要です。
しかし、別の XML エディターである XMLSpy 2004 は、次のように述べています。
「subnode1」の後の「」には必須要素が必要です: subnode2、subnode3
サブノード 1 が欠落していないため、ここでは 2 番目のエラーの方がはるかに正確であるように見えます。ただし、subnode2 と subnode3 は両方ともそうです。
ここに私のXMLファイルがあります:
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="schema.xsd">
<subnode0/>
<subnode1/>
</root>
これは私が使用したXSDです:
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root" type="NodeType">
</xs:element>
<xs:complexType name="NodeType">
<xs:sequence>
<xs:element name="subnode0" type="subnode0_Type" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="subnode1" type="subnode1_Type" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="subnode2" type="subnode2_Type" minOccurs="1" maxOccurs="1"/>
<xs:element name="subnode3" type="subnode3_Type" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="subnode0_Type">
</xs:complexType>
<xs:complexType name="subnode1_Type">
</xs:complexType>
<xs:complexType name="subnode2_Type">
</xs:complexType>
<xs:complexType name="subnode3_Type">
</xs:complexType>
</xs:schema>
そして、これが検証 API を呼び出す Java コードです。
public class XsdErrorTextMain {
private final static DocumentBuilder documentBuilder;
private final static SchemaFactory schemaFactory;
static {
try {
final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
documentBuilder = documentBuilderFactory.newDocumentBuilder();
} catch (final ParserConfigurationException e) {
throw new RuntimeException(e);
}
schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
}
public static void main(final String[] args) throws Exception {
final Document xmlDocument = readXmlFile("file.xml");
final Schema schema = readXsdFile("schema.xsd");
runXmlValidation(xmlDocument, schema);
}
private static void runXmlValidation(final Document xmlDocument, final Schema schema) throws SAXException {
try {
final Validator validator = schema.newValidator();
validator.setErrorHandler(new ErrorHandler() {
@Override
public void warning(final SAXParseException exception) {
return;
}
@Override
public void error(final SAXParseException exception) throws SAXException {
displayValidationError(exception);
}
@Override
public void fatalError(final SAXParseException exception) throws SAXException {
throw new RuntimeException("A fatal error was raised during the validation", exception);
}
});
validator.validate(new DOMSource(xmlDocument));
} catch (final IOException e) {
throw new RuntimeException(e);
}
}
private static void displayValidationError(final SAXParseException validationError) {
System.out.println("Line: " + validationError.getLineNumber());
System.out.println("Column: " + validationError.getColumnNumber());
System.out.println("Message: " + validationError.getMessage());
}
private static Document readXmlFile(final String path) throws IOException, SAXException {
try (final InputStream xmlInputStream = ClassLoader.getSystemResource(path).openStream()) {
return documentBuilder.parse(xmlInputStream);
}
}
private static Schema readXsdFile(final String path) throws IOException, SAXException {
final Document xsdDocument = readXmlFile(path);
return schemaFactory.newSchema(new DOMSource(xsdDocument));
}
}
ここで何か不足していますか?エラーメッセージをより正確に計算できる他の実装を知っていますか? どんな入力でも大歓迎です。ありがとう!