XSD 파일에 대해 XML 파일을 검증하는 방법
나한테 준 xsd 파일을 따라야 하는 xml 파일을 만들고 있어.그들이 일치하는지 어떻게 검증해야 할까?
Java 런타임 라이브러리는 검증을 지원한다.내가 마지막으로 확인한 건 이불 밑에 있는 아파치 엑서스 파서였어자바x.xml.validation을 사용해야 할 겁니다.검증자.
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
를 한다.SD를 정의하고 있어위의 코드는 URL에 대해 WAR 배포 설명자의 유효성을 검증한다.http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd
로컬 파일에 대해 쉽게 검증할 수 있을 겁니다
DOMParser를 사용하여 문서를 검증하지 마십시오(어쨌든 문서 객체 모델을 만드는 것이 목적이 아니라면).이렇게 하면 문서를 구문 분석하면서 DOM 객체를 만들기 시작할 것이다. 사용하지 않을 경우 낭비되는 것이다.
Xerces2를 사용하여 수행하는 방법은 다음과 같다.여기에 대한 자습서(req. 등록)
원래 속성: 여기서 노골적으로 복사:
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.");
}
}
}
우리는 개미를 사용하여 프로젝트를 만들고, schemavalidate 작업을 사용하여 구성 파일을 확인할 수 있다.
<schemavalidate>
<fileset dir="${configdir}" includes="**/*.xml" />
</schemavalidate>
이제 장난꾸러기 구성 파일이 우리의 빌드에 실패할 것이다!
http://ant.apache.org/manual/Tasks/schemavalidate.html
이것은 일반적인 질문이기 때문에, 예를 들어, .xml 파일 자체가 헤더에 XSD를 지정하는 경우, Java는 다음을 사용하여 "참조" 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 파일에 선언된 네임스페이스에 "map"되기 때문에, 네임스페이스를 선언하기 때문에, 그리고 .xml 파일의 네임스페이스와 일치한다면, 당신은 괜찮다.하지만 때로는 맞춤식 해결사를 가질 수 있어 편리할 때도 있다...
자바도크로부터: " URL, 파일 또는 소스를 지정하지 않고 스키마를 만들면, 자바 언어는 사용할 스키마를 찾기 위해 유효성 검사 중인 문서에서 보이는 스키마를 만든다.예:"
SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
Schema schema = factory.newSchema();
그리고 이것은 다중 네임스페이스 등에 효과가 있다.이 접근방식의 문제는 다음과 같다.xmlsns:xsi
아마도 네트워크 위치일 것이다. 따라서 기본적으로 네트워크는 나가서 모든 유효성 검사를 통해 네트워크를 타격할 것이다. 항상 최적인 것은 아니다.
XSD가 참조하는 모든 XSD에 대해 XML 파일을 검증하는 예(네트워크에서 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 카탈로그" 스타일 확인기를 사용하여 참조된 XSD를 네트워크에서 끌어오는 것을 피할 수 있다.Spring은 또한 검증을 위해 로컬 파일을 제공하기 위한 URL 요청을 가로챌 수 있다.또는 setResourceResolver(ex:
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 파싱을 사용하는 것으로 알고 있으며, 검증 중인 색스파서에서도 비슷한 작업을 할 수 있다. saxReader.setEntityResolver(your_resolver_here);
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! }
Linux-Machine을 사용하는 경우, 무료 명령줄 도구인 SOCunt를 사용할 수 있다.나는 이것이 매우 유용하다는 것을 알았다.
SAXCount -f -s -n my.xml
그것은 dtd와 xsd에 대해 유효하다.50MB 파일의 경우 5초.
데비안 압착에서 그것은 "libxerces-c-samples" 패키지에 있다.
dtd와 xsd의 정의는 xml에 있어야 한다!별도로 구성할 수는 없다.
한 가지 더 대답: 생성하는 파일의 유효성을 검사해야 한다고 했으므로(쓰기) 처음 쓰는 대신 유효성 검사를 위해 다시 읽는 동안 내용을 검증하는 것이 좋을 수 있다.만약 당신이 JDK API for XML validation을 사용한다면, 만약 그렇다면, 그냥 'Validator.validate(source, result)'를 호출하여 검증자를 연결하면 된다. 여기서 소스는 당신의 작성자로부터 나오고 결과는 출력이 필요한 것이다.
또는 Stax를 컨텐츠 작성(또는 Stax를 사용하거나 사용할 수 있는 라이브러리)에 사용할 경우, XMLStreamWriter를 사용할 때 Woodstox가 유효성 검사를 직접 지원할 수도 있다.이 작업을 수행하는 방법을 보여 주는 블로그 항목:
XML 파일을 프로그래밍 방식으로 생성하는 경우 XMLBeans 라이브러리를 살펴보십시오.명령줄 도구를 사용하여 XMLBeans는 XSD를 기반으로 자바 객체 집합을 자동으로 생성하고 패키징한다.그런 다음 이러한 객체를 사용하여 이 스키마에 기반한 XML 문서를 작성할 수 있다.
스키마 유효성 검사에 대한 지원이 내장되어 있으며, 자바 객체를 XML 문서 및 그 반대로 변환할 수 있다.
캐스터와 JAXB는 XMLBeans와 유사한 목적을 제공하는 다른 자바 도서관이다.
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
}
}
Woodstox를 사용하여 스키마에 대해 검증할 StAX 파서를 구성하고 XML을 구문 분석하십시오.
예외가 발견되면 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
성능을 극대화하기 위해
도구를 찾으십니까, 아니면 도서관을 찾으십니까?
라이브러리에 관한 한, 실질적인 표준은 C++와 자바 버전을 모두 갖춘 Xerces2이다.
하지만 미리 경고해두어라. 그것은 무거운 해결책이다.그러나 한편, XSD 파일에 대해 XML을 검증하는 것은 다소 무거운 문제다.
이 일을 할 수 있는 도구에 대해서는 XMLFox가 괜찮은 프리웨어 솔루션인 것 같지만 개인적으로 사용하지 않은 것은 확실하지 않다.
온라인 스키마에 대해 확인
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);
로컬 스키마에 대해 확인
XSD에 대한 XML의 유효성을 단 한 번만 검증해야 했기 때문에 XMLFox를 사용해 보았다.나는 그것이 매우 혼란스럽고 이상하다는 것을 알았다.도움말 지침이 인터페이스와 일치하지 않는 것 같았다.
나는 결국 리퀴드X를 사용하게 되었다.훨씬 사용하기 쉽고 즉각적으로 친숙해진 ML Studio 2008 (v6) (UI는 내가 자주 사용하는 Visual Basic 2008 Express와 매우 유사하다.)단점은 검증 기능이 무료 버전에는 없기 때문에 30일 평가판을 사용해야 한다는 것이다.
참조URL: https://stackoverflow.com/questions/15732/how-to-validate-an-xml-file-against-an-xsd-file
'Programing' 카테고리의 다른 글
VueJS에서 애니메이션에 jQuery를 계속 사용해야 하는가? (0) | 2022.04.16 |
---|---|
Vue.js - 이 간단한 예에서 중첩된 구성 요소를 렌더링하는 방법? (0) | 2022.04.16 |
문자열을 CharSequence로 변환하는 방법? (0) | 2022.04.16 |
입력 필드에 최대 및 최소 제한을 설정하는 중? (0) | 2022.04.16 |
Vue 2 라이프사이클 - Destroy 전에 중지하는 방법? (0) | 2022.04.16 |