SAX

SAX, skrót dla Simple API for XML, jest parserem API. Po raz pierwszy SAX został szeroko zadoptowany w API dla XML w Javie i później został zaimplementowany w kilku innych środowiskach programowania. Wraz z Firefoksem 2, parser SAX jest dostępny w aplikacjach XUL i rozszerzeniach. Aby zdobyć dodatkowe informacje, odwiedź stronę domową SAX.

Szybki start

Funkcjonalność parsera SAX jest dostępna poprzez interfejs XML reader component. Aby go utworzyć, zastosuj poniższy kod:

var xmlReader = Components.classes["@mozilla.org/saxparser/xmlreader;1"]
                          .createInstance(Components.interfaces.nsISAXXMLReader);

Po utworzeniu parsera SAX, będzie potrzebne ustawienie podprogramów obsługi dla zdarzeń, którymi jesteśmy zainteresowani and fire off the parsing process. Cała funkcjonalnośc jest dostępna poprzez interfejs nsISAXXMLReader.

Ustawienie obiektów obsługi

Obiekty obsługi (określone przez użytkownika) są zdefiniowanymi obiektami zaimplementowanymi w programie obsługi interfejsu SAX, które są zależne od rodzaju informacji, jaki chcemy otrzymać z parsera. Po rozpoczęciu procesu parsowania, obiekty obsługi przyjmują szereg wywołań zwrotnych dla treści XML, która jest parsowana. Dostępne są następujące obiekty obsługi:

Interfejs Zastosowanie
nsISAXContentHandler Pakiet obiektu obsługuje zawartość logiczną dokumentu (np. elementy, atrybuty, białe znaki oraz instrukcje przetwarzania).
nsISAXDTDHandler Pakiet obiektu obsługuje proste podobne do DTD zdarzenia.
nsISAXErrorHandler Pakiet obsługi błędów strumienia wejściowego.
nsISAXLexicalHandler Rozszerzenie obiektu SAX2 dla zdarzeń struktur leksykalnych (np. komentarzy i sekcji CDATA, deklaracji DTD oraz encji).

Przykład implementacji najczęściej stosowanych obiektów obsługi:

function print(s) {
  dump(s + "\n");
}

xmlReader.contentHandler = {
  // nsISAXContentHandler
  startDocument: function() {
    print("startDocument");
  },
  
  endDocument: function() {
    print("endDocument");
  },
  
  startElement: function(uri, localName, qName, /*nsISAXAttributes*/ attributes) {
    var attrs = [];
    for(var i=0; i<attributes.length; i++) {
      attrs.push(attributes.getQName(i) + "='" + 
                 attributes.getValue(i) + "'");
    }

    print("startElement: namespace='" + uri + "', localName='" + 
          localName + "', qName='" + qName + "', attributes={" + 
          attrs.join(",") + "}");
  },
  
  endElement: function(uri, localName, qName) {
    print("endElement: namespace='" + uri + "', localName='" + 
          localName + "', qName='" + qName + "'");
  },
  
  characters: function(value) {
    print("characters: " + value);
  },
  
  processingInstruction: function(target, data) {
    print("processingInstruction: target='" + target + "', data='" + 
          data + "'");
  },
  
  ignorableWhitespace: function(whitespace) {
    // don't care
  },
  
  startPrefixMapping: function(prefix, uri) {
    // don't care
  },
  
  endPrefixMapping: function(prefix) {
    // don't care
  },
  
  // nsISupports
  QueryInterface: function(iid) {
    if(!iid.equals(Components.interfaces.nsISupports) &&
       !iid.equals(Components.interfaces.nsISAXContentHandler))
      throw Components.results.NS_ERROR_NO_INTERFACE;
    return this;
  }
};

Rozpoczęcie parsowania

XML Reader component potrafi parsować XML z łańcucha znakowego, nsIInputStream lub asynchronicznie przez interfejs nsIStreamListener. Poniżej znajduje się przykład parsowania z łańcucha znakowego:

xmlReader.parseFromString("<f:a xmlns:f='g' d='1'><BBQ/></f:a>", "text/xml");

Wywoła to następującym rezultat na wyjściu (biorąc na siebie zawartość obiektu obsługi stosując przykład powyżej):

startDocument
startElement: namespace='g', localName='a', qName='f:a', attributes={d='1'}
startElement: namespace='', localName='BBQ', qName='BBQ', attributes={}
endElement: namespace='', localName='BBQ', qName='BBQ'
endElement: namespace='g', localName='a', qName='f:a'
endDocument

Autorzy i etykiety dokumentu

 Autorzy tej strony: Ptak82, Mgjbot
 Ostatnia aktualizacja: Ptak82,