2011-12-07 13 views
4

以下は、私が現時点で何を試みているのかを示すコードの一部ですが、その信頼性はありません。 Princimaply私は と考えています。プロトコルハンドラを一度しか登録することができず、他のライブラリが最初にこれを実行していることがあります。クラスパスリソース(jar内)からXMLCatalogを確実にロードするにはどうすればいいですか?

import org.apache.xerces.util.XMLCatalogResolver; 



public static synchronized XMLCatalogResolver getResolver() { 
     String c[] = {"classpath:xml-catalog.xml"}; 
     if (cr==null) { 

      log.debug("Registering new protcol handler for classpath"); 
      ConfigurableStreamHandlerFactory configurableStreamHandlerFactory = new ConfigurableStreamHandlerFactory("classpath", new org.fao.oek.protocols.classpath.Handler(XsdUtils.class.getClassLoader())); 
      configurableStreamHandlerFactory.addHandler("http", new sun.net.www.protocol.http.Handler()); 


      URL.setURLStreamHandlerFactory(configurableStreamHandlerFactory); 

      log.debug("Creating new catalog resolver"); 

     cr = new XMLCatalogResolver(c); 

     } 
     return cr; 
    } 

XML-catalog.xmlには含まれています

<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog"> 
<group prefer="public" xml:base="classpath:org/me/myapp/xsd/" > 
    <uri name="http://www.w3.org/XML/1998/namespace" uri="xml.xsd"/> 
    <uri name="http://www.w3.org/1999/xlink" uri="xlink.xsd" /> 
    <uri name="http://www.w3.org/2001/XMLSchema" uri="XMLSchema.xsd" /> 
    <uri name="http://purl.org/dc/elements/1.1/" uri="dc.xsd" /> 
    <uri name="http://www.loc.gov/mods/v3" uri="mods-3.3.xsd" /> 
</group> 
</catalog> 

を明らかに - XSDファイルをクラスパスに正しい場所に存在します。

答えて

3

リゾルバがコードの次の最小セットで正しく行動:あなたが代わりにJVM引数としてjava.protocol.handler.pkgsを指定することができ

public class XsdUtils { 
    static { 
     System.setProperty("java.protocol.handler.pkgs", "org.fao.oek.protocols"); 
    } 

    private static XMLCatalogResolver cr; 

    public static synchronized XMLCatalogResolver getResolver() { 
     if (cr == null) { 
      cr = new XMLCatalogResolver(new String[] { "classpath:xml-catalog.xml" }); 
     } 
     return cr; 
    } 

    public static void main(String[] args) throws MalformedURLException, IOException { 
     XMLCatalogResolver resolver = getResolver(); 
     URL url0 = new URL("classpath:xml-catalog.xml"); 
     URL url1 = new URL(resolver.resolveURI("http://www.loc.gov/mods/v3")); 
     url0.openConnection(); 
     url1.openConnection(); 
    } 
} 

次のよう

java -Djava.protocol.handler.pkgs=org.fao.oek.protocols ... 

Handlerクラスが実施された:

package org.fao.oek.protocols.classpath; 

import java.io.IOException; 
import java.net.URL; 
import java.net.URLConnection; 

public class Handler extends java.net.URLStreamHandler { 
    @Override 
    protected URLConnection openConnection(URL u) throws IOException { 
     String resource = u.getPath(); 
     if (!resource.startsWith("/")) resource = "/" + resource; 
     System.out.println(getClass().getResource(resource)); 
     return getClass().getResource(resource).openConnection(); 
    } 
} 

havこのスタックオーバーフロー質問で答えとして、電子スラッシュ("/")リソースを要求し、:​​

XsdUtilsmain方法。 xml-catalog.xmlmods-3.3.xsdがクラスパス上ではなく、JARにあるプログラムへの出力は次のとおりです。

file:/workspace/8412798/target/classes/xml-catalog.xml 
file:/workspace/8412798/target/classes/org/me/myapp/xsd/mods-3.3.xsd 

ファイルはJARにあるプログラムの出力は次のようになりますに関しては

jar:file:/workspace/8412798/target/stackoverflow.jar!/xml-catalog.xml 
jar:file:/workspace/8412798/target/stackoverflow.jar!/org/me/myapp/xsd/mods-3.3.xsd 

元の質問では、このコードに:あなたはあなたのAPを設定していない限り

new org.fao.oek.protocols.classpath.Handler(XsdUtils.class.getClassLoader()) 

あなたHandlerは、特定のクラスローダを必要としません。 1つのような特別なクラスローダーを使用するplicationは、URLClassLoaderから拡張されました。

"A New Era for Java Protocol Handlers"は、プロトコルハンドラに関する優れたリソースです。

次のクラスでは、すべてを丸で囲むだけで、XsdUtils.getResolver()を使用してXMLを解析します。 XMLCatalogResolverに指定されたスキーマに対して検証します。

public class SampleParser { 
    public static void main(String[] args) throws Exception { 
     String xml = "<?xml version=\"1.0\"?>" + // 
       "<mods ID=\"id\" version=\"3.3\" xmlns=\"http://www.loc.gov/mods/v3\">" + // 
       "<titleInfo></titleInfo>" + // 
       "</mods>"; 
     ByteArrayInputStream is = new ByteArrayInputStream(xml.getBytes()); 
     XMLReader parser = XMLReaderFactory.createXMLReader(org.apache.xerces.parsers.SAXParser.class.getName()); 
     parser.setFeature("http://xml.org/sax/features/validation", true); 
     parser.setFeature("http://apache.org/xml/features/validation/schema", true); 
     parser.setFeature("http://apache.org/xml/features/validation/schema-full-checking", true); 
     parser.setProperty("http://apache.org/xml/properties/internal/entity-resolver", XsdUtils.getResolver()); 
     parser.setErrorHandler(new ErrorHandler() { 
      @Override 
      public void error(SAXParseException exception) throws SAXException { 
       System.out.println("error: " + exception); 
      } 

      @Override 
      public void fatalError(SAXParseException exception) throws SAXException { 
       System.out.println("fatalError: " + exception); 
      } 

      @Override 
      public void warning(SAXParseException exception) throws SAXException { 
       System.out.println("warning: " + exception); 
      } 
     }); 
     parser.parse(new InputSource(is)); 
    } 
} 
関連する問題