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 nullem.
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.