2011-08-16 8 views
5

Tengo algunos objetos que JAXB no ha eliminado de JAXB de un archivo XML. ¿Es posible que JAXB me diga o de alguna manera descubra en qué parte del archivo XML (línea y columna) proviene cada objeto?Ubicación de JAXB en el archivo para objetos no ordenados

Esta información está disponible en algún momento, porque JAXB me la proporciona durante los errores de validación del esquema. Pero me gustaría tenerlo disponible para objetos validados también.

Respuesta

9

Se podría hacer esto en JAXB aprovechando una XMLStreamReader y un Unmarshaller.Listener:

demostración

package forum383861; 

import java.io.FileInputStream; 
import java.util.HashMap; 
import java.util.Map; 

import javax.xml.bind.JAXBContext; 
import javax.xml.bind.Unmarshaller; 
import javax.xml.bind.Unmarshaller.Listener; 
import javax.xml.stream.Location; 
import javax.xml.stream.XMLInputFactory; 
import javax.xml.stream.XMLStreamReader; 

public class Demo { 

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


     XMLInputFactory xif = XMLInputFactory.newFactory(); 
     FileInputStream xml = new FileInputStream("src/forum383861/input.xml"); 
     XMLStreamReader xsr = xif.createXMLStreamReader(xml); 

     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     LocationListener ll = new LocationListener(xsr); 
     unmarshaller.setListener(ll); 

     Customer customer = (Customer) unmarshaller.unmarshal(xsr); 
     System.out.println(ll.getLocation(customer)); 
     System.out.println(ll.getLocation(customer.getAddress())); 
    } 

    private static class LocationListener extends Listener { 

     private XMLStreamReader xsr; 
     private Map<Object, Location> locations; 

     public LocationListener(XMLStreamReader xsr) { 
      this.xsr = xsr; 
      this.locations = new HashMap<Object, Location>(); 
     } 

     @Override 
     public void beforeUnmarshal(Object target, Object parent) { 
      locations.put(target, xsr.getLocation()); 
     } 

     public Location getLocation(Object o) { 
      return locations.get(o); 
     } 

    } 

} 

input.xml

<?xml version="1.0" encoding="UTF-8"?> 
<customer> 
    <address/> 
</customer> 

salida

[row,col {unknown-source}]: [2,1] 
[row,col {unknown-source}]: [3,5] 

cliente

package forum383861; 

import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement 
public class Customer { 

    private Address address; 

    public Address getAddress() { 
     return address; 
    } 

    public void setAddress(Address address) { 
     this.address = address; 
    } 

} 

Dirección

package forum383861; 

public class Address { 

} 

Para más información

+0

funcionó perfectamente, muchas gracias. Lo único ligeramente inesperado para mí es que da la ubicación del final de la etiqueta de apertura del elemento XML en lugar del comienzo de la etiqueta de apertura. Pero eso es lo suficientemente bueno para mi aplicación. – lexicalscope

2

Me temo que no. JAXB se basa en un analizador XML, este tendrá una representación lógica de su documento XML, olvidando la representación de cadena original de su documento.

El paso de validación se realiza mientras se lee la cadena, por lo que el analizador puede mostrar un mensaje de error que le indica la posición del error. JAXB solo omitirá ese mensaje de error. Pero tan pronto como el XML sea validado y analizado, solo existirá la representación lógica.

+0

Se podría aprovechar un '' XMLStreamReader' y un Unmarshaller.Listener' para obtener este tipo de apoyo: http://stackoverflow.com/questions/7079796/jaxb-location-in-file-for -unmakers-objetos/7081390 # 7081390 –

Cuestiones relacionadas