2012-01-06 7 views
6

JAXB ve doğrulama konusunda yeni bir bilgim var ve bu sorunu çözmek için birkaç saat harcadım. Bir XML dosyasını ayrıştırmak için basit bir JAXB unmarshaller örneği oluşturdum. Uygun bir XSD dosyası da oluşturdum, ancak doğrulayıcı, bir öğenin bildirimini bulamadığı konusunda şikâyette bulunuyor.JAXB unmarshal validation, cvc-elt.1'i atar: Öğe hatası bildirimi bulamıyor

Ad alanı sorunları ile ilgili olabileceğini düşünüyorum, ancak düşünebildiğim her şeyi denedim ve hala hatayı çözemiyorum. Anlayabildiğim kadarıyla, benim XSD ve XML'im uygun, bu yüzden, imkansızlaştırıcıyı yaratma yolumla ilgili olarak yapmak zorunda kalabilirim, fakat sorunu herhangi bir yerde bulamıyorum.

ben almaya devam hata/istisnadır: Burada

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 

hataya neden olan kaynak dosyalarıdır.

Java Kodu:

// 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> 

ben ve XSD son öğe tanımı olmadan hem çalıştı (yani : xsd: element name = "calculateBorrowingDataResponse" ...) ama ne işe yaramaz.

Denemek istediğim farklı şeyler hakkında fikirlerim tükendi. Herhangi bir öneri veya tavsiyeniz büyük ölçüde takdir edilecektir!

+0

JAXB sınıflarınızı el ile mi yoksa XJC ile mi oluşturdunuz? Ayrıca, referans ettiğiniz * SimpleType.xsd * nedir? Bu bilgiler olmadan hızlı bir test yapmak zor. –

+0

Evet - Sınıfları XJC ile oluşturdum. Ben aslında XJC ve eclipse eklentisi ile (pom içinde jaxb uygulama olarak maven merkezinden jaxb-2.1.9-osgi kullanarak) çalıştım. Aynı hatayı her iki şekilde de alıyorum. Yukarıdaki soruyu düzenledim ve orijinal XSD şemasını, SimpleType.xsd dosyasından ilgili türleri içeren yeni bir sürümle değiştirdim, böylece yalnızca bir şema dosyası var ve artık SimpleType.xsd'de bağımlılık olmayacak. Sadece netlik için, orijinal isim alanı tanımlayıcısını bıraktım. –

+0

Ayrıca, calculateBorrowingDataResponse.xml örnek verileri için tanım eklemek üzere yayınımı düzenledim. –

cevap

22

Bu, sorunun kaynağını bulmaya çalıştığım dördüncü saattir. Çok mücadele ettikten sonra, şimdi, görkemli zirvelere yükselebilmek için tek satırlık kodu kaçırdığına eminim!

sorun varsayılan tarafından DocumentBuilderFactory.newInstance() aracılığıyla oluşturulan DocumentBuilderFactory farkında -Evet ad alanı olmamasıdır.

  1. farkında senin DocumentBuilderFactory ad yapmak:

    Bunu iki şekilde üstesinden gelinebilir

    DocumentBuilderFactory.setNamespaceAware(true);

  2. veya unmarshalling ederken StreamSource kullanmak ve tamamen DocumentBuilder ve onun küçük arkadaş damla :

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

İkinci seçenek durumunda bunu böyle yapmalısınız.Bu şema farkındalık-lik-belge-builderness-harikaları üzerinde

arada
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); 

, , kesinlikle o Unmarshaller class' documentation üst bölümünde bir çok bilgileri kontrol etmelidir var!

+0

Vay. Bu konuda çok zaman geçirdiğiniz için çok teşekkür ederim. Bu konuda 8+ saat harcadım ama sonra tekrar çözmek benim problemim oldu. Eğer daha fazlasını yapabilirsem, yapardım. :) Sanırım aynı zamanda aynı sonuca vardım; DocumentBuilderFactory'nin ad alanı varsayılan olarak bilinmediğini fark etmemiştim, ayrıca bunun böyle bir fark yaratacağı konusunda hiçbir fikrim yoktu. Beni bulamadığı DOMUtils (http://www.java2s.com/Code/Java/XML/ComparetwoDOMNodes.htm) adlı bir sınıf bulduğumda ipucunu aldım. –

+1

@ EricB. _Ben, DocumentBuilderFactory ad alanının varsayılan olarak bilinmediğini fark etmemiştim, ve dahası, böyle bir fark yaratacağına dair hiçbir fikrim yoktu. Ben de, bu bizim için iyi bir dersti, bu yüzden dokümanlar daha kapsamlı bir şekilde kontrol ettik. gelecekte. :) –

+0

Yardım için teşekkürler. Maalesef JaxB sorunum devam ediyor; benzer damar, ama farklı sorun. Bu sefer, JAXB oluşturulan sınıflarımdan şema neslim eksik. Herhangi bir öneri takdir edilecektir. Farklı bir sorun olduğu için yeni bir konu oluşturdum. http://stackoverflow.com/questions/8809406/jaxbcontext-generating-incomplete-schemas –