programas - manejar arraylist java
JAXB obtiene una ArrayList creada por XmlAdapter (1)
En su XmlAdapter
necesita convertir el HashMap
a una instancia de un objeto con una propiedad de List
lugar de directamente a una ArrayList
.
HashMapAdapter
package forum13163430;
import java.util.*;
import java.util.Map.Entry;
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public final class HashMapAdapter extends XmlAdapter<HashMapAdapter.AdaptedHashMap, HashMap<String, String>> {
@Override
public AdaptedHashMap marshal(HashMap<String, String> hashMap) throws Exception {
AdaptedHashMap adaptedHashMap = new AdaptedHashMap();
for(Entry<String, String> entry : hashMap.entrySet()) {
adaptedHashMap.item.add(new HashMapEntry(entry.getKey(), entry.getValue()));
}
return adaptedHashMap;
}
@Override
public HashMap<String, String> unmarshal(AdaptedHashMap adaptedHashMap) throws Exception {
HashMap<String, String> result = new HashMap<String, String>();
for(HashMapEntry entry : adaptedHashMap.item)
result.put(entry.key, entry.value);
return result;
}
public static class AdaptedHashMap {
public List<HashMapEntry> item = new ArrayList<HashMapEntry>();
}
public static class HashMapEntry {
@XmlAttribute
public String key;
@XmlValue
public String value;
public HashMapEntry() {
}
public HashMapEntry(String key, String value) {
this.key = key;
this.value = value;
}
}
}
Para más información
ACTUALIZAR
Gracias, esto funciona. Sin embargo, entonces obtengo un nivel adicional de anotación en el XML producido. ¿Hay alguna manera de evitar eso?
Si está utilizando EclipseLink MOXy como su proveedor JAXB (JSR-222) , puede aprovechar la extensión @XmlPath
para este caso de uso. Lo demostraré a continuación con un ejemplo.
Foo
En la propiedad hashmap
, además de @XmlJavaTypeAdapter
, he agregado la anotación @XmlPath de @XmlPath
. Una ruta XML de "."
indica que el niño debe organizarse en el elemento XML de los padres.
package forum13163430;
import java.util.HashMap;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.eclipse.persistence.oxm.annotations.XmlPath;
@XmlRootElement
public class Foo {
private HashMap<String, String> hashMap;
public Foo() {
this.hashMap = new HashMap<String, String>();
}
@XmlPath(".")
@XmlJavaTypeAdapter(HashMapAdapter.class)
public HashMap<String, String> getHashmap() {
return hashMap;
}
public void setHashmap(HashMap<String, String> hashMap) {
this.hashMap = hashMap;
}
}
jaxb.properties
Para especificar MOXy como su proveedor JAXB, debe incluir un archivo llamado jaxb.properties
en el mismo paquete que su modelo de dominio con la siguiente entrada (consulte: http://blog.bdoughan.com/2011/05/specifying-eclipselink- moxy-as-your.html ).
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
Manifestación
Como MOXy es una implementación compatible con JAXB (JSR-222), las API estándar se pueden usar para convertir objetos de / a XML.
package forum13163430;
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Foo.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum13163430/input.xml");
Foo foo = (Foo) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(foo, System.out);
}
}
input.xml / Salida
A continuación se muestra la entrada y salida de ejecutar el código de demostración.
<?xml version="1.0" encoding="UTF-8"?>
<foo>
<item key="b">B</item>
<item key="c">C</item>
<item key="a">A</item>
</foo>
Para más información
Quiero adaptar la representación XML de un campo HashMap
usando XmlAdapter
. Yo uso una ArrayList
para hacer eso. Sin embargo, al ordenar ArrayList
no se organiza en absoluto. ¿Porqué es eso?
El código
@XmlRootElement
public class Foo {
private HashMap<String, String> hashMap;
public Foo() {
this.hashMap = new HashMap<String, String>();
}
@XmlJavaTypeAdapter(HashMapAdapter.class)
public HashMap<String, String> getHashmap() {
return hashMap;
}
public void setHashmap(HashMap<String, String> hashMap) {
this.hashMap = hashMap;
}
}
public final class HashMapAdapter extends XmlAdapter<ArrayList<HashMapEntry>, HashMap<String, String>> {
@Override
public ArrayList<HashMapEntry> marshal(HashMap<String, String> arg0) throws Exception {
ArrayList<HashMapEntry> result = new ArrayList<HashMapEntry>();
for(Entry<String, String> entry : arg0.entrySet())
result.add(new HashMapEntry(entry.getKey(), entry.getValue()));
return result;
}
@Override
public HashMap<String, String> unmarshal(ArrayList<HashMapEntry> arg0) throws Exception {
HashMap<String, String> result = new HashMap<String, String>();
for(HashMapEntry entry : arg0)
result.put(entry.key, entry.value);
return result;
}
}
public class HashMapEntry {
@XmlElement
public String key;
@XmlValue
public String value;
public HashMapEntry() {
}
public HashMapEntry(String key, String value) {
this.key = key;
this.value = value;
}
}
El resultado
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><foo><hashmap/></foo>