1. 개요
이 사용방법(예제)에서는 XSD 파일에 대해 XML 파일의 유효성을 검사하는 방법을 보여줍니다.
2. XML 및 두 개의 XSD 파일 정의
우편 번호와 도시로 구성된 이름과 주소를 포함하는 다음 XML 파일 baeldung.xml 을 고려해 보겠습니다.
<?xml version="1.0" encoding="UTF-8" ?>
<individual>
<name>Baeldung</name>
<address>
<zip>00001</zip>
<city>New York</city>
</address>
</individual>
baeldung.xml 의 내용은 정확히 person.xsd 파일 의 설명과 일치 합니다.
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="individual">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string" />
<xs:element name="address">
<xs:complexType>
<xs:sequence>
<xs:element name="zip" type="xs:positiveInteger" />
<xs:element name="city" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
그러나 다음 XSD 파일 full-person.xsd 와 관련하여 XML이 유효하지 않습니다 .
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="individual">
<xs:complexType>
<xs:sequence>
<xs:element name="name">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="5" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="address">
<xs:complexType>
<xs:sequence>
<xs:element name="zip" type="xs:positiveInteger" />
<xs:element name="city" type="xs:string" />
<xs:element name="street" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
두 가지 문제가 있습니다.
- 이름 속성은 최대 5자로 제한됩니다.
- 주소에는 거리 속성이 필요합니다.
Java를 사용하여 이 정보를 얻는 방법을 살펴보겠습니다.
3. XSD 파일에 대해 XML 파일 유효성 검사
javax.xml.validation 패키지 는 XML 문서의 유효성 검사를 위한 API를 정의합니다.
먼저 XML 스키마 1.0 사양을 따르는 파일을 읽을 수 있는 SchemaFactory 를 준비합니다. 그런 다음 이 SchemaFactory 를 사용하여 XSD 파일에 해당하는 스키마 를 생성 합니다. 스키마 는 제약 조건 집합을 나타냅니다.
마지막으로 Schema 에서 Validator 를 검색합니다 . 유효성 검사기 는 스키마 에 대해 XML 문서를 확인하는 프로세서입니다 .
private Validator initValidator(String xsdPath) throws SAXException {
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Source schemaFile = new StreamSource(getFile(xsdPath));
Schema schema = factory.newSchema(schemaFile);
return schema.newValidator();
}
이 코드에서 getFile 메서드를 사용 하면 XSD 를 File 로 읽을 수 있습니다 . 이 예제에서는 파일을 리소스 디렉터리 아래에 두므로 이 메서드는 다음과 같이 읽습니다.
private File getFile(String location) {
return new File(getClass().getClassLoader().getResource(location).getFile());
}
Schema 를 만들 때 XSD 파일이 유효하지 않으면 SAXException 이 발생할 수 있습니다.
이제 유효성 검사기 를 사용하여 XML 파일이 XSD 설명과 일치하는지 확인할 수 있습니다. 유효성 검증 메소드를 사용하려면 파일 을 StreamSource 로 변환해야 합니다 .
public boolean isValid(String xsdPath, String xmlPath) throws IOException, SAXException {
Validator validator = initValidator(xsdPath);
try {
validator.validate(new StreamSource(getFile(xmlPath)));
return true;
} catch (SAXException e) {
return false;
}
}
유효성 검사 메서드 는 구문 분석 중에 오류가 있는 경우 SAXException 을 throw합니다 . 이는 XML 파일이 주어진 XSD 사양에서 유효하지 않음을 나타냅니다.
유효성 검사 메서드 는 파일을 읽는 동안 근본적인 문제가 있는 경우 IOException 을 throw할 수도 있습니다 .
이제 XmlValidator 클래스 에서 코드를 마무리하고 baeldung.xml이 person.xsd 설명 과 일치 하지만 full-person.xsd가 아닌지 확인할 수 있습니다 .
@Test
public void givenValidXML_WhenIsValid_ThenTrue() throws IOException, SAXException {
assertTrue(new XmlValidator().isValid("person.xsd", "baeldung.xml"));
}
@Test
public void givenInvalidXML_WhenIsValid_ThenFalse() throws IOException, SAXException {
assertFalse(new XmlValidator().isValid("full-person.xsd", "baeldung.xml"));
}
4. 모든 유효성 검사 오류 나열
유효성 검사 메서드 의 기본 동작은 구문 분석에서 SAXException 이 발생하면 종료하는 것 입니다.
이제 모든 유효성 검사 오류를 수집하려고 하므로 이 동작을 변경해야 합니다. 이를 위해 자체 ErrorHandler 를 정의해야 합니다 .
public class XmlErrorHandler implements ErrorHandler {
private List<SAXParseException> exceptions;
public XmlErrorHandler() {
this.exceptions = new ArrayList<>();
}
public List<SAXParseException> getExceptions() {
return exceptions;
}
@Override
public void warning(SAXParseException exception) {
exceptions.add(exception);
}
@Override
public void error(SAXParseException exception) {
exceptions.add(exception);
}
@Override
public void fatalError(SAXParseException exception) {
exceptions.add(exception);
}
}
이제 Validator 에게 이 특정 ErrorHandler 를 사용하도록 지시할 수 있습니다 .
public List<SAXParseException> listParsingExceptions(String xsdPath, String xmlPath) throws IOException, SAXException {
XmlErrorHandler xsdErrorHandler = new XmlErrorHandler();
Validator validator = initValidator(xsdPath);
validator.setErrorHandler(xsdErrorHandler);
try {
validator.validate(new StreamSource(getFile(xmlPath)));
} catch (SAXParseException e)
{
// ...
}
xsdErrorHandler.getExceptions().forEach(e -> LOGGER.info(e.getMessage()));
return xsdErrorHandler.getExceptions();
}
baeldung.xml 은 person.xsd 의 요구 사항을 충족 하므로 이 경우 오류가 나열되지 않습니다. 그러나 full-person.xsd 로 호출 하면 다음 오류 메시지가 출력됩니다.
XmlValidator - cvc-maxLength-valid: Value 'Baeldung' with length = '8' is not facet-valid with respect to maxLength '5' for type '#AnonType_nameindividual'.
XmlValidator - cvc-type.3.1.3: The value 'Baeldung' of element 'name' is not valid.
XmlValidator - cvc-complex-type.2.4.b: The content of element 'address' is not complete. One of '{street}' is expected.
섹션 1에서 언급한 모든 오류는 프로그램에서 발견되었습니다.
5. 결론
이 문서에서는 XSD 파일에 대해 XML 파일의 유효성을 검사하는 방법과 모든 유효성 검사 오류를 나열할 수도 있음을 살펴보았습니다.
항상 그렇듯이 코드는 GitHub에서 사용할 수 있습니다 .