SAX
z Mozilla Developer Center, polskiego centrum programistów Mozilli.
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.
[edytuj] 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.
[edytuj] 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;
}
};
[edytuj] 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