Select Page

W trakcie pracy nad projektem okazało się, że wstawienie XML w jeden z elementów strony powoduje problem.

Houston, mamy problem

Jeśli wstawimy XML na stronę function screenOutput( content ), struktura naszego XML DOM trochę się pomiesza. Źle zinterpretowane zostaną puste znaczniki, które mają postać <tag/> zamiast <tag></tag>. Parser traktuje je jako otwierające i zamiast od razu je zamknąć, wstawia jako ich zawartość tagi po nich następujące. Nie stanowi to większego problemu, kiedy DOM służy nam jako pomoc w badaniu kolejnych elementów. Jeśli jednak chcemy poruszać się po drzewie i wybierać z niego informacje, sytuacja zmienia się diametralnie. Spowodowane jest to zaburzeniem relacji rodzic–potomek, i skutkuje nieoczekiwanymi (błędnymi) wynikami.
Żeby to zmienić, musimy poprawić metodę pobierania z drzewa interesującego nas węzła (w tym przypadku <office:text>). Ponieważ nie możemy pobrać fragmentu wstrzykniętego w nasz dokument HTML, musimy operować na wyniku przetwarzania XMLHttpRequest responseXML. Pomoże nam w tym funkcja getContent, która z przekazanej treści pobierze element o podanej nazwie. Dzięki temu struktura naszego DOM będzie nienaruszona a puste znaczniki nie wprowadzą zamieszania.
Ktoś może się zastanawiać, co właściwie zyskujemy? Rozwiązanie wcześniejsze, czyli próba pobrania <office:text> wstrzykniętego do HTML dawała nam jeden tablicę jednoelementową. To działało, ale rekurencyjne wywoływanie funkcji readFromFirst łączyło wszystkie elementy naszego pliku w jeden duży tekst. Zmiana, która została wprowadzona w pobieraniu <office:text> sprawiła, że każdy potomek <office:text> jest osobnym elementem tablicy. Teraz readFromFirst zwraca tablicę, która przechowuje poszczególne dzieci <office:text> jako osobne elementy tekstowe.

Node.js

Zmiana, która została wprowadzona działa również w node.js. To jest drugi mały sukces (pierwszym jest odkrycie i skorygowanie problemu XML DOM). Kod napisany pod, i testowany w przeglądarce udało się przenieść do node właściwie bez zmian. Jedyne różnice to wczytanie pliku XML. Dla przeglądarki jest to funkcja success z XMLHttpRequest i zmienną const response = xhr.responseXML, dla node.js jsdom.env ze zmienną const response = window.document. Dalsza część jest już identyczna. W obu przypadkach następuje content = getContent( response, 'office:text' ); oraz traverseDOM( content );

Listy

Do tej pory wszystkie testy odbywały się na tytułach i tekście akapitowym ze stylami znakowymi. Pomyślałem, że może warto dodać do nich listy numerowane i nienumerowane. Przygotowałem odpowiedni plik, którego adres przechowuje zmienna urlFour. Kod działa również w tym przypadku, traktuje jednak elementy listy jako dzieci akapitu z listą (w strukturze tak to jest zdefiniowane) i ze wszystkich elementów listy robi jeden długi tekst.

Co dalej?

Zaczynam myśleć, że łatwa część projektu powoli się kończy. Dotarłem do miejsca, w którym nie objedzie się chyba bez drobiazgowego analizowania specyfikacji formatu ODF XML. Żeby ruszyć do przodu, trzeba rozwiązać teraz problem rozpoznawania elementów, na które trafiamy przy odczytywaniu dokumentu. Na pewno będą to nagłówki, akapity, style znakowe, listy, elementy list. To na początek, a ten zbiór jest o wiele pojemniejszy. Od tego, jaki fragment dokumentu analizujemy, zależeć będzie jego zapis po przekonwertowaniu. Dla akapitu będzie to na przykład "<styl-akapitu>To <styl-znakowy-1>jest</styl-znakowy-1> test <styl-znakowy-2>projektu</styl-znakowy-2>.".

Dla zainteresowanych link do projektu na github.com