Я создаю инструмент, который анализирует некоторые 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 с событиями разбора атрибутов или что-то в этом роде ...