Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Cómo analizar el XML de SimpleXML

Estoy intentando analizar el XML abajo usando el análisis de SimpleXML .
He intentado en diversas maneras analizar los Attributes del Element pero incapaz de conseguir éxito en analizar el XML abajo.
Genera un error que se lista en la parte inferior.

 <prestashop xmlns:xlink="http://www.w3.org/1999/xlink"> <order> <id>1</id> <id_address_delivery xlink:href="http://abc.com/add/1">1</id_address_delivery> <id_address_invoice xlink:href="http://abc.com/add/2">2</id_address_invoice> </order> </prestashop> 

Order.java

 @Root(name="order") @Namespace(reference="http://www.w3.org/1999/xlink",prefix="xlink") public class Order { @Element(name="id",required=true) private int order_id; @Element(name="id_address_delivery",required=false) private int id_address_delivery; @Attribute( name="href", required=false) private String id_address_delivery_href; @Element(name="id_address_invoice",required=false) private int id_address_invoice; @Attribute(name="href", required=false) private String id_address_invoice_href; } 

OrderObject.java

 public class OrderObject { @ElementList(required=true, inline=true) private List<Order> list = new ArrayList<Order>(); public List<Order>getList() { return this.list; } } 

La excepción que recibo es:

 WARN/System.err(988): org.simpleframework.xml.core.PersistenceException: Duplicate annotation of name 'href' on field 'id_address_delivery_href' private java.lang.String com.prestashop.orders.Order.id_address_delivery_href at org.simpleframework.xml.core.StructureBuilder.process(StructureBuilder.java:250) at org.simpleframework.xml.core.StructureBuilder.process(StructureBuilder.java:173) at org.simpleframework.xml.core.ObjectScanner.field(ObjectScanner.java:438) at org.simpleframework.xml.core.ObjectScanner.scan(ObjectScanner.java:371) at org.simpleframework.xml.core.ObjectScanner.<init>(ObjectScanner.java:82) . . 

  • Uso de XML simple y obtención de NoClassDefFoundError en Android
  • El documento no tiene excepción de elemento raíz utilizando el serializador xml simple (v2.6.6)
  • ¿Cómo puede convertir el archivo XML local a org.ksoap2.serialization.SoapObject?
  • Excepción con la deserialización del marco XML simple
  • One Solution collect form web for “Cómo analizar el XML de SimpleXML”

    La razón de esta excepción son las anotaciones de @Attribute . No se establecen en el siguiente elemento, sino en todo el objeto Order . Sus anotaciones establecerían href dos veces, pero con valores diferentes.

    Consulte @Attribute de @Attribute :

    La anotación de Attribute representa un atributo XML serializable dentro de un elemento XML. […]

    Pero hay una solución agradable y simple: En lugar de combinar elemento y atributo, haga una clase que haga esto.

    Clase OrderObject :

     @Root(name = "prestashop") @Namespace(reference = "http://www.w3.org/1999/xlink", prefix = "xlink") public class OrderObject { @ElementList(required = true, inline = true) private List<Order> list; public OrderObject() { this.list = new ArrayList<>(); } public List<Order> getList() { return list; } // ... @Override public String toString() { return "OrderObject{" + "list=" + list + '}'; } } 

    Nota: ¡ Los métodos toString() de estas clases solo se implementan para comprobar el resultado!

    Clase de Order :

     @Root(name = "order") public class Order { @Element(name = "id") private int id; @Element(name = "id_address_delivery") private AdressDelivery delivery; @Element(name = "id_address_invoice") private AdressInvoice invoice; public Order(int id, AdressDelivery delivery, AdressInvoice invoice) { this.id = id; this.delivery = delivery; this.invoice = invoice; } private Order() { } // Getter / Setter etc. @Override public String toString() { return "Order{" + "id=" + id + ", delivery=" + delivery + ", invoice=" + invoice + '}'; } @Root() public static class AdressDelivery { @Namespace(reference = "http://www.w3.org/1999/xlink", prefix = "xlink") @Attribute(name = "href", required = false) private String link; @Text() private int value; public AdressDelivery(String link, int value) { this.link = link; this.value = value; } AdressDelivery() { } // Getter / Setter etc. @Override public String toString() { return "AdressDelivery{" + "link=" + link + ", value=" + value + '}'; } } @Root() public static class AdressInvoice { @Attribute(name = "href", required = false) @Namespace(reference = "http://www.w3.org/1999/xlink", prefix = "xlink") private String link; @Text() private int value; public AdressInvoice(String link, int value) { this.link = link; this.value = value; } AdressInvoice() { } // Getter / Setter etc. @Override public String toString() { return "AdressInvoice{" + "link=" + link + ", value=" + value + '}'; } } } 

    Puede ver las clases AdressDelivery y AdressInvoice que combinan atributo y elemento. No tienes que implementarlas como clases internas; No dude en escribirlos como "normal" uno. Tampoco tienes que hacerlas públicas, incluso privadas es posible (por ejemplo, construirlas dentro del constructor de la Order .

    Pero tenga en cuenta los constructores vacíos sin argumentos en la clase Order (y sus clases internas). Son necesarios . Pero puedes hacerlos todos private , sin necesidad de exponerlos. Sólo es importante tener un constructor sin argumentos.

    Cómo usar (ejemplo) :

     File f = new File("whatever.xml"); Serializer ser = new Persister(); OrderObject orderObject = ser.read(OrderObject.class, f); System.out.println(orderObject); 

    Este código analiza el Xml del archivo e imprime el objeto deserializado.

    Entrada Xml (como en su pregunta) :

     <prestashop xmlns:xlink="http://www.w3.org/1999/xlink"> <order> <id>1</id> <id_address_delivery xlink:href="http://abc.com/add/1">1</id_address_delivery> <id_address_invoice xlink:href="http://abc.com/add/2">2</id_address_invoice> </order> </prestashop> 

    Resultado (desde println() ) :

     OrderObject{list=[Order{id=1, delivery=AdressDelivery{link=http://abc.com/add/1, value=1}, invoice=AdressInvoice{link=http://abc.com/add/2, value=2}}]} 

    No está claramente representado, pero lo suficiente para ver el resultado 🙂

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.