Разбор Java SAX. Получение доступа к строкам файла в текущем файле XML - PullRequest
1 голос
/ 13 декабря 2011

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

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

Спасибо!

:::::::::::::::::::::::::: EDIT :::::::::::::::::::

Я пытаюсь отобразить XML-файл и хочу, чтобы в него были включены объявления типа документа:

<!DOCTYPE employee [<!ELEMENT employee (Name, Dept, Title)>
<!ELEMENT Name (#PCDATA)> 
<!ELEMENT Dept (#PCDATA)>
<!ELEMENT Title (#PCDATA)> ]>

Есть

public void startDTD(String name, String publicId, String systemId);

и

public void endDTD();

Где вы можете использовать локатор для получения текущей строки и столбца и чтения из файла.

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

Ответы [ 2 ]

2 голосов
/ 13 декабря 2011

Во-первых, если вы уверены, что синтаксический анализатор не предоставляет необходимую информацию через один из более специализированных обработчиков, например LexicalHandler

Если вам действительно нужен доступ к необработанным данным, напишите реализацию Reader или InputStream, которая находится между анализатором SAX и «реальным» Reader или InputStream, передавая все запросы read () базовому читателю, но отслеживая последние несколько строк читаются из файла. Затем этот фильтр может отвечать на запросы о предоставлении содержимого строки N, поскольку он сохранил данные. Однако я не уверен, как вы можете заставить эту работу соответствовать вашим реальным требованиям, потому что искомая информация может быть распределена по произвольному количеству строк.

0 голосов
/ 13 декабря 2011

Нет способа добраться до "файла".Там может даже не быть файла, поскольку выходные данные могут генерироваться динамически или извлекаться по сети.Синтаксический анализатор отслеживает количество новых строк (\ r \ n, \ n или \ r), которые он пропустил при анализе содержимого.При использовании SAX не вся текущая строка обязательно доступна (представьте большой документ, все в одной строке).

Вы можете заключить свой ввод в класс, который отслеживает «текущую строку» для вас,но опять же, остерегайтесь больших документов в одну строку.

РЕДАКТИРОВАТЬ: обещанная простая оболочка

public class LastLineInputStreamWrapper extends InputStream {

    private final byte[] buffer = new byte[10*1024];
    private final InputStream wrapped;
    private int previous;
    private int length;

    public LastLineInputStreamWrapper(InputStream wrapped) {
        this.wrapped = wrapped;
    }

    @Override
    public int read() throws IOException {
        int current = wrapped.read();
        if ('\r' == current) {
            newLine();
        } else if ('\n' == current) {
            if ('\r' != previous) {
                newLine();
            }
        } else {
            add(current);
        }
        previous = current;
        return current;
    }

    private void newLine() {
        length = 0;
    }

    private void add(int current) {
        if (length < buffer.length && current != -1) {
            buffer[length++] = (byte) current;
        }
    }

    public byte[] getLine() {
        byte[] line = new byte[length];
        System.arraycopy(buffer, 0, line, 0, length);
        return line;
    }
}

Простой способ сделать это, просто чтобы показать вам, как начать.Если вы хотите пойти по этому маршруту, вы, вероятно, захотите переопределить методы read (byte []), чтобы избежать вызова read для каждого байта.

Если у вас вместо этого есть Reader, то вы можете использовать символы непосредственно вместобайт.

...