Подтвердить что ты не робот

Разбор больших XML-документов в JAVA

У меня есть следующая проблема:

У меня есть XML файл (около 1 ГБ), и вам нужно итерации вверх и вниз (т.е. не последовательно, один за другим), чтобы получить требуемые данные и выполнить некоторые операции над ним. Первоначально я использовал пакет DOM Java, но, очевидно, при анализе XML файла JVM достигает своего максимального пространства кучи и останавливается.

Чтобы решить эту проблему, одним из решений, которые я придумал, было найти другой парсер, который выполняет итерацию каждого элемента в XML, а затем я храню его содержимое во временной базе данных SQLite на моем жестком диске. Следовательно, таким образом, куча JVM не будет превышена, и как только все данные будут заполнены, я проигнорирую файл XML и продолжу свои действия во временной базе данных SQLite.

Есть ли другой способ, как я могу решить мою проблему?

4b9b3361

Ответ 1

SAX (простой API для XML) поможет вам здесь.

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

Вот пример реализации:

SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
DefaultHandler handler = new MyHandler();
parser.parse("file.xml", handler);

Где в MyHandler вы определяете действия, которые необходимо предпринять, когда генерируются такие события, как начало/конец документа/элемента.

class MyHandler extends DefaultHandler {

    @Override
    public void startDocument() throws SAXException {
    }

    @Override
    public void endDocument() throws SAXException {
    }

    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
    }

    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
    }

    // To take specific actions for each chunk of character data (such as
    // adding the data to a node or buffer, or printing it to a file).
    @Override
    public void characters(char ch[], int start, int length)
            throws SAXException {
    }

}

Ответ 2

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

Разбор XML файла должен выполняться с помощью SAX parser, как рекомендовал каждый (включая меня). Таким образом, вы можете создавать один объект за раз, и вы можете сразу же его перенести в базу данных.

Для последующей обработки (разрешения перекрестных ссылок) вы можете использовать SELECT из базы данных, делать первичные ключи, индексы и т.д. Вы также можете использовать ORM (Eclipselink, Hibernate), если вам комфортно с этим.

На самом деле я не рекомендую SQLite, проще настроить сервер MySQL и хранить там данные. Позже вы можете даже повторно использовать данные XML (если вы не удалите).

Ответ 3

Если вы хотите использовать более высокий уровень, чем SAX, что может быть очень сложно для программирования, вы можете посмотреть потоковые преобразования XSLT, используя недавнюю версию Saxon-EE. Однако вы слишком расплывчаты в отношении точной обработки, которую вы делаете, чтобы узнать, будет ли это работать для вашего конкретного случая.

Ответ 4

если вам нужен дружественный к ресурсам подход для обработки очень большого xml, попробуйте это: http://www.xml2java.net/xml-to-java-data-binding-for-big-data/ он позволяет обрабатывать данные по SAX-способу, но с преимуществом получать события высокого уровня (данные xml, отображаемые на java), и иметь возможность напрямую работать с этими объектами в вашем коде. поэтому он сочетает в себе удобство jaxb и удобство использования SAX.