2011-10-03 52 views
1

我有一種情況,我們希望驗證在內存中作爲字節流保存的XML文檔,以及在文件系統中放置在其他XSD中的XSD。我們希望避免在XML文件中明確提到文件名,而是告訴XML解析器使用一個或多個XSD文件的目錄進行驗證。JAXP - 調試XSD目錄查找

我嘗試創建的DocumentBuilder提供商(對於吉斯3.0)看起來像:

public class ValidatingDocumentBuilderProvider implements 
     Provider<DocumentBuilder> { 

    static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; 
    static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema"; 
    static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource"; 

    Logger log = getLogger(ValidatingDocumentBuilderProvider.class); 

    DocumentBuilderFactory dbf; 

    public synchronized DocumentBuilder get() { // dbf not thread-safe 

     if (dbf == null) { 
      log.debug("Setting up DocumentBuilderFactory"); 

      // http://download.oracle.com/javaee/1.4/tutorial/doc/JAXPDOM8.html 
      dbf = DocumentBuilderFactory.newInstance(); 
      dbf.setNamespaceAware(true); 
      dbf.setValidating(true); 
      dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA); 
      // parser should look for schema reference in xml file 

      // Find XSD's in current directory. 

      FilenameFilter fileNameFilter = new FilenameFilter() { 

       public boolean accept(File dir, String name) { 
        return name.toLowerCase().endsWith(".xsd"); 
       } 
      }; 
      File[] schemaFiles = new File(".").listFiles(fileNameFilter); 

      dbf.setAttribute(JAXP_SCHEMA_SOURCE, schemaFiles); 

      log.debug("{} schema files found", schemaFiles.length); 
      for (File file : schemaFiles) { 
       log.debug("schema file: {}", file.getAbsolutePath()); 
      } 

     } 

     try { 
      return dbf.newDocumentBuilder(); 
     } catch (ParserConfigurationException e) { 
      throw new RuntimeException("get DocumentBuilder", e); 
     } 
    } 
} 

(我也試圖與文件名太)。 Eclipse接受XSD - 當將其放入目錄中時,它可以驗證此處處理的XML

看起來,肉眼看來,解析器在嘗試驗證時會暫時停止。這可能是網絡查找。

-Djaxp.debug=1只會增加這些線路

JAXP: find factoryId =javax.xml.parsers.DocumentBuilderFactory 
JAXP: loaded from fallback value: com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl 
JAXP: created new instance of class com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl using ClassLoader: null 

我怎樣才能在JDK 6解析器告訴我它在做什麼?如果我不能這樣做,我該如何檢查其中的XML Catalog用法,以瞭解爲什麼沒有選擇提供的XSD?

我忽視了什麼顯而易見的東西?

回答

0

你說

我們想避免在XML文件中明確提到

那麼如何將解析器能夠選擇適當的模式的文件名?

您可以嘗試的方法是使用SchemaFactory基於所有可用模式資源創建Schema,並將其附加到文檔生成器工廠。解析器會自動根據這個「超級模式」驗證文檔。

如果您的模式集具有內部依賴關係(即導入或包含),請確保使用相對URL或專用解析器正確解析這些引用。

UPDATE:

更仔細地看這篇文章,http://java.sun.com/j2ee/1.4/docs/tutorial/doc/JAXPDOM8.html,過一會兒之後,我才知道你的方法應該是我的建議同樣的效果,所以別的東西會ñ。我只能說我所描述的工作非常好。

+0

據我瞭解,每個XSD都提到了它可以驗證的命名空間。如果在XML中使用任何這些名稱空間,我希望解析器使用相應的XSD。 –