2010-06-18 2 views
7

Ich verwende die Apache-Webdienst-XML-RPC-Bibliothek, um Anforderungen an einen RPC-Dienst zu senden. Irgendwo in diesem Prozess ist ein XML-Dokument mit einer DTD-Referenz auf http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd, die die Bibliothek versucht, beim Analysieren der XML zu downloaden. Dieser Download schlägt mit einem 503-Statuscode fehl, weil der w3c wiederholte Downloads dieses weitgehend statischen Dokuments von Java-Clients blockiert.Verwenden eines XML-Katalogs mit einer Java-Bibliothek, die intern JAXP verwendet

Die Lösung ist XML-Kataloge, um die DTD lokal zwischenzuspeichern. Während ich jedoch Beispiele finden kann, um einen EntityHandler direkt in einer JAXP SAXParser-Instanz zu setzen, um die Unterstützung von Katalogparsern zu aktivieren, habe ich hier eigentlich keinen Zugriff auf den darunter liegenden Parser. Es wird nur von der XML-RPC-Bibliothek verwendet. Gibt es eine Möglichkeit, eine globale Eigenschaft oder etwas festzulegen, das JAXP XML-Kataloge verwenden wird?

Antwort

1

Ich denke, Sie möchten die Systemeigenschaft xml.catalog.files.

Werfen Sie einen Blick auf http://xml.apache.org/commons/components/resolver/resolver-article.html

BTW, dies war der dritte Treffer auf einer Google-Suche für jaxp catalog

+0

ich diesen Artikel gesehen hatte, und ich habe bereits versucht, xml-Resolver in mein Projekt zu integrieren. Das Problem ist, dass die Systemeigenschaft "xml.catalog.files" nur dann wirksam wird, wenn Sie den XML-Resolver als Entitätsresolver auf Ihrer JAXP-Leserinstanz installiert haben. Mein Problem ist, dass ich keinen Zugriff auf die JAXP-Leserinstanz habe, die intern von der Web-Service-Bibliothek verwendet wird. –

+0

Wenn Sie diese Eigenschaft beim Starten des Programms in der Befehlszeile festlegen, wird sie dann nicht von der Parser-Factory "gesehen"? –

1

Leider xml.catalog.files Einstellung hat keine Auswirkung auf den Parser Fabrik. Im Idealfall sollte dies natürlich der Fall sein, aber die einzige Möglichkeit, einen Resolver zu verwenden, besteht darin, eine Methode hinzuzufügen, die die Auflösung an den Katalogresolver in dem vom SAX-Parser verwendeten Handler delegiert.

Wenn Sie bereits einen SAX-Parser verwenden, das ist ziemlich einfach:

final CatalogResolver catalogResolver = new CatalogResolver(); 
    DefaultHandler handler = new DefaultHandler() { 
     public InputSource resolveEntity (String publicId, String systemId) { 
      return catalogResolver.resolveEntity(publicId, systemId); 
     } 
     public void startElement(String namespaceURI, String lname, String qname, 
      Attributes attrs) { 
      // the stuff you'd normally do 
     } 
     ... 
    }; 

    SAXParserFactory factory = SAXParserFactory.newInstance(); 
    factory.setNamespaceAware(true); 
    SAXParser saxParser = factory.newSAXParser(); 
    String url = args.length == 0 ? "http://horstmann.com/index.html" : args[0]; 
    saxParser.parse(new URL(url).openStream(), handler); 

Andernfalls werden Sie brauchen, um herauszufinden, ob Sie Ihr eigenes Unternehmen Resolver liefern können. Mit einem javax.xml.parsers.DocumentBuilder können Sie. Mit dem scala.xml.XML Objekt können Sie nicht, aber Sie können Ausflucht benutzen

val res = new com.sun.org.apache.xml.internal.resolver.tools.CatalogResolver 

val loader = new factory.XMLLoader[Elem] { 
    override def adapter = new parsing.NoBindingFactoryAdapter() { 
    override def resolveEntity(publicId: String, systemId: String) = { 
     res.resolveEntity(publicId, systemId) 
    } 
    } 
} 

val doc = loader.load(new URL("http://horstmann.com/index.html"))enter code here 
Verwandte Themen