DOMParser#
DOMParser.parseFromString()#
Metoda parseFromString()
pozwala sparsować przekazany łańcuch znakowy (pierwszy argument) pod kątem określonego typu (drugi argument). W efekcie otrzymujemy nowy dokument (z interfejsem zależnym od przekazanego typu), w którym zawarta jest sparsowana węzłowa struktura obiektowa.
Opis działania#
Samo wywołanie i poszczególne jego części najlepiej objaśnić na zapisie składniowym:
var new_document = domParser.parseFromString(str, type);
gdzie poszczególne człony oznaczają:
- new_document - referencja do nowego dokumentu.
- domParser - parser DOM będący obiektem kontekstu.
- str - łańcuch znakowy podlegający parsowaniu.
- type - typ parsowania określany przez wyliczenie
SupportedType
, od którego zależy rodzaj użytego algorytmu parsującego oraz rodzaj interfejsu implementowanego przez nowy dokument. Dostępne są tylko i wyłącznie następujące łańcuchy znakowe:- "
text/html
" - "
text/xml
" - "
application/xml
" - "
application/xhtml+xml
" - "
image/svg+xml
"
- "
Algorytm wywołania metody parseFromString(str, type)
nie jest skomplikowany. Dla lepszego zrozumienia tematu prezentuję go w całości:
- Dla type równego "
text/html
": Parsuj str przy użyciu parsera HTML i zwróć nowo utworzony dokument.
Flaga skryptu musi być ustawiona na "
disabled
".Elementy
<meta>
nie są brane pod uwagę dla używanego kodowania, dopóki strumień Unicode jest przekazywany do parsera.Elementy
<script>
są oznaczane jako niewykonywalne (unexecutable) i zawartość<noscript>
jest parsowana jak struktura znacznikowa (markup).
- Dla type równego "
text/xml
", "application/xml
", "application/xhtml+xml
" i "image/svg+xml
": Parsuj str przy użyciu parsera XML z odblokowaną przestrzenią nazw.
Dla wszystkich XHTML-owych elementów
<script>
parsowanych przy użyciu parsera XML odpowiednik flagi skryptu musi być ustawiony na "disabled
".- Jeśli poprzedni krok nie zwrócił błedu, to zwróć nowo utworzony dokument.
Niech document będzie nowo utworzonym dokumentem XML.
Obiekt document będzie używał interfejsu Document zamiast interfejsu XMLDocument.
Niech root będzie nowym elementem, z nazwą lokalną ustawianą na "
parsererror
" i przestrzenią nazw ustawianą na "http://www.mozilla.org/newlayout/xml/parsererror.xml
".W tym momencie aplikacje klienckie mogą dodać kolejne węzły do root, np. w celu zaprezentowania charakteru błędu.
- Dodaj root do document.
Zwróć document.
W każdym wspomnianym przypadku typ zawartości zwracanego dokumentu musi być zgodny z przekazanym argumentem type
. Ponadto zwracany dokument musi mieć adres URL równy adresowi URL aktywnego dokumentu, i właściwość Document.location
musi zwracać wartość null
. W przypadku kodowania domyślnie ustawiane jest "UTF-8"
.
Działanie metody parseFromString()
dla konkretnego argumentu type można zasymulować innymi metodami, np. wykorzystując DOMImplementation.createDocument()
czy DOMImplementation.createHTMLDocument()
.
Zwracam uwagę, że błąd występujący podczas parsowania odmian XML-a nie zostaje zrzucony (w klasyczny ujęciu), w zamian zwrócony zostaje nowy dokument, w którym poszczególne jego elementy mogą wyjaśniać przyczynę błędu. Oczywiście błąd taki może być automatycznie przekazywany do konsoli przeglądarki (np. w przypadku Firefoksa).
Parsowanie danych tekstowych pochodzących od osób trzecich stwarza duże zagrożenie i jeśli nie jest niezbędne należy rozważyć alternatywne rozwiązania.
Prosty przykład:
<script>
// Tworzymy nowy parser DOM
var parser = new DOMParser();
// Poprawna zawartość XML
var strXML = "<root><customer name='Leszek' address='Warszawa'></customer></root>";
var docXML = parser.parseFromString(strXML, "text/xml");
document.write(docXML); // [object XMLDocument]
document.write("<br>");
document.write(docXML.contentType); // text/xml
document.write("<br>");
document.write(docXML.URL); // Firefox i IE prawidłowo (w Chrome pusty łańcuch znakowy)
document.write("<br>");
document.write(docXML.documentURI); // Firefox i IE prawidłowo (w Chrome null)
document.write("<br>");
document.write(docXML.location); // null (IE zrzuca błąd)
document.write("<br>");
document.write(docXML.characterSet); // UTF-8
document.write("<br>");
document.write(docXML.documentElement.tagName); // root
document.write("<br><br>");
// Poprawna zawartość HTML
var strHTML = "Witam!";
var docHTML = parser.parseFromString(strHTML, "text/html");
document.write(docHTML); // [object HTMLDocument]
document.write("<br>");
document.write(docHTML.contentType); // text/html
document.write("<br>");
document.write(docHTML.URL); // Firefox i IE prawidłowo (w Chrome pusty łańcuch znakowy)
document.write("<br>");
document.write(docXML.documentURI); // Firefox i IE prawidłowo (w Chrome null)
document.write("<br>");
document.write(docXML.location); // null (IE zrzuca błąd)
document.write("<br>");
document.write(docHTML.characterSet); // UTF-8
document.write("<br>");
document.write(docHTML.documentElement.tagName); // HTML
document.write("<br><br>");
// Nieprawidłowa zawartość XML (IE zrzuca błąd)
var strErrorXML = "Witam!";
var errorXML = parser.parseFromString(strErrorXML, "text/xml");
document.write(errorXML); // [object XMLDocument]
document.write("<br>");
document.write(errorXML.childNodes.length); // Zależne od przeglądarki (Firefox - 2, Chrome - 1)
document.write("<br>");
document.write(errorXML.documentElement.tagName); // parsererror (w Chrome html)
document.write("<br>");
document.write(errorXML.documentElement.childNodes.length); // Zależne od przeglądarki (Firefox - 2, Chrome - 1)
document.write("<br>");
document.write(errorXML.documentElement.innerHTML); // Zależne od przeglądarki
</script>
Warto wspomnieć o jeszcze jednej sprawie. Parsowanie tekstu do postaci dokumentu XML najczęściej wykonuje się przy użyciu technologii Ajax, czyli za pomocą obiektu typu XMLHttpRequest
. Służy do tego celu specjalna właściwość XMLHttpRequest.responseXML
, która zwraca gotowy dokument XML zbudowany na bazie pobranej treści. Alternatywnie można skorzystać z właściwości XMLHttpRequest.responseText
, która przechowuje pobrane dane w postaci tekstu, i następnie ręcznie wykonać parsowanie do dokumentu XML przy użyciu metody parseFromString()
.
Na chwilę obecną żadna przeglądarka internetowa nie obsługuje metody parseFromString()
prawidłowo. Wszystkie mają znany problem z użyciem prawidłowego interfejsu dla tworzonego dokumentu oraz niewłaściwie zaimplementowaną obsługę błędów parsowania XML:
- Firefox dodaje węzeł instrukcji przetwarzania przed korzeniem
<parsererror>
, z celem w postaci "xml-stylesheet
" oraz danymi tekstowymi w postaci 'href="chrome://global/locale/intl.css" type="text/css"
', co jest niezgodne ze specyfikacją (można dodawać nowe węzły jedynie do korzenia). - Chrome niewłaściwie ustawia korzeń nowego dokumentu na element
<html>
, do którego wstawia element<body>
, i dopiero w nim znajduje się<parsererror>
z pozostałymi elementami. To samo dotyczy właściwościDocument.URL
błędnie ustawianej na pusty łańcuch znakowy oraz właściwościDocument.documentURI
błędnie ustawianej na wartośćnull
. - IE zrzuca błąd w standardowy sposób, w dodatku próba odwołania się do właściwości
Document.location
generuje błąd.
Kwestie związane z prawidłowym ustawianiem adresów URL dla poszczególnych właściwości nie zostały do końca rozstrzygnięte (W3C - Bug 20378). Problem ten może dotykać wszystkich pozostałych poleceń tworzących nowe dokumenty.
Składnia Web IDL#
interface DOMParser { [NewObject] Document parseFromString(DOMString str, SupportedType type); };