Генерация XML с использованием SAX и Java - PullRequest
18 голосов
/ 04 февраля 2011

Кто-нибудь знает хороший учебник (или хороший пример) для написания XML с использованием фреймворка SAX (или чего-то подобного) и Java? Поиск дал очень мало с точки зрения полезных результатов. Я пытаюсь выполнить экспорт из приложения для Android и стараюсь избежать как можно большего объема памяти.

Ответы [ 6 ]

33 голосов
/ 04 февраля 2011

SAX-разбор предназначен для чтения документов, а не их записи.

Вы можете написать XML с помощью XMLStreamWriter:

OutputStream outputStream = new FileOutputStream(new File("doc.xml"));

XMLStreamWriter out = XMLOutputFactory.newInstance().createXMLStreamWriter(
                new OutputStreamWriter(outputStream, "utf-8"));

out.writeStartDocument();
out.writeStartElement("doc");

out.writeStartElement("title");
out.writeCharacters("Document Title");
out.writeEndElement();

out.writeEndElement();
out.writeEndDocument();

out.close();
16 голосов
/ 04 февраля 2011

Существует очень полезный метод для генерации XML напрямую из POJO через SAX framework (не парсер SAX, а фреймворк SAX).Этот метод может быть использован для генерации XML-документа .

Генерация XML из произвольной структуры данных
http://download.oracle.com/javaee/1.4/tutorial/doc/JAXPXSLT5.html

По сути, вы добавляете методы в свой POJOили напишите служебный класс для ваших POJO, который превратит их в генераторы событий SAX (генерация событий, как это делает парсер SAX, при анализе XML-документа).Теперь ваш «генератор событий SAX» выглядит как выходная сторона синтаксического анализатора SAX, и ему может быть предоставлен любой обработчик содержимого, который будет использовать синтаксический анализатор SAX, например, тот, который pretyy печатает XML.Но его также можно передавать в анализатор DOM для создания дерева DOM или в механизм XSLT для генерации HTML или выполнения истинного перевода XSL без необходимости сначала создавать промежуточный документ XML из POJO.

ДляНапример, класс Person может иметь метод emitXML(), который включает следующие строки:

handler.startElement(nsu, PERSON_TAG, PERSON_TAG, NO_ATTRIBUTES);

handler.startElement(nsu, FIRSTNAME_TAG, FIRSTNAME_TAG, atts);
handler.characters(this.firstName.toCharArray(), 
        0,
        this.firstName.length());
handler.endElement(nsu, FIRSTNAME_TAG, FIRSTNAME_TAG);

... emit more instance variables

... emit child object like: homeAddress.emitXML(handler, ...);

handler.endElement(nsu, PERSON_TAG, PERSON_TAG);

Обновление:

Пара других ссылок:


Несколько ответов на комментарии:

Это правда, но интерфейс XMLStreamWriter, описанный выше, намного более удобен для пользователя.- Майкл Кей 3 часа назад

Да, но, думаю, я не совсем понял.Я мог бы легко пройти по иерархии и использовать XMLStreamWriter для непосредственного вывода XML-документа в поток. Однако в статьях показан мощный метод обхода иерархии и генерации событий SAX вместо прямой выдачи XML-документа.Теперь я могу подключить разные обработчики контента, которые делают разные вещи или генерируют разные версии XML. Мы также можем передать нашу иерархию объектов любому инструменту, который принимает синтаксический анализатор SAX, например, движок XSLT.На самом деле, он просто использует преимущества шаблона посетителя, установленного инфраструктурой SAX: мы отделяем обход иерархии от вывода XML.Части, которые выводят XML, обработчики контента, должны обязательно использовать XMLStreamWriter, если их целью является запись потока XML.

Например, в нашей программе мы отправляли сообщения XML по сетевым сокетам между распределеннымикомпоненты, и мы также использовали XSLT для генерации наших HTML-страниц.Ранее мы прошли через нашу иерархию, чтобы сгенерировать XML-документ (строку), а затем либо записали этот XML-документ в сетевой сокет, либо передали этот документ в механизм XSLT (который, по сути, просто анализировал его снова).После использования этого метода мы могли бы по существу передать нашу иерархию объектов (используя этот SAX-адаптер) непосредственно в механизм XSLT, не нуждаясь в промежуточной строке XML.Было также удобно иметь возможность использовать один обработчик содержимого для создания компактного представления XML для сетевого потока, а другой - для создания довольно распечатанного документа XML для записи в файл журнала.

* 1052Кроме того, использование API синтаксического анализатора SAX для написания XML является злоупотреблением API, IMHO.- Puce 49 минут назад

Возможно, но я думаю, что это зависит от ваших потребностей.Если требование OP состоит в том, чтобы просто написать конкретный XML-документ, то это определенно излишне.Однако я подумал, что стоит упомянуть, использует ли ОП в своем проекте XML другими способами, которые он не упомянул.Нет ничего плохого в том, чтобы выдвигать альтернативную идею.

Называть ее злоупотреблять может быть немного сильным, но я согласен, что вы имеете право на свое мнение.Он задокументирован в учебнике по Oracle, поэтому он не считается злоупотреблением со стороны инженеров Sun / Oracle.В нашем проекте было очень успешно помочь нам удовлетворить наши требования без каких-либо существенных недостатков, поэтому я буду держать этот подход в своем наборе инструментов, когда он пригодится в будущем.

5 голосов
/ 04 февраля 2011

Ниже приведены ответы «хороший учебник по написанию XML с использованием SAX-анализатора и Java» часть вопроса

Я не уверен, что вы прошли через это.Но мне действительно нравится Действительно большой индекс всего Java .

Пройдите через это: http://download.oracle.com/javase/tutorial/jaxp/index.html

И, наконец, это: http://download.oracle.com/javase/tutorial/jaxp/sax/index.html

4 голосов
/ 06 декабря 2011

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

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

3 голосов
/ 04 февраля 2011

Также рассмотрим JAXB для записи / чтения XML.

1 голос
/ 02 августа 2013

Вы также можете соединиться с trax с помощью:

public abstract class PipedSAXSource extends SAXSource {
  protected PipedSAXSource() {
    setXMLReader(new CallWriteDuringSax());
  }

  protected abstract void writeTo(ContentHandler sink)
      throws IOException, SAXException;

  private class CallWriteDuringSax extends XMLFilterImpl {
    @Override
    public void parse(InputSource ignored) throws IOException, SAXException {
      writeTo(getContentHandler());
    }

    @Override
    public void setFeature(String name, boolean value) {}
  }
}

Используйте вот так:

  public static void main(String[] args) throws Exception {
    Source in = new PipedSAXSource() {
      @Override
      protected void writeTo(ContentHandler sink) throws SAXException {
        sink.startDocument();

        sink.startElement("", "root", "root", new AttributesImpl());
        sink.endElement("", "root", "root");

        sink.endDocument();
      }
    };

    Transformer identity = TransformerFactory.newInstance().newTransformer();
    identity.transform(in, new StreamResult(System.out));
  }
...