2012-01-06 14 views
6

Soy un poco nuevo en JAXB y la validación, y he pasado varias horas tratando de resolver este problema en vano. Creé un ejemplo simple de unmarshaller de JAXB para analizar un archivo XML. También he creado un archivo XSD apropiado, pero el validador sigue quejándose de que no puede encontrar la declaración de un elemento.La validación unmarshal de JAXB arroja cvc-elt.1: No se puede encontrar la declaración de error de elemento

Creo que puede estar relacionado con problemas de espacio de nombres, pero he intentado todo lo que puedo pensar y todavía parece que no puede resolver el error. Por lo que puedo decir, mi XSD y XML son adecuados, por lo que puede tener que ver con la forma en que estoy instanciando el unmarshaller, pero parece que no puedo encontrar el problema en ninguna parte.

El error/excepción sigo recibiendo es:

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 

Éstos son los archivos de origen que están causando el error.

Código 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> 

He intentado tanto con y sin la última definición de elemento en el XSD (es decir, : xsd: element name = "calculateBorrowingDataResponse" ...) pero ninguno funciona.

Me estoy quedando sin ideas de diferentes cosas para probar. ¡Cualquier sugerencia o recomendación sería muy apreciada!

+0

¿Creó sus clases JAXB a mano o con XJC? Además, ¿a qué * SimpleType.xsd * hace referencia? Sin esta información es difícil ejecutar una prueba rápida. –

+0

Sí - Genere las clases con XJC. De hecho, probé tanto con XJC como con el plugin eclipse (usando jaxb-2.1.9-osgi de maven central como mi implementación jaxb en mi pom). Recibo el mismo error en ambos sentidos. He editado mi pregunta anterior y reemplazado el esquema XSD original con una nueva versión que incluye los tipos relevantes de SimpleType.xsd para que solo haya un archivo de esquema y ya no dependa de SimpleType.xsd. Sin embargo, para mayor claridad, dejé el identificador de espacio de nombre original. –

+0

También he editado mi publicación para agregar la definición de mis datos de muestra calculateBorrowingDataResponse.xml. –

Respuesta

22

Esta es la cuarta hora que estoy tratando de encontrar el origen del problema. Después de mucha lucha, ahora, estoy seguro de que te está faltando una sola línea del código para poder ascender a alturas gloriosas!

El problema es que DocumentBuilderFactory creado a través de DocumentBuilderFactory.newInstance()por defecto no está al tanto de espacio de nombres Sí.

Usted puede superar esto de dos maneras:

  1. hacer su DocumentBuilderFactory espacio de nombres de cuenta:

    DocumentBuilderFactory.setNamespaceAware(true);

  2. o utilizar un StreamSource mientras unmarshalling y soltar los y sus pequeños amigos DocumentBuilder completo :

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

En caso de la segunda opción, debe hacerlo así.

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

Por cierto, en este esquema -conciencia-dad-document-builderness-genialidad hay un montón información en la sección superior de la Unmarshaller class' documentation, debería comprobar que fuera!

+0

Wow. Muchas gracias por haber pasado tanto tiempo en esto. Pasé más de 8 horas en esto, pero nuevamente fue mi problema resolverlo en primer lugar. Si pudiera votarte más, lo haría. :) Creo que llegué a la misma conclusión al mismo tiempo; No me había dado cuenta de que DocumentBuilderFactory no era consciente del espacio de nombres de forma predeterminada, y además, no tenía idea de que marcaría una gran diferencia. Me enteré cuando encontré una clase llamada DOMUtils (http://www.java2s.com/Code/Java/XML/ComparetwoDOMNodes.htm) que me dio seguimiento. –

+1

@EricB. No me había dado cuenta de que DocumentBuilderFactory no era consciente del espacio de nombres de forma predeterminada, y además, no tenía idea de que marcaría una gran diferencia. Yo tampoco, sin embargo, fue una buena lección para nosotros, para que verifiquemos los documentos más a fondo en el futuro. :) –

+0

Gracias por toda la ayuda. Desafortunadamente, mis problemas con JaxB continúan; vena similar, pero problema diferente. Esta vez, mi generación de esquema de mis clases generadas JAXB está incompleta. Cualquier sugerencia sera apreciada. Creé un nuevo hilo ya que es un problema diferente. http://stackoverflow.com/questions/8809406/jaxbcontext-generating-incomplete-schemas –

Cuestiones relacionadas