XML 파일과 해당 XSD 파일이 있습니다. StAX 파서를 사용하여 유효성을 검사하는 동안 오류 처리기를 첨부했습니다. 기본적으로 올바른 형식의 XML 파일에서 두 가지 유형의 오류가 발생합니다.XSD에 대해 유효성을 검사하는 동안 DOM, StAX, SAX 파서 중 하나를 사용하여 XML에서 정확한 누락 요소를 찾습니다.
1) 요소 내에 잘못된 유형의 데이터가 있습니다 (예 : 정수가 있어야하는 요소 내부의 문자열).
2) 누락 요소 : XSD에 따라 있어야하는 요소가 XML에 없습니다.
StAX 구문 분석기 및 사용자 지정 오류 처리기를 사용하여 첫 번째 오류 유형을 수정할 수 있습니다. 그러나 두 번째 유형의 경우 CHARACTER 이벤트가 트리거되고 TEXT 값은 바로 다음 요소의 값입니다. 누락 된 요소를 파악하는 방법을 모르겠습니다. 또한 CHARACTER 이벤트가 트리거되고 누락 된 요소가 완전히 무시되는 이유는 무엇입니까?
StAX 파서는 앞으로 만 진행되므로 다른 파서를 사용하여 두 가지 오류를 모두 해결할 수있는 방법이 있습니까?
<?xml version="1.0" encoding="UTF-8"?>
<PHSHumanSubjectsAndClinicalTrialsInfo:PHSHumanSubjectsAndClinicalTrialsInfo xmlns:PHSHumanSubjectsAndClinicalTrialsInfo="http://apply.grants.gov/forms/PHSHumanSubjectsAndClinicalTrialsInfo-V1.0" PHSHumanSubjectsAndClinicalTrialsInfo:FormVersion="1.0"
>
<!-- <PHSHumanSubjectsAndClinicalTrialsInfo:HumanSubjectsIndicator
>Y: </PHSHumanSubjectsAndClinicalTrialsInfo:HumanSubjectsIndicator
>-->
<PHSHumanSubjectsAndClinicalTrialsInfo:HumanSubjectsIndicator1
>Y: Yes</PHSHumanSubjectsAndClinicalTrialsInfo:HumanSubjectsIndicator1
>
<PHSHumanSubjectsAndClinicalTrialsInfo:HumanSubjectsIndicator2
>Y: Yes</PHSHumanSubjectsAndClinicalTrialsInfo:HumanSubjectsIndicator2
>
다음
HumanSubjectsIndicator 요소가 두 번째 시나리오를 자극 주석 :
import java.io.File;
import java.io.IOException;
import javax.xml.XMLConstants;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.*;
import javax.xml.validation.Validator;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
public class XMLValidation {
public static void main(String[] args) {
XMLValidation xmlValidation = new XMLValidation();
System.out.println(xmlValidation.validateXMLSchema("PHSHumanSubjectsAndClinicalTrialsInfo-V1.0.xsd", "FullPHSHuman.xml"));
}
public boolean validateXMLSchema(String xsdPath, String xmlPath){
try {
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = factory.newSchema(new File(xsdPath));
StreamSource XML = new StreamSource(xmlPath);
XMLStreamReader reader = XMLInputFactory.newFactory().createXMLStreamReader(XML);
Validator validator = schema.newValidator();
validator.setErrorHandler(new MyErrorHandler(reader));
validator.validate(new StAXSource(reader));
} catch (IOException | SAXException | XMLStreamException e) {
System.out.println("Exception: "+e.getMessage() + " local message " + e.getLocalizedMessage() + " cause " + e.getCause());
return false;
}
return true;
}
}
class MyErrorHandler implements ErrorHandler {
private XMLStreamReader reader;
public MyErrorHandler(XMLStreamReader reader) {
this.reader = reader;
}
@Override
public void error(SAXParseException e) throws SAXException {
System.out.println("error");
warning(e);
}
@Override
public void fatalError(SAXParseException e) throws SAXException {
System.out.println("fatal error");
warning(e);
}
@Override
public void warning(SAXParseException e) throws SAXException {
if(reader.getEventType() == 1 || reader.getEventType() == 2) {
//The first type of error is detected here.
System.out.println(reader.getLocalName());
System.out.println(reader.getNamespaceURI());
}
if(reader.getEventType() == XMLStreamConstants.CHARACTERS) {
int start = reader. getTextStart();
int length = reader.getTextLength();
System.out.println(new String(reader.getTextCharacters(), start, length));
}
}
}
아래는 잘 구성된 XML 파일의 조각입니다. 이 경우 'MyErrorHandler'에서 CHARACTER 이벤트가 트리거됩니다. 'Y : Yes'값은 reader.getTextCharacters()에서 가져옵니다. 이 값은 HumanSubjectsIndicator1 요소에 해당합니다 (getLocation() 메소드를 사용하여이 값을 찾습니다).
누락 된 요소의 로컬 이름을 정확하게 가져 오는 방법이 있습니까? StAX를 사용하지 않는다면 다른 파서를 사용 하시겠습니까?
감사합니다. 필요한 요소가 없을 때
확실히 패턴 매칭을 구현할 수 있습니다. 하지만 뭔가 구체적인 것을 찾고 있어요. 오류가 발생하여 이벤트를 통해 캡처 할 수있는 코드의 일부를 찾고 있는데, 이전 형제를 찾을 수 있습니다. ** StAX가 앞으로 만 전달되므로 DOM이 원인을 제공 할 수 있습니까? – mark42inbound
SAXParseException의 메시지는 다음과 같습니다. ** cvc-complex-type.2.4.a : 'PHSHumanSubjectsAndClinicalTrialsInfo : HumanSubjectsIndicator1'요소로 시작하는 잘못된 콘텐츠가 발견되었습니다. '{ "http://apply.grants.gov/forms/PHSHumanSubjectsAndClinicalTrialsInfo-V1.0"HumanSubjectsIndicator}"중 하나가 필요합니다. **이 메시지는 내부적으로 형성 될 수 있으므로 요소 이름을 추출하는 방법이 있습니까? 몇 가지 구체적인 방법? – mark42inbound
메시지는 'HumanSubjectsIndicato r1' 대신에 다른 것이 있어야 함을 의미합니다. 그리고 그 중 하나는 "그 중 하나"다음에 그 목록에 있습니다.또한 XSD를 검사하여'HumanSubjectsIndicato r1' 대신에 무엇이 있어야하는지 더 잘 이해할 수 있습니다. – Vadim