Zamiast name.equals("lala")
znacznie lepiej pisać "lala".equals(name)
.
Jeśli name == null
w pierwszym przypadku będzie wyjątek, w drugim otrzymamy false
.
Naprawdę warto nabrać nawyku i zawsze pisać w tej kolejności.
Jeśli mamy dwie zmienne, to zawsze equals
wykonujmy na tej, o której wiemy, że nie jest null
em.
Na przykład zamiast ns == null || node.getNamespaceURI().equals(ns)
lepiej napisać
ns == null || ns.equals(node.getNamespaceURI())
.
Wyraźnie napisałem, że przetwarzanie ma być namespace aware. W dodatku schemat deklarował elementy w przestrzeni nazw (co samo powinno wskazywać, że mamy uwzględniać przestrzenie nazw).
Około połowa z Was nie sprawdzała przestrzeni nazw. Przy poprawnej obsłudze insertContent
to nie było konieczne (bo schemat zabraniał pojawiania się innych elementów), ale w przypadku braku lub błędnej implementacji,
powodowało to interpretację zagnieżdżonych elementów jako operacji (nawet jeśli były z innej przestrzeni nazw).
Kilka osób (ok. 1/5) porównywała z nazwą operacji kwalifikowaną nazwę elementu, zamiast nazwy lokalnej.
Powodowało to niedziałanie programu na pliku wejściowym z operacjami postaci op:readFromFile
.
Uznałem to za poważny błąd.
Należało poprawnie obsłużyć sytuację, gdy elementy z przestrzeni nazw operacji, w tym sam insertContent
,
znajdowały się wewnątrz operacji. Należało je sparsować do tworzonego poddrzewa, a nie wykonywać.
Aby nie kończyć zbyt szybko "trybu parsowania", można było liczyć głębokość (wszystkich lub tylko specjalnych elementów)
lub tworzone elementy ustawiać na stosie i sprawdzać czy stos jest pusty.
Niektórzy z Was niepoprawnie dodawali do drzewa DOM atrybuty (to nie są dzieci!) lub węzły tekstowe.
Zmienna powinna wskazywać zawsze na jakiś element (nie węzeł tekstowy, nie węzeł dokumentu).
W wielu rozwiązaniach operacje move...
nie zachowywały tego niezmiennika.
Co więcej, czasami operacje jednocześnie zakładały, że zawsze jesteśmy w elemencie, co powodowało błędy na dokumentach z węzłami tekstowymi.
W moveToChildren
niektórzy uwzględniali nie tylko elementy. Inni używali metody
getElementsByTagNameNS()
, która zwraca listę potomków a nie dzieci.
Niektórzy pozwalali operacji moveUp
na wejście do węzła dokumentu (#document
)
lub ustawiali wskaźnik nowych zmiennych na węzeł dokumentu. Czasami prowadziło to do błędów
w innych operacjach (np. remove
), poza tym w treści było napisane, że zmienna ma w tych
sytuacjach powinna wskazywać na element główny (z dokumentu mżna go pobrać metodą getDocumentElement()
)..
Należało walidować dokument z operacjami. W przypadku wykrycia błędu przerwać program. Niektórzy nie walidowali w ogóle, inni pisali na ekran komunikaty o błędzie, ale nie przerywali parsowania.