2010-03-28 16 views
6

tengo el siguiente código XMLxstream analizar los atributos y valores, al mismo tiempo

<search ver="3.0"> 
    <loc id="ARBA0009" type="1">Buenos Aires, Argentina</loc> 
    <loc id="BRXX1283" type="1">Buenos Aires, Brazil</loc> 
    <loc id="ARDF0127" type="1">Aeroparque Buenos Aires, Argentina</loc> 
    <loc id="MXJO0669" type="1">Concepcion De Buenos Aires, Mexico</loc> 
    <loc id="MXPA1785" type="1">San Nicolas De Buenos Aires, Mexico</loc> 
    <loc id="ARBA0005" type="1">Balcarce, Argentina</loc> 
    <loc id="ARBA0008" type="1">Bragado, Argentina</loc> 
    <loc id="ARBA0010" type="1">Campana, Argentina</loc> 
    <loc id="ARBA0016" type="1">Chascomus, Argentina</loc> 
    <loc id="ARBA0019" type="1">Chivilcoy, Argentina</loc> 
</search> 

y una clase de Ciudad

public class City { 

    private String id; 
    private Integer type; 
    private String name; 

    // getters & setters... 
} 

He intentado lo siguiente alias para analizar el código XML

xStream.alias("search", List.class); 
xStream.alias("loc", City.class); 
xStream.useAttributeFor("id", String.class); 
xStream.useAttributeFor("type", Integer.class); 

Pero no puedo encontrar la manera de establecer el valor de la etiqueta "loc", si intento transformar el objeto City en XML obtengo

<search> 
    <loc id="ARBA0001" type="1"> 
     <name>Buenos Aires</name> 
    </loc> 
</search> 

cuando realmente lo necesito para obtener este

<search> 
    <loc id="ARBA0001" type="1">Buenos Aires</loc> 
</search> 

Entonces, si trato de analizar el código XML a un objeto City consigo el campo "Nombre" con un valor nulo.

¿Alguien sabe cómo configurar los alias correctos para hacer esto? Gracias por adelantado.

Respuesta

8

fin encontré la solución, un convertidor resuelve esto, aquí está el código

public class CityConverter implements Converter { 

    public void marshal(Object value, HierarchicalStreamWriter writer, 
                   MarshallingContext context) { 
     City city = (City) value; 
     writer.addAttribute("id", city.getId()); 
     writer.addAttribute("type", city.getType().toString()); 
     writer.setValue(city.getName()); 
    } 

    public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { 
     City city = new City(); 
     city.setName(reader.getValue()); 
     city.setId(reader.getAttribute("id")); 
     city.setType(reader.getAttribute("type")); 
     return city; 
    } 

    public boolean canConvert(Class clazz) { 
     return clazz.equals(City.class); 
    } 

} 

Y en la parte de configuración de los alias también me juego hasta la CityConverter

xStream.registerConverter(new CityConverter()); 
xStream.alias("search", List.class); 
xStream.alias("loc", City.class); 

Y todo funciona bien :)

1

XStream parece algo complicado, puede hacer lo siguiente en JAXB:

public class City { 

    @XmlAttribute private String id; 
    @XmlAttribute private Integer type; 
    @XmlValue private String name; 

    // getters & setters... 
} 
+2

Mira mi publicación en el blog comparando JAXB y XStream: http://bdoughan.blogspot.com/2010/10/how-does-jaxb-compare-to-xstream.html –

4

Estoy publicar esto con la esperanza de que podría ayudar a los demás porque me tomó bastante tiempo para encontrarlo ... http://fahdshariff.blogspot.com/2011/12/using-xstream-to-map-single-element.html

La respuesta es utilizar @XStreamConverter - ToAttributedValueConverter

@XStreamAlias("error") 
@XStreamConverter(value=ToAttributedValueConverter.class, strings={"message"}) 
public class Error { 

    String message; 

    ... 

Hay muchos convertidores interesantes que proporcionan todo tipo de funcionalidades útiles ... http://x-stream.github.io/converters.html

+0

Solución mucho más fácil, debería ser la más votada – maxivis

Cuestiones relacionadas