XSD 파일에 대해 XML 파일의 유효성을 검사하는 가장 좋은 방법은 무엇입니까?
나에게 주어진 xsd 파일을 준수 해야하는 일부 XML 파일을 생성 중입니다. 그것들이 일치하는지 확인하는 가장 좋은 방법은 무엇입니까?
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>
이제 나쁜 구성 파일이 빌드에 실패합니다!
http://ant.apache.org/manual/Tasks/schemavalidate.html
이것은 대중적인 질문이므로 java는 .xml 파일 자체가 헤더에 XSD를 지정 xsi:SchemaLocation
하거나 xsi:noNamespaceSchemaLocation
(또는 특정 네임 스페이스의 경우 xsi) ex 를 사용하여 xsd에 대해 "참조"할 수 있는지 확인할 수 있음을 지적합니다 .
<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);
Java 7을 사용하면 패키지 설명에 제공된 설명서를 따를 수 있습니다 .
// parse an XML document into a DOM tree DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document document = parser.parse(new File("instance.xml")); // 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 DOMSource(document)); } catch (SAXException e) { // instance document is invalid! }
Linux-Machine을 사용하는 경우 무료 명령 줄 도구 SAXCount를 사용할 수 있습니다. 나는 이것이 매우 유용하다는 것을 알았다.
SAXCount -f -s -n my.xml
dtd 및 xsd에 대해 유효성을 검사합니다. 50MB 파일의 경우 5 초.
데비안 스퀴즈에서는 "libxerces-c-samples"패키지에 있습니다.
dtd와 xsd의 정의는 xml에 있어야합니다! 별도로 구성 할 수 없습니다.
한 가지 추가 답변 : 생성 (쓰기) 중인 파일의 유효성을 검사해야한다고 말했기 때문에 먼저 쓰고 나서 유효성 검사를 위해 다시 읽는 대신 내용을 확인하는 것이 좋습니다. SAX 기반 라이터를 사용하는 경우 Xml 유효성 검사를위한 JDK API를 사용하여이 작업을 수행 할 수 있습니다. 그렇다면 'Validator.validate (source, result)'를 호출하여 유효성 검사기에서 링크하면됩니다. 출력이 필요한 곳.
또는 컨텐츠 (또는 stax를 사용하거나 사용할 수있는 라이브러리)를 작성하기 위해 Stax를 사용하는 경우 Woodstox 는 XMLStreamWriter를 사용할 때 유효성 검사를 직접 지원할 수도 있습니다. 수행 방법을 보여주는 블로그 항목 은 다음과 같습니다 .
프로그래밍 방식으로 XML 파일을 생성하는 경우 XMLBeans 라이브러리 를 살펴볼 수 있습니다. XMLBeans는 명령 행 도구를 사용하여 XSD를 기반으로 Java 오브젝트 세트를 자동으로 생성하고 패키지합니다. 그런 다음이 객체를 사용하여이 스키마를 기반으로 XML 문서를 작성할 수 있습니다.
스키마 유효성 검사를 기본적으로 지원하며 Java 오브젝트를 XML 문서로 변환하거나 그 반대로 변환 할 수 있습니다.
Castor 및 JAXB 는 XMLBean과 유사한 목적을 제공하는 다른 Java 라이브러리입니다.
도구 나 도서관을 찾고 있습니까?
라이브러리가 진행 되는 한 사실상의 표준은 C ++ 및 Java 버전 이 모두있는 Xerces2 입니다 .
그러나 무거운 솔루션입니다. 그러나 XSD 파일에 대해 XML의 유효성을 검사하는 것은 다소 무거운 문제입니다.
이를위한 도구는 XMLFox 가 적절한 프리웨어 솔루션 인 것 같지만 개인적으로 사용하지 않은 것은 확실하지 않습니다.
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 일 평가판을 사용해야했습니다.
'Programing' 카테고리의 다른 글
window.location =과 window.location.replace ()의 차이점은 무엇입니까? (0) | 2020.04.02 |
---|---|
tf.placeholder와 tf.Variable의 차이점은 무엇입니까? (0) | 2020.04.02 |
루비-배열 테스트 (0) | 2020.04.01 |
Html.fromHtml은 Android N에서 더 이상 사용되지 않습니다. (0) | 2020.04.01 |
JavaScript로 클릭을 시뮬레이션하는 방법은 무엇입니까? (0) | 2020.04.01 |