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.

Foi útil?

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.

  1. Utilizou SAXSource ao usar o método validado.
  2. Utilizou a implementação do manipulador de erros para capturar saxparseexception.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top