Mientras valida con XSD, encuentre el elemento exacto que falta en el XML utilizando cualquiera de los analizadores DOM, StAX, SAX

Tengo un archivo XML y su archivo XSD correspondiente. Al validar con el analizador StAX, adjunté un controlador de errores. Básicamente, encuentro dos tipos de errores en un archivo XML bien formado.

1) Tipo de datos incorrecto dentro de un elemento, por ejemplo, cadena dentro de un elemento que se supone que tiene un número entero.

2) Elemento faltante: un elemento que debe estar presente de acuerdo con XSD no está presente en el XML.

Utilizando un analizador StAX y un controlador de errores personalizado, puedo rectificar el primer tipo de error. Pero para el segundo tipo, se activa un evento CHARACTER y el valor de TEXT es el valor del siguiente elemento inmediato. No sé cómo resolverlo, el elemento que falta. Además, ¿por qué se activa el evento CHARACTER y se ignora por completo el elemento que falta?

Como el analizador StAX es solo hacia adelante, ¿hay alguna forma de rectificar los dos errores utilizando otros analizadores?

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));
        }
    }
}

A continuación se muestra el fragmento del archivo XML bien formado:

<?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
    >

Aquí se comenta el elemento HumanSubjectsIndicator para provocar el segundo escenario. En este caso, se desencadena un evento CHARACTER en 'MyErrorHandler'. El valor 'Y: Sí' se obtiene reader.getTextCharacters (). Este valor corresponde al elemento HumanSubjectsIndicator1 (encontrado usando el método getLocation ()).

¿Hay alguna manera de obtener exactamente el nombre local del elemento que falta? Si no usa StAX, ¿entonces usa otros analizadores?

Gracias.

Respuestas a la pregunta(1)

Su respuesta a la pregunta