Obtendo mais informações do Validador Sax
Pergunta
Posso obter, por exemplo, a estrutura do nó ou algo assim do validador? Algo como um ouvinte ou um manipulador. A exceção não é suficiente. Eu tenho que selecionar o nó onde ocorreu o erro. Isso é o que eu construo até agora.
def factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI)
def schema = factory.newSchema(new StreamSource(new FileReader("src/import.xsd")))
def validator = schema.newValidator()
try {
validator.validate(new StreamSource(new FileReader("src/import.xml")))
println "everything is fine"
} catch(SAXException e) {
println e
}
Obrigada.
Solução
Valide quando você analisa. Aqui está o código em Java, parece que a tradução para Groovy deve ser bem direta:
InputStream xml = // …
InputStream xsd = // …
SchemaFactory xsFact = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = xsFact.newSchema(new StreamSource(xsd));
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setValidating(false);
dbf.setSchema(schema);
DocumentBuilder db = dbf.newDocumentBuilder();
Document dom = db.parse(new InputSource(xml));
Outras dicas
Você tem que usar o SaxparseException para obter mais erros ou o Localizador Sax Se você está implementando o ContentHandler e possivelmente um Lexer. A exceção fornecerá detalhes sobre o erro, número da linha.
try{
...
}
catch(SAXParseException e){
int lineNumber = e.getLineNumber();
int columnNumber = e.getColumnNumber();
String message = e.getMessage();
// do something
}
catch(SAXException e){
// what should we do?
// if we're implementing ContentHandler
// we can use the org.xml.sax.Locator to get more info
}
Normalmente, as informações da coluna do localizador retornam -1. Para precisão de deslocamento, você precisará usar um conteúdo estendido ou um Lexer:
- Obtenha o número da linha do erro
- Estime a posição do nó com as informações da linha, atributos (tag inicial, etiqueta final) usando um lexer ou expressões regulares ou qualquer outra coisa.
Dependendo de quanto controle você tem sobre o ambiente, há uma maneira um pouco desajeitada de fazer isso. o Xerxes 2 O analisador XML, que substitui o analisador padrão, possui uma propriedade no validador para obter o nó atual; portanto, se você mantiver uma referência ao validador (como um campo de um manipulador de erros que você define no validador, por exemplo) você pode obter a estrutura do nó. Veja como eu fiz isso em Java:
...
Validator validator = schema.newValidator();
validator.setErrorHandler(new MyErrorHandler(validator));
...
public class MyErrorHandler implements ErrorHandler {
private Validator validator;
public AnnotatingErrorHandler(Validator v) {
super();
validator = v;
}
@Override
public void error(SAXParseException e) throws SAXException {
try {
element = (Element)validator.getProperty("http://apache.org/xml/properties/dom/current-element-node");
} catch (SAXNotRecognizedException e) {
log(Level.SEVERE, "Xerxes 2 XML parser is required", saxnre);
} catch (SAXNotSupportedException e) {
; // shouldn't happen in this context
}
... // do stuff
}
...
}
Encontrou o mesmo problema e o resolveu usando o seguinte.
- Utilizou SAXSource ao usar o método validado.
- Utilizou a implementação do manipulador de erros para capturar saxparseexception.