получать больше информации от саксофониста - PullRequest
0 голосов
/ 22 сентября 2009

Могу ли я получить, например, структуру узла или что-то подобное из валидатора? Что-то вроде слушателя или обработчика. Исключения недостаточно. Я должен выбрать узел, где произошла ошибка. Это то, что я строю до сих пор.

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
}

Спасибо.

Ответы [ 4 ]

1 голос
/ 22 сентября 2009

Подтвердить при разборе. Вот код на Java, похоже, что перевод на Groovy должен быть довольно простым:

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));
0 голосов
/ 16 августа 2012

Наткнулся на ту же проблему и решил ее, используя следующее.

  1. Использовал SAXSource при использовании метода validate.
  2. Используется реализация обработчика ошибок для захвата SAXParseException.
0 голосов
/ 17 ноября 2009

В зависимости от того, насколько вы контролируете окружающую среду, есть несколько неуклюжий способ сделать это. Синтаксический анализатор XML Xerxes 2 , который является заменой для синтаксического анализатора по умолчанию, имеет свойство Validator для получения текущего узла, поэтому, если вы сохраняете ссылку на Validator (как поле например, ErrorHandler, который вы устанавливаете в Validator, вы можете получить структуру узла. Вот как я это сделал на 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
  }
  ...
}
0 голосов
/ 22 сентября 2009

Вы должны использовать SAXParseException , чтобы получить больше ошибок, или SAX locator , если вы реализуете ContentHandler, и, возможно, лексер. Исключение даст вам подробную информацию об ошибке, номер строки.

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
}

Обычно информация столбца из локатора возвращает -1 . Для точности смещения вам придется использовать расширенный ContentHandler или лексер:

  • Получить номер строки ошибки
  • Оцените положение узла с помощью информации о строке, атрибутов (начальный тег, конечный тег), используя лексер или регулярные выражения или что-то еще.
...