Dobry parser XML z mapowaniem

Problem wygląda następująco:
Mam dokument xml, który chcę przekonwertować do hasha lub obiektu. Problem w xml jest taki, że czasami tag może wystąpić tylko raz a w innym przypadku kilka razy.

Przejrzałem kilka bibliotek i nie znalazłem dobrej biblioteki do parsowania/mapowania. A więc po kolei:

HTTParty - parser w tym gemie działa tak, że jeśli tag występuje raz to mapuje go na hash a jak występuje wielokrotnie to robi tablicę. Co prowadzi do nieścisłości, bo raz możemy otrzymać hash dla danego pola a raz tablicę

Happymapper - to jest mniej więcej to czego szukam, ale gem ten ma problemy z mapowaniem zagnieżdżonych elementów np.:

<a><b><a></a></b></a>

Po mapowaniu wyjdzie tak, że mamy dwa tagi a na pierwszym poziomie, co nie jest prawdą

Patrzyłem też na inne gem, ale większość używa nokogiri, a mam jakieś wrażenie, że nokogiri, działa dużo wolniej

W prostych parserach XML nie da się ustawić, że jakieś pole ma być zawsze tablicą), a te bardziej skomplikowane nie zawsze chcą działać prawidłowo.

Czego używanie do parsowania XML i jak radzicie sobie z sytuacją, gdy pole może występować wielokrotnie, a w dokumencie XML występuje tylko raz ?

używałem Nori. Ma pewne problemy, ale są do obejścia.

Co do zamiany kilku tagów na tablicę - tego nie przeskoczysz. Parser sam nie odgadnie że pojedynczy element powinien być tablicą, ew. możesz mu pomóc przez zadeklarowanie typu (<tag type="array"></tag> ).

W przypadku Nori możesz dopisać własną wersję parsera XML (domyślne są Nokogiri i REXML), wtedy na poziomie parsowania zanim tag trafi do Nori możesz mu dopisać potrzebne atrybuty. Ale to nie będzie eleganckie na dłuższą metę. Najbezpieczniej jest się z tym pogodzić i oprogramować przypadek że w hashu może wystąpić tablica.

Największy problem jaki napotkałem w Nori to parsowanie niektórych elementów jako string (edge case), tj. zamiast pełnego hasha możesz dostać wynik typu { :root => "<whole><xml><as><string/></as></xml></whole>"} (swoją drogą it’s a feature, not a bug).

Nori jest chyba najlepszym gemem, niestety nie podoba mi się, że ustawia masę zmiennych, i wygląda to okropnie.

Teraz skłaniam się nad prostym parsowaniem xml -> hash, a następnie przepuszczenie przez jakąś klasę/metodę transformującą. To rozwiązanie chyba jest najlepsze, gdyż węzły w tym xmlu nie do końca są udokumentowane (na tą chwilę jakaś dokumentacja zdawkowa jest, ale co jakiś czas pojawiają się nowe węzły)

Dzięki za pomoc

Z mojej strony mogę polecić https://github.com/ohler55/ox, dużo szybszy od nokogiri.