2010-02-12 31 views
2

我有兩個模式A和B與循環依賴(這是一箇中間步驟)。我用作輸入的XML文件根據xmllint和Visual Studio根據模式進行驗證。 Eclipse告訴我這兩個模式包含兩個具有相同名稱的全局組件。爲什麼我的JAXB Unmarshaller找不到在導入的模式中聲明的元素?

A.xsd:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-Instance" 
    targetNamespace="http://foo.org/A" 
    xmlns="http://foo.org/A" 
    elementFormDefault="unqualified" 
    attributeFormDefault="unqualified"> 

<xs:import schemaLocation="b.xsd" /> 

B.xsd:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-Instance" 
    xmlns:foo="http://foo.org/A" 
    elementFormDefault="unqualified" 
    attributeFormDefault="unqualified"> 

    <xs:import namespace="http://foo.org/A" schemaLocation="a.xsd" /> 

我傳遞給Unmarshaller的XSD的是A.xsd。當遇到B.xsd中定義的元素時,它會投訴:

org.xml.sax.SAXParseException:cvc-elt.1:找不到元素'foo'的聲明。

我設置通過(僞)模式:

InputStream in = .. A.xsd 
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 
return factory.newSchema(new StreamSource(in); 

任何人都可以解釋我做錯了嗎?謝謝。

+0

查看編輯答案 – skaffman 2010-02-12 14:51:33

回答

1

<xs:import>用於將在其他架構中定義的名稱空間導入到當前架構中。 schemaLocation屬性不過是提示在哪裏可以找到其他名稱空間。

如果是B.xsd,則表示要導入名稱空間http://blah.org,並且該名稱空間由A.xsd中的架構處理。

A.xsd的情況下,您導入的B.xsd未指定要導入的命名空間。

如果A.xsdB.xsd表示不同的名稱空間,那麼import需要明確指定。

另一方面,如果您只是試圖從另一個模式文件內嵌入相同名稱空間中的元素,則include指令更合適。


編輯: OK,見過你的模式片段,我可以說,<xs:import>絕對不是做正確的事。 A.xsdB.xsd都是在相同名稱空間(http://foo.org/A)中定義的元素,因此您應該使用<xs:include>來代替。

當Java遇到<xs:import>,並且該導入的名稱空間是它已知的名稱空間時,它將有效地忽略它。因爲它解析了B.xsd(在命名空間http://foo.org/A中),並且它爲該同一名稱空間找到一個導入,它將忽略它。

+0

感謝您的回覆。我通過顯示我的元素是如何定義的,給我的問題添加了詳細信息。 – Elliot 2010-02-12 14:46:02

相關問題