SAX

SAX (англ. «Simple API for XML») — способ последовательного чтения/записи XML-файлов.

Обычно SAX-парсеры требуют фиксированного количества памяти для своей работы, но не позволяют изменять содержимое документа. Всё, что делает SAX-парсер, это сообщает вызвавшему приложению о встретившихся распознанных элементах XML-разметки или о встретившихся ошибках. Связь парсера с вызывающим приложением, как правило, осуществляется посредством функций обратного вызова.

Реализации SAX-парсеров могут различаться, но в целом они устроены однотипно, примерно так, как показано ниже:

// ... На примере языка C++

// Поток документа
struct Stream
{
    virtual xml_char pop_char() = 0;
    virtual bool has_data() = 0;
};

// Класс, которому парсер сообщает о найденных элементах разметки
struct Callback
{
    virtual void doc_start() = 0;
    virtual void doc_end() = 0;

    virtual void element_start( string el_name ) = 0;
    virtual void element_end( string el_name ) = 0;

    virtual void attribute( string name, string value ) = 0;

    virtual void text_node( string txt ) = 0;

    // ...
};

// Сам парсер. -- Довольно сложный, чтобы его тут полностью записать
struct Parser
{
    bool parse( Stream& xml, Callback& cb );
    // ... 
};

Использование:

struct MyFileStream : Stream { ... };
struct MyCallback : Callback { ... };

MyFileStream _stream( "some_file.xml" );
MyCallback _cb;

Parser parser;

bool success = parser.parse( _stream, _cb );

// Например, "some_file.xml" содержит следующий текст:
// <html lang="en">
//   <b>bold text</b>
// </html>

// Тогда парсер вызовет методы класса "Callback" в следующем порядке:
// _cb.doc_start();
// _cb.element_start( "html" );
// _cb.attribute( "lang", "en" );
// _cb.element_start( "b" );
// _cb.text_node( "bold text" );
// _cb.element_end( "b" );
// _cb.element_end( "html" );
// _cb.doc_end();

Применяются SAX-парсеры либо для быстрого поиска по XML-документам, либо во время построения DOM, либо для чтения XML-потоков большого объёма (когда построение DOM требует слишком большого объёма памяти).

SAX — событийный парсер XML. Он содержит очень похожую модель обработки событий на такую же модель в Java. К примеру, в аплете можно зарегистрировать обработчик события на клик мышкой, а в SAX можно зарегистрировать обработчик события на начало и конец тегов элементов, таких как <name> и </name>. В этом документе рассматривается XML парсер производства IBM. Он бесплатен и имеет общедоступные исходные тексты. Возьмём простой пример XML файла:

 <?xml version="1.0" encoding="windows-1251"?>
 <order>
   <item>
     <name>Soccer Ball</name>
     <price>15.00</price>
     <quantity>5</quantity>
   </item>
 </order>

Параметр encoding="windows-1251" необходим для работы в кодировке Windows. Осуществим разбор XML-документа с помощью SAX в несколько шагов. Эти шаги выделены в коде примера.

  • Регистрация парсера XML
  • Создание экземпляра XMLReader
  • Создание экземпляра класса, отвечающего за обработку событий SAX-а
  • Подключение обработчика событий к экземпляру нашего XMLReader-а
  • Разбор документа посредством передачи XMLReader-у XML файла. (В этом примере используется файл «order.xml», содержащий XML код, приведенный в начале статьи.)

В примере наш класс расширит DefaultHandler. DefaultHandler — это класс-адаптер, который позволит нам обрабатывать только те события SAX-а, которые нам нужны, а не реализовывать все его события.

package xml;

import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;

public class SimpleSax extends DefaultHandler {
  private String currentElement = null;

  public static void main(String[] args) {
    try {
      //В JDK 5.0 введен этот парсер, и путь такой: com.sun.org.apache.xerces.internal.parsers.SAXParser.
      Class c = Class.forName("org.apache.xerces.parsers.SAXParser");
      XMLReader reader = (XMLReader)c.newInstance();
      SimpleSax ss = new SimpleSax();
      reader.setContentHandler(ss);
      reader.parse("order.xml");
    } catch(Exception e){System.out.println(e);}
  }

  public void startElement(String uri, String local_name, String raw_name, Attributes amap) throws SAXException {
    currentElement = local_name;
    System.out.println("start " + local_name + " found ");
  }
  public void endElement(String uri, String local_name, String raw_name) throws SAXException {
    System.out.println("end " + local_name + " found");
  }

  public void startDocument() throws SAXException {
   System.out.println("start document");
  }

  public void endDocument() throws SAXException {
   System.out.println("end document");
  }

  public void characters(char[] ch, int start, int length) throws SAXException {
   String value = new String(ch,start,length);
   if (!Character.isISOControl(value.charAt(0))) {
    System.out.println("characters " + value + " found " + currentElement);
   }
  }
}

См. также

Литература

Ссылки

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.