Пропустить содержимое элемента в SAX-разборе в Java

Я анализирую пользовательский файл конфигурации XML в приложении Java. Я пытаюсь использовать синтаксический анализатор SAX, главным образом потому, что мне нужно сообщать об ошибках в конфигурации с номерами строк.

В Интернете есть много примеров кода реализации класса-обработчика, и для нормальной обработки все выглядит довольно просто - например, http://tutorials.jenkov.com/java-xml/sax-example.html

Но в моем случае иногда мне нужно пропустить целое дерево под элементом:

<sampledocument>
    <sampletag>
         <process/>
         <these/>
         <tags/>
    </sampletag>
    <sampletag skip="yes">
         <do_not>
         <process/>
         <these/>
         <tags/>
    </sampletag>
<sampledocument>

ПОСЛЕДНЕЕ ДОБАВЛЕНИЕ: Более того, я знаю только, пропустить ли во время выполнения. В несколько надуманном примере мне нужно открыть файл для обработки тегов в <sampletag>, а если файл не найден, не обрабатывать их:

<sampledocument>
    <sampletag file="file1">
         <process/>
         <these/>
         <tags/>
         <if_file1_exists/>
    </sampletag>
    <sampletag file="file2">
         <process/>
         <these/>
         <tags/>
         <if_file2_exists/>
    </sampletag>
<sampledocument>

Конечно, я могу просто отследить пропуск в коде обработчика, но это немного неловко. Могу ли я как-то сказать SAX в методе startElement(), чтобы просто пропустить содержимое этого элемента?

1 ответ

Напишите класс фильтра для конвейера между анализатором SAX и вашим существующим ContentHandler. Вы можете сделать это, расширив XMLFilterImpl, Этот фильтр должен иметь целочисленную переменную skipDepth, изначально равную нулю.

В startElement, если вы распознаете элемент, который хотите глубоко пропустить, или если skipDepth > 0, тогда увеличьте skipDepth.

В endElement, если skipDepth > 0, уменьшать skipDepth.

Во всех обработчиках событий передавайте событие по конвейеру (вызывая super.xxx()) тогда и только тогда, когда skipDepth == 0.

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

Другие вопросы по тегам