2012-10-26 6 views
5

Tak, nasza aplikacja analizuje dokumenty XML pobrane z usługi WWW (w szczególności PubMed). Dokumenty te deklarują DTD (an example). Domyślnie, wbrew moim naiwnym oczekiwaniom, biblioteka XML, której używamy (JDom2, zbudowany na Xerces, jak sądzę), pobiera ten DTD przed analizą dokumentu XML. Pobierania, jak w przypadku sprawia, że ​​żądanie HTTP przez Internet na podany adres.Standardowa metoda parsowania dokumentów XML bez pobierania DTD

czytając inne posty tutaj, jego moje zrozumienie, że czytanie DTD jest konieczne biorąc pod uwagę, że może on zawierać deklaracje podmiot zobowiązany do analizowania &foo; bitów w dokumencie (BTW, to jest obłęd w standardzie XML, prawda?)

Pomyślałem, że musi istnieć jakiś łatwy, standardowy, każdy, kto wie, co robi, robi, w ten sposób określając, że mam DTD lokalnie. Ale widzę tylko wzmiankę o tworzeniu katalogu XML (czarna magia) lub tworzeniu niestandardowego EntityResolver (ból w dupie).

Dla innych problemów, które napotykam, znajduję na wiosnę lub w innej bibliotece Java standardowy sposób na pokonanie ich bez dużej ilości blachy kotła. Jednak w tym przypadku mam wrażenie, że piszę dość niechlujny, kruchy kod, aby osiągnąć coś, z czym musi się zmierzyć każdy inny programista.

Jak pisać aplikacje XML, używając dobrze znanych bibliotek, które nie przesyłają ponownie żądań internetowych w celu pobrania plików, które nigdy się nie zmieniają?

PS: Odkryłem ten problem, ponieważ PubMed miał problemy z łącznością już dziś, a moje testy jednostkowe (używające wyodrębnionych dokumentów w oparciu o prawdziwe zapytania) zawodziły, gdy analizator składni XML nie mógł pobrać DTD.

PPS: Uważam, że to naprawdę zabawne, że W3C has issues with this, kiedy to one propagują standard, który praktycznie błaga o tego rodzaju nadużycia.

+0

Mam nadzieję, że otrzymasz odpowiedź na to pytanie, z wyjątkiem "dobrze ... musisz samemu wykonać to zadanie". Zawsze używam do tego niestandardowego EntityResolver. Nie znalazłem go kruchego --- dokładnie --- ale jest dużo kodu, aby zrobić prostą rzecz. –

Odpowiedz

2

Najlepszym sposobem na załadowanie DTD z innego źródła jest użycie EntityResolver, nie powinno to być zbyt dużym bólem w tylnej części. Wczytuję lokalne zasoby XML przy użyciu EntityResolver dla DOM4j i umieszczam plik wewnątrz mojego słoika, aby był łatwo dostępny za pomocą poniższego kodu.

new org.xml.sax.EntityResolver() 
{ 
    @Override 
    public InputSource resolveEntity(String publicId, String systemId) 
    { 
     if (systemId != null && systemId.equals("http://something.com/xml.dtd")) 
      return new InputSource(getClass().getResourceAsStream("../xml/local.dtd"));; 
    } 
}; 

Myślę, że jest to "standardowy" sposób.

Innym sposobem może być modyfikowanie dokumentu xml za pomocą ciągu zastępuje odniesienie dtd i wstrzykuje wszelkie odwołania Entity, które mogą być używane.

Powiązane problemy