2012-01-06 38 views
6

我對JAXB和驗證很陌生,並花了幾個小時試圖找出這個問題無濟於事。我創建了一個簡單的JAXB unmarshaller示例來解析XML文件。我也創建了一個合適的XSD文件,但驗證器一直抱怨說它無法找到元素的聲明。JAXB unmarshal驗證拋出cvc-elt.1:找不到元素錯誤的聲明

我認爲這可能與命名空間問題有關,但我試過了所有我能想到的,仍然無法解決錯誤的方法。據我所知,我的XSD和XML是正確的,所以它可能與我實例化unmarshaller的方式有關,但我似乎無法在任何地方找到問題。

錯誤/例外,我不斷收到是:

Caused by: org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'calculateBorrowingDataResponse'. 
    at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source) 
    at org.apache.xerces.util.ErrorHandlerWrapper.error(Unknown Source) 
    at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source) 
    at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source) 
    at org.apache.xerces.impl.xs.XMLSchemaValidator.handleStartElement(Unknown Source) 
    at org.apache.xerces.impl.xs.XMLSchemaValidator.startElement(Unknown Source) 
    at org.apache.xerces.jaxp.validation.ValidatorHandlerImpl.startElement(Unknown Source) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.ValidatingUnmarshaller.startElement(ValidatingUnmarshaller.java:85) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.InterningXmlVisitor.startElement(InterningXmlVisitor.java:47) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:113) 
    at com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:236) 
    at com.sun.xml.internal.bind.unmarshaller.DOMScanner.scan(DOMScanner.java:119) 
    at com.sun.xml.internal.bind.unmarshaller.DOMScanner.scan(DOMScanner.java:102) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:299) 
    ... 2 more 

下面是導致該錯誤的源文件。

Java代碼:

// We need a Document 
InputStream is = UnmarshalTest.class.getClassLoader().getResourceAsStream("calculateBorrowingDataResponse.xml"); 
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
DocumentBuilder db = dbf.newDocumentBuilder(); 
Node node = db.parse(is); 

// Creating an unmarshaller 
Unmarshaller u = JAXBContext.newInstance(CalculateBorrowingDataResponseType.class).createUnmarshaller(); 

// Setting the Validation 
Schema schema; 
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 
schema = schemaFactory.newSchema(new File("src/main/webapp/WEB-INF/wsdl/CalculateBorrowingDataResponse.xsd")); 
u.setSchema(schema); 
u.unmarshal(node, CalculateBorrowingDataResponseType.class); 

CalculateBorrowingDataResponse.xsd:

<?xml version="1.0" encoding="UTF-8"?> 
<xsd:schema 
    version="1.1" 
    attributeFormDefault="unqualified" 
    elementFormDefault="qualified" 
    targetNamespace="http://www.domain.com/ClientServices/LendingSimulation/CalculateBorrowingDataResponse" 
    xmlns:lssSt="http://www.domain.com/ClientServices/LendingSimulation/CalculateBorrowingDataResponse" 
    xmlns:cbdRes="http://www.domain.com/ClientServices/LendingSimulation/CalculateBorrowingDataResponse" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 


    <!-- CalculateBorrowingData --> 
    <xsd:complexType name="CalculateBorrowingDataResponseType"> 
     <xsd:sequence> 
      <xsd:element name="loanAgmt" type="cbdRes:LoanAgreementType" minOccurs="1" maxOccurs="1" /> 
     </xsd:sequence> 
    </xsd:complexType> 


    <xsd:complexType name="LoanAgreementType"> 
     <xsd:sequence> 
      <xsd:element name="borrowingBasedPmtAmt" type="lssSt:borrowingBasedPmtAmt" minOccurs="0" maxOccurs="1" /> 
      <xsd:element name="maxPmtAmt" type="lssSt:maxPmtAmt" minOccurs="0" maxOccurs="1" /> 
      <xsd:element name="borrowingCapacityMin" type="lssSt:borrowingCapacityMin" minOccurs="0" maxOccurs="1" /> 
      <xsd:element name="borrowingCapacityMax" type="lssSt:borrowingCapacityMax" minOccurs="0" maxOccurs="1" /> 
      <xsd:element name="propertyValueMinAmt" type="lssSt:propertyValueMinAmt" minOccurs="0" maxOccurs="1" /> 
      <xsd:element name="propertyValueMaxAmt" type="lssSt:propertyValueMaxAmt" minOccurs="0" maxOccurs="1" /> 
     </xsd:sequence> 
    </xsd:complexType> 

    <xsd:element name="calculateBorrowingDataResponse" type="cbdRes:CalculateBorrowingDataResponseType"/> 


    <xsd:simpleType name="borrowingBasedPmtAmt"> 
     <xsd:restriction base="xsd:decimal" > 
     <xsd:totalDigits value="19" /> 
     <xsd:fractionDigits value="4" /> 
     </xsd:restriction> 
    </xsd:simpleType> 
    <xsd:simpleType name="maxPmtAmt"> 
     <xsd:restriction base="xsd:decimal" > 
     <xsd:totalDigits value="19" /> 
     <xsd:fractionDigits value="4" /> 
     </xsd:restriction> 
    </xsd:simpleType> 
    <xsd:simpleType name="borrowingCapacityMin"> 
     <xsd:restriction base="xsd:decimal" > 
     <xsd:totalDigits value="19" /> 
     <xsd:fractionDigits value="4" /> 
     </xsd:restriction> 
    </xsd:simpleType> 
    <xsd:simpleType name="borrowingCapacityMax"> 
     <xsd:restriction base="xsd:decimal" > 
     <xsd:totalDigits value="19" /> 
     <xsd:fractionDigits value="4" /> 
     </xsd:restriction> 
    </xsd:simpleType> 
    <xsd:simpleType name="propertyValueMinAmt"> 
     <xsd:restriction base="xsd:decimal" > 
     <xsd:totalDigits value="19" /> 
     <xsd:fractionDigits value="4" /> 
     </xsd:restriction> 
    </xsd:simpleType> 
    <xsd:simpleType name="propertyValueMaxAmt"> 
     <xsd:restriction base="xsd:decimal" > 
     <xsd:totalDigits value="19" /> 
     <xsd:fractionDigits value="4" /> 
     </xsd:restriction> 
    </xsd:simpleType> 
</xsd:schema> 

calculateBorrowingDataResponse.xml

<?xml version="1.0" encoding="UTF-8"?> 
<calculateBorrowingDataResponse 
    xmlns="http://www.domain.com/ClientServices/LendingSimulation/CalculateBorrowingDataResponse" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:ns2="http://www.domain.com/ClientServices/LendingSimulation/V1.1"> 
    <loanAgmt> 
     <borrowingBasedPmtAmt>1231231</borrowingBasedPmtAmt> 
     <maxPmtAmt>987654321</maxPmtAmt> 
     <borrowingCapacityMax>99999</borrowingCapacityMax> 
    </loanAgmt> 
</calculateBorrowingDataResponse> 

我既沒有在XSD的最後一個元素定義嘗試(即:xsd:element name =「calculateBorrowingDataResponse」...)但都不起作用。

我正在用盡不同想法的想法嘗試。任何建議或建議將不勝感激!

+0

您是用手還是用XJC創建了JAXB類?此外,您正在引用的* SimpleType.xsd *是什麼?沒有這些信息,很難進行快速測試。 – 2012-01-08 07:09:21

+0

是的 - 我用XJC生成類。我實際上嘗試過使用XJC和eclipse插件(使用maven central的jaxb-2.1.9-osgi作爲我的pom中的jaxb實現)。兩種方式我都有同樣的錯誤。 我編輯了上面的問題,並用包含SimpleType.xsd中相關類型的新版本替換原始XSD架構,以便只有一個架構文件並且不再依賴SimpleType.xsd。但爲了清楚起見,我留下了原始的名稱空間標識符。 – 2012-01-09 17:56:00

+0

我也編輯了我的帖子,爲我的calculateBorrowingDataResponse.xml示例數據添加了定義。 – 2012-01-09 18:03:07

回答

22

這是第四個小時,我試圖找到問題的根源。經過很多努力,現在,我相信你錯過了單行代碼才能夠崛起到輝煌的高度!

問題在於DocumentBuilderFactory默認通過DocumentBuilderFactory.newInstance()創建不支持名稱空間 -yeah。

您可以通過兩種方式解決此問題:

  1. 讓你DocumentBuilderFactory感知名稱空間:

    DocumentBuilderFactory.setNamespaceAware(true);

  2. 或使用StreamSource進行解和完全放棄了DocumentBuilder和他的小夥伴們:

    Unmarshaller.unmarshal(StreamSource, Class<T>);

在第二選擇的情況下,你要這樣做。

InputStream xsdStream = ... 
InputStream xmlStream = ... 

SchemaFactory f = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 
Schema s = schemaFactory.newSchema(xsdStream); 

JAXBContext c = JAXBContext.newInstance(CalculateBorrowingDataResponseType.class); 
Unmarshaller u = c.createUnmarshaller(); 
u.setSchema(schema); 
CalculateBorrowingDataResponseType b = 
    u.unmarshal(new StreamSource(xmlStream), CalculateBorrowingDataResponseType.class); 

順便說一句,在這個架構意識岬 - 文檔builderness-迷死有在Unmarshaller class' documentation的頂部一個很多信息,你一定要檢查出來!

+0

哇。非常感謝你花了這麼多時間。我花了8個小時以上,但這又是我首先解決的問題。如果我能夠更多地讚揚你,我會的。 :)我想我在同一時間得出了同樣的結論;我沒有意識到DocumentBuilderFactory默認情況下不是名稱空間,而且我也不知道它會產生這樣的差異。當我找到一個叫做DOMUtils的類(http://www.java2s.com/Code/Java/XML/ComparetwoDOMNodes.htm)來引導我時,我被提到了。 – 2012-01-10 19:06:33

+1

@EricB。 _我沒有意識到DocumentBuilderFactory默認情況下不是名稱空間,而且我也不知道它會產生這樣的差異。我也不知道,但這對我們來說是一個很好的教訓,所以我們會更徹底地檢查文檔在將來。 :) – 2012-01-10 19:26:57

+0

感謝您的幫助。不幸的是,我的JaxB問題仍在繼續;類似的脈絡,但不同的問題。這一次,我的JAXB生成的類生成的模式不完整。任何建議,將不勝感激。我創建了一個新線程,因爲它是一個不同的問題。 http://stackoverflow.com/questions/8809406/jaxbcontext-generating-incomplete-schemas – 2012-01-10 19:36:13

相關問題