답변:
Java 런타임 라이브러리는 유효성 검사를 지원합니다. 마지막으로 이것을 확인했을 때 덮개 아래의 Apache Xerces 파서였습니다. 아마도 javax.xml.validation.Validator를 사용해야합니다 .
import javax.xml.XMLConstants;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.*;
import java.net.URL;
import org.xml.sax.SAXException;
//import java.io.File; // if you use File
import java.io.IOException;
...
URL schemaFile = new URL("http://host:port/filename.xsd");
// webapp example xsd:
// URL schemaFile = new URL("http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd");
// local file example:
// File schemaFile = new File("/location/to/localfile.xsd"); // etc.
Source xmlFile = new StreamSource(new File("web.xml"));
SchemaFactory schemaFactory = SchemaFactory
.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
try {
Schema schema = schemaFactory.newSchema(schemaFile);
Validator validator = schema.newValidator();
validator.validate(xmlFile);
System.out.println(xmlFile.getSystemId() + " is valid");
} catch (SAXException e) {
System.out.println(xmlFile.getSystemId() + " is NOT valid reason:" + e);
} catch (IOException e) {}
스키마 팩토리 상수는 http://www.w3.org/2001/XMLSchema
XSD를 정의 하는 문자열 입니다. 위의 코드는 URL에 대해 WAR 배치 디스크립터를 유효성 검증 http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd
하지만 로컬 파일에 대해서도 쉽게 유효성을 검증 할 수 있습니다.
문서 오브젝트 모델을 작성하는 것이 아니라면 DOMParser를 사용하여 문서를 유효성 검증하지 않아야합니다. 문서를 구문 분석 할 때 DOM 객체를 생성하기 시작합니다. 사용하지 않을 경우 낭비입니다.
Xerces2 사용하는 방법은 다음과 같습니다 . 이에 대한 튜토리얼은 여기 (요청 가입)입니다.
원래 귀속 : 여기 에서 뻔뻔스럽게 복사 :
import org.apache.xerces.parsers.DOMParser;
import java.io.File;
import org.w3c.dom.Document;
public class SchemaTest {
public static void main (String args[]) {
File docFile = new File("memory.xml");
try {
DOMParser parser = new DOMParser();
parser.setFeature("http://xml.org/sax/features/validation", true);
parser.setProperty(
"http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation",
"memory.xsd");
ErrorChecker errors = new ErrorChecker();
parser.setErrorHandler(errors);
parser.parse("memory.xml");
} catch (Exception e) {
System.out.print("Problem parsing the file.");
}
}
}
ant를 사용하여 프로젝트를 빌드하므로 schemavalidate 태스크를 사용하여 구성 파일을 확인할 수 있습니다.
<schemavalidate>
<fileset dir="${configdir}" includes="**/*.xml" />
</schemavalidate>
이제 나쁜 구성 파일이 빌드에 실패합니다!
이것은 대중적인 질문이므로 java는 .xml 파일 자체가 헤더에 XSD를 지정 xsi:SchemaLocation
하거나 xsi:noNamespaceSchemaLocation
(또는 특정 네임 스페이스의 경우 xsi) ex :
<document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.example.com/document.xsd">
...
또는 SchemaLocation (항상 xsd 맵핑에 대한 네임 스페이스 목록)
<document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:SchemaLocation="http://www.example.com/my_namespace http://www.example.com/document.xsd">
...
다른 답변도 여기에서 작동합니다. .xsd 파일은 .xml 파일에 선언 된 네임 스페이스에 "맵핑"되기 때문에 네임 스페이스를 선언하고 .xml 파일의 네임 스페이스와 일치하면 좋습니다. 그러나 때로는 맞춤형 리졸버 를 가질 수있는 것이 편리합니다 ...
javadocs에서 : "URL, 파일 또는 소스를 지정하지 않고 스키마를 작성하는 경우 Java 언어는 유효성을 검사 할 문서를 찾아서 사용해야하는 스키마를 찾습니다. 예를 들면 다음과 같습니다."
SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
Schema schema = factory.newSchema();
이것은 여러 네임 스페이스 등에서 작동합니다.이 방법의 문제점 xmlsns:xsi
은 네트워크 위치 일 가능성이 있기 때문에 기본적으로 항상 최적의 것은 아니지만 모든 유효성 검사를 수행하여 네트워크를 종료합니다.
다음은 참조하는 모든 XSD에 대해 XML 파일의 유효성을 검사하는 예입니다 (네트워크에서 파일을 가져와야하는 경우에도).
public static void verifyValidatesInternalXsd(String filename) throws Exception {
InputStream xmlStream = new new FileInputStream(filename);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(true);
factory.setNamespaceAware(true);
factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
"http://www.w3.org/2001/XMLSchema");
DocumentBuilder builder = factory.newDocumentBuilder();
builder.setErrorHandler(new RaiseOnErrorHandler());
builder.parse(new InputSource(xmlStream));
xmlStream.close();
}
public static class RaiseOnErrorHandler implements ErrorHandler {
public void warning(SAXParseException e) throws SAXException {
throw new RuntimeException(e);
}
public void error(SAXParseException e) throws SAXException {
throw new RuntimeException(e);
}
public void fatalError(SAXParseException e) throws SAXException {
throw new RuntimeException(e);
}
}
xml 파일이 url을 참조하더라도 xsd를 수동으로 지정하거나 (여기서 다른 답변 참조) "XML catalog" 스타일 resolver 를 사용하여 네트워크에서 참조 된 XSD를 가져 오는 것을 피할 수 있습니다 . Spring은 분명히 유효성 검사를 위해 로컬 파일을 제공하기 위해 URL 요청을 가로 챌 수 있습니다 . 또는 setResourceResolver 를 통해 자신을 설정할 수 있습니다 .
Source xmlFile = new StreamSource(xmlFileLocation);
SchemaFactory schemaFactory = SchemaFactory
.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema();
Validator validator = schema.newValidator();
validator.setResourceResolver(new LSResourceResolver() {
@Override
public LSInput resolveResource(String type, String namespaceURI,
String publicId, String systemId, String baseURI) {
InputSource is = new InputSource(
getClass().getResourceAsStream(
"some_local_file_in_the_jar.xsd"));
// or lookup by URI, etc...
return new Input(is); // for class Input see
// https://stackoverflow.com/a/2342859/32453
}
});
validator.validate(xmlFile);
다른 튜토리얼 은 여기 를 참조하십시오 .
기본값은 DOM 파싱을 사용하는 것으로 생각되며 SAX 파서와 비슷한 것을 수행 할 수 있습니다. saxReader.setEntityResolver(your_resolver_here);
setResourceResolver
그 밖의 새로운 질문이있을 수도 있습니다.
Java 7을 사용하면 패키지 설명에 제공된 설명서를 따를 수 있습니다 .
// create a SchemaFactory capable of understanding WXS schemas SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); // load a WXS schema, represented by a Schema instance Source schemaFile = new StreamSource(new File("mySchema.xsd")); Schema schema = factory.newSchema(schemaFile); // create a Validator instance, which can be used to validate an instance document Validator validator = schema.newValidator(); // validate the DOM tree try { validator.validate(new StreamSource(new File("instance.xml")); } catch (SAXException e) { // instance document is invalid! }
ErrorHandler
유효성 검사를 수행해야하는 경우 이를 제공 해야합니다.
Linux-Machine을 사용하는 경우 무료 명령 줄 도구 SAXCount를 사용할 수 있습니다. 나는 이것이 매우 유용하다는 것을 알았다.
SAXCount -f -s -n my.xml
dtd 및 xsd에 대해 유효성을 검사합니다. 50MB 파일의 경우 5 초.
데비안 스퀴즈에서는 "libxerces-c-samples"패키지에 있습니다.
dtd와 xsd의 정의는 xml에 있어야합니다! 별도로 구성 할 수 없습니다.
xmllint --schema phone.xsd phone.xml
(13ren의 답변에서)
하나 더 답변 : 생성중인 파일의 유효성을 검사해야한다고 말했기 때문에 (쓰기) 먼저 쓰고 나서 유효성 검사를 위해 다시 읽는 대신 내용을 확인하는 것이 좋습니다. SAX 기반 라이터를 사용하는 경우 Xml 유효성 검사를위한 JDK API를 사용하여이 작업을 수행 할 수 있습니다. 그렇다면 'Validator.validate (source, result)'를 호출하여 유효성 검사기에서 링크하면됩니다. 출력이 필요한 곳.
또는 컨텐츠 (또는 stax를 사용하거나 사용할 수있는 라이브러리)를 작성하기 위해 Stax를 사용하는 경우 Woodstox 는 XMLStreamWriter를 사용할 때 유효성 검사를 직접 지원할 수도 있습니다. 수행 방법을 보여주는 블로그 항목 은 다음과 같습니다 .
JAXB를 사용하면 아래 코드를 사용할 수 있습니다.
@Test
public void testCheckXmlIsValidAgainstSchema() {
logger.info("Validating an XML file against the latest schema...");
MyValidationEventCollector vec = new MyValidationEventCollector();
validateXmlAgainstSchema(vec, inputXmlFileName, inputXmlSchemaName, inputXmlRootClass);
assertThat(vec.getValidationErrors().isEmpty(), is(expectedValidationResult));
}
private void validateXmlAgainstSchema(final MyValidationEventCollector vec, final String xmlFileName, final String xsdSchemaName, final Class<?> rootClass) {
try (InputStream xmlFileIs = Thread.currentThread().getContextClassLoader().getResourceAsStream(xmlFileName);) {
final JAXBContext jContext = JAXBContext.newInstance(rootClass);
// Unmarshal the data from InputStream
final Unmarshaller unmarshaller = jContext.createUnmarshaller();
final SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
final InputStream schemaAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(xsdSchemaName);
unmarshaller.setSchema(sf.newSchema(new StreamSource(schemaAsStream)));
unmarshaller.setEventHandler(vec);
unmarshaller.unmarshal(new StreamSource(xmlFileIs), rootClass).getValue(); // The Document class is the root object in the XML file you want to validate
for (String validationError : vec.getValidationErrors()) {
logger.trace(validationError);
}
} catch (final Exception e) {
logger.error("The validation of the XML file " + xmlFileName + " failed: ", e);
}
}
class MyValidationEventCollector implements ValidationEventHandler {
private final List<String> validationErrors;
public MyValidationEventCollector() {
validationErrors = new ArrayList<>();
}
public List<String> getValidationErrors() {
return Collections.unmodifiableList(validationErrors);
}
@Override
public boolean handleEvent(final ValidationEvent event) {
String pattern = "line {0}, column {1}, error message {2}";
String errorMessage = MessageFormat.format(pattern, event.getLocator().getLineNumber(), event.getLocator().getColumnNumber(),
event.getMessage());
if (event.getSeverity() == ValidationEvent.FATAL_ERROR) {
validationErrors.add(errorMessage);
}
return true; // you collect the validation errors in a List and handle them later
}
}
온라인 스키마에 대한 유효성 검사
Source xmlFile = new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream("your.xml"));
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = factory.newSchema(Thread.currentThread().getContextClassLoader().getResource("your.xsd"));
Validator validator = schema.newValidator();
validator.validate(xmlFile);
로컬 스키마에 대해 유효성 검증
Woodstox를 사용 하여 스키마에 대해 유효성을 검증하고 XML을 구문 분석하도록 StAX 구문 분석기를 구성하십시오.
예외가 발견되면 XML이 유효하지 않으면 유효하지 않습니다.
// create the XSD schema from your schema file
XMLValidationSchemaFactory schemaFactory = XMLValidationSchemaFactory.newInstance(XMLValidationSchema.SCHEMA_ID_W3C_SCHEMA);
XMLValidationSchema validationSchema = schemaFactory.createSchema(schemaInputStream);
// create the XML reader for your XML file
WstxInputFactory inputFactory = new WstxInputFactory();
XMLStreamReader2 xmlReader = (XMLStreamReader2) inputFactory.createXMLStreamReader(xmlInputStream);
try {
// configure the reader to validate against the schema
xmlReader.validateAgainst(validationSchema);
// parse the XML
while (xmlReader.hasNext()) {
xmlReader.next();
}
// no exceptions, the XML is valid
} catch (XMLStreamException e) {
// exceptions, the XML is not valid
} finally {
xmlReader.close();
}
참고 : 여러 파일의 유효성을 검사해야하는 경우 XMLInputFactory
및 파일을 재사용하여 XMLValidationSchema
성능을 최대화해야합니다.
한 번만 XSD에 대해 XML의 유효성을 검사해야했기 때문에 XMLFox를 사용해 보았습니다. 나는 그것이 매우 혼란스럽고 이상하다는 것을 알았습니다. 도움말 지침이 인터페이스와 일치하지 않는 것 같습니다.
사용하기 쉽고 훨씬 친숙한 LiquidXML Studio 2008 (v6)을 사용하게되었습니다 (UI는 자주 사용하는 Visual Basic 2008 Express와 매우 유사합니다). 단점 : 유효성 검사 기능이 무료 버전이 아니므로 30 일 평가판을 사용해야했습니다.