Можно ли получить номер текущей строки при разборе XML-документа с помощью Xerces? - PullRequest
3 голосов
/ 20 февраля 2009

У меня есть Java-программа, которая анализирует XML-документ с помощью API xerces.

Мой класс синтаксического анализа расширяет org.apache.xerces.parsers.XMLDocumentParser, перегружая методы startElement, endElement, characters.

Поскольку это сложный XML-документ, который написан от руки (в основном, это некие элементы конфигурации), классической проверки с помощью xsd или dtd недостаточно, и я должен вернуть пользователю, что документ XML недействителен.

Но одна вещь, которую я не смог достичь, - это добавить в сообщения об ошибках информацию о номере строки (и почему не о номере столбца), то есть анализируемую величину тока и место возникновения ошибки.

Я полагаю, что это возможно, потому что исключения (org.apache.xerces.xni.parser.XMLParseException), сгенерированные синтаксическим анализатором, когда документ XML не является допустимым XML, содержат эту информацию.

Ответы [ 2 ]

5 голосов
/ 20 февраля 2009

Я никогда не пробовал это с xerces, но парсеры SAX могут хранить SAX Locator , из которого вы можете получить номера строк и столбцов при разборе документа (или после исключения).

Похоже, XMLDocumentParser может сделать то же самое. Его родительский класс, AbstractXMLDocumentParser, имеет метод startDocument , которому передается параметр XMLLocator. Если вы переопределите этот метод, вы можете сохранить XMLLocator и использовать его методы getLineNumber и getColumnNumber.

1 голос
/ 20 февраля 2009

Не уверен, какой будет «правильный» способ, но глядя на API, предполагая, что вы предоставляете XMLInputSource, который принимает InputStream или Reader, который вы можете предоставить в InputStream / Reader, который обернут LineNumberInputStream или LineNumberReader, а затем запросите его для номера строки.

Например:

InputStream stream;

stream = ...;

new XMLInputSource(stream);

станет:

InputStream stream;
LineNumberInputStream lineStream;

stream = ...;
lineStream = new LineNumberInputStream(lineStream);

new XMLInputSource(lineStream);

// can now ask the line stream what line it is on via getLineNumber()

Полагаю, вам также необходимо передать LineNumberInputStream / LineNumberReader в ваш класс, который расширяет XMLDocumentParser.

Не уверен, что все это выполнимо в вашем коде.

Либо покопайтесь в источнике и узнайте, как они это делают. Если переменные / методы, к которым вам нужно получить доступ, являются закрытыми, и вы не беспокоитесь о том, что ваш код будет нарушен в будущем, вы можете использовать отражение и удалить права доступа, чтобы получить к нему доступ.

...