Разбор XML файла с сохранением информации о номере строки - PullRequest
3 голосов
/ 03 декабря 2010

Я создаю инструмент, который анализирует некоторые XML файлы (точнее, XHTML файлы). Цель этого инструмента - не только проверить структуру XML, но и проверить значение некоторых атрибутов.

Итак, я создал свой org.xml.sax.helpers.DefaultHandler для обработки событий во время синтаксического анализа XML. Одно из моих требований - иметь информацию о текущем номере строки. Поэтому я решил добавить org.xml.sax.helpers.LocatorImpl к своему DefaultHandler. Это решает почти все мои проблемы, кроме одной, касающейся атрибутов XML.

Давайте рассмотрим пример:

<rootNode>
    <foo att1="val1"/>
    <bar att2="val2"
         answerToEverything="43"
         att3="val3"/>
</rootNode>

Одно из моих правил указывает, что если атрибут answerToEverything определен на узле bar, его значение не должно отличаться от 42.

При обнаружении такого XML мой инструмент должен обнаружить ошибку. Как я хочу дать пользователю точное сообщение об ошибке, например:

Ошибка в файле "foo.xhtml", строка # 4: answerToEverything допускает только "42" в качестве значения.

мой синтаксический анализатор должен сохранять номер строки во время синтаксического анализа, даже для атрибутов . Если мы рассмотрим следующую реализацию для моего DefaultHandler класса:

public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    System.out.println("Start element <" + qName + ">" + x());
    for (int i = 0; i < attributes.getLength(); i++) {
        System.out.println("Att '" + attributes.getQName(i) + "' = '" + attributes.getValue(i) + "' at " + locator.getLineNumber() + ":" + locator.getColumnNumber());
    }
}

затем для узла >bar> отобразится следующий вывод:

Начать элемент в 5: 23
Att 'att2' = 'val2' в 5: 23
Att 'answerToEverything' = '43' в 5:23
Att 'att3' = 'val3' в 5: 23

Как видите, номер строки неверен, потому что парсер будет рассматривать весь узел, включая его атрибуты, как один блок.

В идеале, если бы интерфейс ContentHandler определил бы методы startAttribute и startElementBeforeReadingAttributes, у меня не было бы здесь никаких проблем: o)

Итак, мой вопрос: как мне решить мою проблему?

Для информации, я использую Java 6

ps: Возможно, другим заголовком для этого вопроса может быть Разбор Java SAX с событиями разбора атрибутов или что-то в этом роде ...

Ответы [ 3 ]

0 голосов
/ 03 декабря 2010

Ищите редактор XML с открытым исходным кодом, его анализатор может иметь эту информацию.

Редакторы не используют тот же самый синтаксический анализатор, который использовало бы приложение, которое просто использует xml для данных. Редакторы нуждаются в дополнительной информации, как, например, вы говорите номера строк, и я бы также подумал о пробельных символах. Парсер для редактора не должен терять никакой информации о символах в файле. Так вы можете реализовать, например, функцию форматирования или «выбрать включающий элемент» (Alt-Shift-Up в Eclipse).

0 голосов
/ 03 декабря 2010

Как в XmlBeans, так и в JAXB можно сохранить информацию о номере строки. Вы можете рассмотреть возможность использования одного из этих инструментов (это проще в XmlBeans).

0 голосов
/ 03 декабря 2010

Я думаю, что единственный способ реализовать это - создать собственный InputStream (или Reader), который считает строки и каким-то образом связывается с вашим обработчиком SAX. Я не пытался реализовать это сам, но я верю, что это возможно. Я желаю вам удачи и был бы рад, если вам удастся сделать это и опубликовать свои результаты здесь.

...