2010-06-07 90 views
9

我想根據XSD模式驗證XML文件。 XML文件根元素沒有任何名稱空間或xsi詳細信息。它沒有屬性,所以只有<root>對xml進行Java xsd驗證,但沒有名稱空間

我有我收到沒有運氣試圖從http://www.ibm.com/developerworks/xml/library/x-javaxmlvalidapi.html下面的代碼 cvc-elt.1: Cannot find the declaration of element 'root'

SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema"); 

File schemaFile = new File("schema.xsd"); 

Schema xsdScheme = factory.newSchema(schemaFile); 

Validator validator = xsdScheme.newValidator(); 

Source source = new StreamSource(xmlfile); 

validator.validate(source); 

的XML驗證精細與命名空間標題包括等(通過XMLSpy的增加),但我已經想好了XML可以聲明名稱空間而無需手動編輯源文件?

編輯和解決方案:

public static void validateAgainstXSD(File file) { 

    try { 
     SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema"); 

     File schemaFile = new File("path/to/xsd"); 

     Schema xsdScheme = factory.newSchema(schemaFile); 

     Validator validator = xsdScheme.newValidator(); 

     SAXSource source = new SAXSource(
       new NamespaceFilter(XMLReaderFactory.createXMLReader()), 
       new InputSource(new FileInputStream(file))); 

     validator.validate(source,null); 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

} 

protected static class NamespaceFilter extends XMLFilterImpl { 

    String requiredNamespace = "namespace"; 

    public NamespaceFilter(XMLReader parent) { 
     super(parent); 
    } 

    @Override 
    public void startElement(String arg0, String arg1, String arg2, Attributes arg3) throws SAXException { 
     if(!arg0.equals(requiredNamespace)) 
      arg0 = requiredNamespace; 
     super.startElement(arg0, arg1, arg2, arg3); 
    }  
} 

回答

2

你有兩個單獨的關注,你需要照顧:

  1. 聲明,你的文檔使用的命名空間。
  2. 在文件中添加一個xsi:schemaLocation屬性,以提示模式所在的提示(!)

您可以安全地跳過第二部分,因爲該位置實際上只是一個提示。你不能跳過第一部分。 XML文件中聲明的名稱空間與模式匹配。重要的是,這樣的:

<xml> ... </xml> 

不一樣就象這樣:

<xml xmlns="urn:foo"> ... </xml> 

所以你需要聲明的命名空間中的XML文檔中,否則將不符合你的架構和你會得到這個錯誤。

+1

xml文檔是由第三方創建的,它們可能沒有添加正確的名稱空間,在驗證之前,java中是否有方法可以輕鬆地將此名稱空間附加到根xml元素? – 2010-06-08 12:14:12

+2

您可以對此做兩件事:1.如果您知道自己在做什麼,並且格式非常靜態或更好,請使用字符串操作插入它2.創建SAX過濾器以更改命名空間(請參閱http:// www.saxproject.org/filters.html),並將過濾器傳遞給Validator。我沒有嘗試過使用Validator對象,但希望它能起作用。 – xcut 2010-06-08 12:43:03

+1

謝謝xcut。我研究了過濾器,它功能強大。對於其他人,請在上面的原始帖子中查看解決方案 – 2010-06-09 15:48:18