2016-09-21 45 views
2

我想驗證使用多個名稱空間的XML文檔。我想在主命名空間的文檔中嵌入輔助命名空間的標籤。主/主名稱空間不「知道」擴展名/輔助名稱空間。使用Java中的多個名稱空間驗證XML

的test.xml

<?xml version="1.0" encoding="UTF-8"?> 
<book 
    xmlns ="MyMain_FPI" 
    xmlns:ns2="MyExtension_FPI" 
    > 
    <ns2:playmusic/> 
    <chapter/> 
    <chapter/> 
</book> 

進行驗證的Java代碼如下:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
factory.setNamespaceAware(true); 

SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 
Schema schema = schemaFactory.newSchema(new Source[] { 
    new StreamSource(new FileInputStream("main.xsd")), 
    new StreamSource(new FileInputStream("extension.xsd")), 
}); 
factory.setSchema(schema); 

DocumentBuilder builder = factory.newDocumentBuilder(); 

Document doc = builder.parse(new File("test.xml")); 

正如你所看到的,我直接的XSD文件添加到的DocumentBuilderFactory。 這些文件是:

main.xsd

<xs:schema 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns="MyMain_FPI" 
    targetNamespace="MyMain_FPI" 
    elementFormDefault="qualified"> 
    <xs:element name="book"> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element maxOccurs="unbounded" ref="chapter"/> 
     </xs:sequence> 
    </xs:complexType> 
    </xs:element> 
    <xs:element name="chapter"> 
    <xs:complexType/>  
    </xs:element> 
</xs:schema> 

extension.xsd

<xs:schema 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns="MyExtension_FPI" 
    targetNamespace="MyExtension_FPI" 
    elementFormDefault="qualified"> 
    <xs:element name="playmusic"> 
    </xs:element> 
</xs:schema> 

上面執行代碼時,我得到的錯誤是

[Error] test.xml:6:18: cvc-complex-type.2.4.a: Ungültiger Content wurde beginnend mit Element 'ns2:playmusic' gefunden. '{"MyMain_FPI":chapter}' wird erwartet. 

含義,這在主命名空間中是意外的 - 這是可以理解的,因爲該元素本身在該命名空間中是未知的。我期望擴展命名空間的元素在將文檔再次驗證爲主命名空間時被忽略,反之亦然 - 這意味着我可以在主命名空間內的擴展命名空間後面嵌入文檔。但這顯然不起作用。

我錯過了什麼?

+1

你的XSD說,你的「書」元素有「章」元素的列表。您試圖放入不同的元素。我不確定你的問題是什麼。你想知道如何重寫'main.xsd'來允許playmusic? –

+0

我認爲可以在不重寫'main.xsd'的情況下驗證文檔。兩個XSD都沒有真正相關。 我假設我可以編寫一個結合了兩個XSD的XSD,但這很煩人,因爲我的真實應用程序可能有幾個可能存在或不存在的擴展XSD - 並且該列表可能會繼續。 (把它看作是一種插件的嵌入式子文檔)。 我的問題是,如果有任何方法來驗證這一點,以便驗證器不會抱怨extension.xsd – taranion

回答

1

您的main.xsd明確表示book元素允許的內容。如果你想允許任何額外的元素,你需要在main.xsd中聲明。之後你可以添加任何你想要的擴展XSD。見https://www.w3.org/TR/xmlschema-0/#any

新main.xsd

<xs:schema 
xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns="MyMain_FPI" 
targetNamespace="MyMain_FPI" 
    elementFormDefault="qualified"> 
<xs:element name="book"> 
    <xs:complexType> 
    <xs:sequence> 
     <xs:any minOccurs="0" maxOccurs="unbounded" /> 
     <xs:element maxOccurs="unbounded" ref="chapter"/> 
    </xs:sequence> 
    </xs:complexType> 
</xs:element> 
<xs:element name="chapter"> 
    <xs:complexType/>  
</xs:element> 
</xs:schema> 
+0

的元素謝謝。儘管未知(在main.xsd中)元素出現在文檔樹中,但ANY元素是保持主XSD不知道可能的擴展並仍然有效的良好折衷。這樣我只需要在'main.xsd'中定義可能的擴展點。 – taranion