2012-05-23 19 views
7

que estoy tratando de hacer lo contrario de: JAXB - Ignore elementerror JAXB en elementos no asignada

Es decir que estoy tratando de analizar XML con JAXB a un POJO y quiero JAXB a fallar si lo hace NO encuentra una propiedad Java correspondiente para un elemento dado. Sé que probablemente podría hacer la validación del esquema, pero preferiría no hacerlo.

Ejemplo:

@XmlRootElement(name="Dog") 
public class Dog { 
    private String name; 
    public String getName() {return name;} 
    public String setName(String name) {this.name = name}; 
} 

Este XML fallaría:

<Dog> 
<id>blah</id> 
<name>Stuff</name> 
</Dog> 

Debido a que no hay ninguna propiedad id Java

+0

No sé si se puede lograr que el uso de jaxb. Sin embargo, este es el comportamiento predeterminado de XStream. – tibtof

+0

Es más para fines de prueba de la unidad. Probablemente solo tenga que usar XmlUnit, descomponer el XML y luego volver a marcarlo y comparar qué es lo que hice en el pasado. –

Respuesta

0

La única manera que he podido validar falta de propiedades de Java (w/o schema) es desempaquetar el XML en mi POJO, luego volver a colocarlo en XML usando el mismo POJO y comparar.

A continuación se muestra un ejemplo que utiliza XMLUnit que ayuda a ignorar los problemas de orden y espacio en blanco.

@Test 
public void testSerialization() throws Exception { 
    XMLUnit.setIgnoreWhitespace(true); 

    EventSearchResults r = 
      JAXB.unmarshal(getClass().getResourceAsStream("/EventSearchResults.xml"), 
        EventSearchResults.class); 
    StringWriter sw = new StringWriter(); 
    JAXB.marshal(r, sw); 
    String expected = 
      IOUtils.toString(getClass().getResourceAsStream("/EventSearchResults.xml"), "UTF-8"); 
    String actual = sw.toString(); 
    //System.out.println(expected); 
    System.out.println(actual); 
    assertXMLEqual(expected, actual); 
} 

Esto no es ideal, pero en su mayor parte funciona para pruebas unitarias.

3

Puede aprovechar un ValidationEventHandler para obtener el comportamiento que está buscando. Un elemento inesperado se trata como una advertencia que se ignora por defecto. Para respaldar su caso de uso, puede suministrar un ValdidationEventHandler que falle en las advertencias (consulte a continuación).

demostración

package forum10721257; 

import java.io.File; 
import javax.xml.bind.*; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Dog.class); 

     File xml = new File("src/forum10721257/input.xml"); 
     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     unmarshaller.setEventHandler(new ValidationEventHandler() { 

      @Override 
      public boolean handleEvent(ValidationEvent event) { 
       return false; 
      } 

     }); 
     Dog dog = (Dog) unmarshaller.unmarshal(xml); 
    } 

} 

JAXB RI Excepción

Exception in thread "main" javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"id"). Expected elements are <{}name> 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:647) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:243) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:238) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:105) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.childElement(Loader.java:90) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.StructureLoader.childElement(StructureLoader.java:236) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:483) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:465) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:135) 
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:506) 
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:376) 
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2715) 
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:607) 
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:116) 
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:488) 
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:835) 
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:764) 
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:123) 
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1210) 
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:568) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:202) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:174) 
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157) 
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:162) 
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:171) 
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:189) 
    at forum10721257.Demo.main(Demo.java:26) 

EclipseLink JAXB (moxy)

Recientemente hemos añadido a este comportamiento moxy. Tendrá que usar EclipseLink 2.4.0 o 2.3.3. Una acumulación de todas las noches se puede obtener de la siguiente ubicación:


ACTUALIZACIÓN

que necesitaba para modificar la clase Dog de su pregunta. Debajo está lo que utilicé.

perro

package forum10721257; 

import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement(name="Dog") 
public class Dog { 
    private String name; 
    public String getName() {return name;} 
    public void setName(String name) {this.name = name;} 
} 
+1

Hmm Lo intenté y no funcionó (concedió que no era MOXy).Tendré que intentarlo de nuevo. Por cierto, acabo de utilizar su truco para elementos XML dinámicos: http://blog.bdoughan.com/2012/02/xmlanyelement-and-xmladapter.html. Te mueves cuando se trata de JAXB :) –

+0

Corrí este código exacto en JDK 1.7.0 (para Mac) para obtener la excepción que publiqué. ¿Qué versión del JDK estás usando? –

+0

JDK 1.6 Lo intentaré de nuevo en breve. Creo que fue porque la forma en que estaba haciendo el contexto. –

Cuestiones relacionadas