, И что может быть в этом списке после «Один из» ... Кроме того, вы можете проверить свой XSD, чтобы лучше понять, что должно быть вместо
я есть файл XML и соответствующий ему файл XSD. При проверке с использованием анализатора StAX я подключил обработчик ошибок. По сути, я сталкиваюсь с двумя типами ошибок в правильно сформированном XML-файле.
1) Неверный тип данных внутри элемента, например, строка внутри элемента, который должен иметь целое число.
2) Отсутствующий элемент: элемент, который должен присутствовать в соответствии с XSD, отсутствует в XML.
Используя анализатор StAX и пользовательский обработчик ошибок, я могу исправить первый тип ошибок. Но для второго типа запускается событие CHARACTER, и значение TEXT является значением ближайшего следующего элемента. Я не знаю, как выяснить, он пропустил элемент. Кроме того, почему вызывается событие CHARACTER, а отсутствующий элемент полностью игнорируется?
Поскольку анализатор StAX работает только вперед, есть ли способ исправить обе ошибки, используя другие анализаторы?
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-файла:
<?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, чтобы спровоцировать второй сценарий. В этом случае событие CHARACTER запускается в «MyErrorHandler». Значение «Y: Да» получается reader.getTextCharacters (). Это значение соответствует элементу HumanSubjectsIndicator1 (обнаружен с помощью метода getLocation ()).
Есть ли способ получить именно локальное имя отсутствующего элемента. Если не использовать StAX, то использовать другие парсеры?
Благодарю.