2010-07-08 24 views
5

Hay algunos XML bastante desagradables que me gustaría separar a un objeto java utilizando JaxB. La mayor parte se ha parecido bastante sencillo hasta ahora - pero estoy un poco atascado en esto:JAXB: ¿cómo deshacer este XML?

  <assets> 
       <asset type="fixed">74,414</asset> 
       <asset type="current">1,022,069</asset> 
       <asset type="other">0</asset> 
       <total type="assets">1,096,483</total> 
      </assets> 

Esta es la parte correspondiente de la DTD

<!ELEMENT assets (asset|total)*> <!ELEMENT asset (#PCDATA)> <!ATTLIST asset type CDATA #REQUIRED> <!ELEMENT total (#PCDATA)> <!ATTLIST total type CDATA #REQUIRED>

¿Alguna idea? ¿O debería dejar de intentar usar JAXB para esto?

Gracias

+0

No veo cómo la DTD es relevante aquí ... ¿a qué tipo de estructura de objetos desea asignar? – skaffman

+0

Todavía no tengo una clase a la que me estoy desmarcando, el XML fue manejado previamente por un controlador de SAX. Supongo que quería intentar aplanar la estructura, ya que todo lo que tengo que hacer es mostrarla en una tabla html/PDF; ¡Su potencial diario, y peor! Esto es solo una pequeña porción del xml. De las respuestas aquí parece que tendré que usar Colecciones; Soy nuevo en JAXB y en el mundo de XML, pero espero que las respuestas aquí me den algunas ideas si continúo en este camino. –

Respuesta

5

Mirando el XML y DTD, que crearon el XSD de la estructura:

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    elementFormDefault="qualified"> 
    <xs:element name="assets"> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element maxOccurs="unbounded" ref="asset"/> 
     <xs:element maxOccurs="unbounded" ref="total"/> 
     </xs:sequence> 
    </xs:complexType> 
    </xs:element> 
    <xs:element name="asset"> 
    <xs:complexType mixed="true"> 
     <xs:attribute name="type" use="required" type="xs:string"/> 
    </xs:complexType> 
    </xs:element> 
    <xs:element name="total"> 
    <xs:complexType mixed="true"> 
     <xs:attribute name="type" use="required" type="xs:string"/> 
    </xs:complexType> 
    </xs:element> 
</xs:schema> 

Uso xjc para generar las clases Java anotadas con las anotaciones de enlace JAXB desde el XSD. Luego use el unmarshaller para desmarcarlo en el objeto Java.

Editar

clases Java generadas:

import java.util.ArrayList; 
import java.util.List; 
import javax.xml.bind.annotation.XmlAccessType; 
import javax.xml.bind.annotation.XmlAccessorType; 
import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.XmlType; 
import javax.xml.bind.annotation.XmlAttribute; 
import javax.xml.bind.annotation.XmlValue; 

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "", propOrder = { 
    "asset", 
    "total" 
}) 
@XmlRootElement(name = "assets") 
public class Assets { 

    @XmlElement(required = true) 
    protected List<Asset> asset; 
    @XmlElement(required = true) 
    protected List<Total> total; 

    public List<Asset> getAsset() { 
     if (asset == null) { 
      asset = new ArrayList<Asset>(); 
     } 
     return this.asset; 
    } 

    public List<Total> getTotal() { 
     if (total == null) { 
      total = new ArrayList<Total>(); 
     } 
     return this.total; 
    } 

} 

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "", propOrder = { 
    "content" 
}) 
@XmlRootElement(name = "asset") 
public class Asset { 

    @XmlValue 
    protected String content; 
    @XmlAttribute(required = true) 
    protected String type; 

    public String getContent() { 
     return content; 
    } 

    public void setContent(String value) { 
     this.content = value; 
    } 

    public String getType() { 
     return type; 
    } 

    public void setType(String value) { 
     this.type = value; 
    } 

} 

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "", propOrder = { 
    "content" 
}) 
@XmlRootElement(name = "total") 
public class Total { 

    @XmlValue 
    protected String content; 
    @XmlAttribute(required = true) 
    protected String type; 

    public String getContent() { 
     return content; 
    } 

    public void setContent(String value) { 
     this.content = value; 
    } 

    public String getType() { 
     return type; 
    } 

    public void setType(String value) { 
     this.type = value; 
    } 

} 
1

¿Tiene una clase que está a unmarshalling? Suena como que necesitaría la siguiente:

/** AssetContainer */ 
@XmlRootElement(namespace = "project/schema") 
@XmlAccessorType(XmlAccessType.FIELD) 
public class AssetContainer implements Unmarshallable { 
    private List<Asset> assetList; 
    private int totalAssets; 
} 

/** Asset */ 
@XmlType 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Asset implements Unmarshallable { 
    private AssetTypeEnum type; 
    private int count; 
} 

/** Unmarshallable */ 
public interface Unmarshallable { 
    // Marker interface 
} 

y luego usar un XmlTypeAdapter para mapear los elementos XML a la clase adecuada.

Cuestiones relacionadas