2010-07-08 2 views
5

Il y a quelques XML assez méchant que je voudrais unmarshall à un objet java en utilisant JaxB. La plupart d'entre elle a semblé assez simple à ce jour - mais je suis un peu coincé sur ce point:JAXB - comment unmarshall ce 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> 

Ceci est la partie pertinente de la dtd

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

Toutes les idées? Ou devrais-je renoncer à essayer d'utiliser JAXB pour cela?

Merci

+0

Je ne vois pas comment la DTD est pertinente ici ... quel type de structure d'objet voulez-vous mapper? – skaffman

+0

Je n'ai pas encore de classe à laquelle je suis unmarshalling, le XML était auparavant géré par un gestionnaire SAX. Je suppose que je voulais essayer d'aplatir la structure - comme tout ce que j'ai besoin de faire est de l'afficher dans une table html/PDF; ses trucs potentiels de dailywtf, et c'est pire! Ceci est juste une petite partie du XML. D'après les réponses ici, il semble que je devrais utiliser Collections; Je suis nouveau à JAXB et le monde de XML, mais j'espère que les réponses ici devraient me donner quelques idées si je continue dans cette voie. –

Répondre

5

En regardant le XML et la DTD, j'ai créé le XSD de la structure:

<?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> 

Utilisez xjc pour générer les classes Java annotées avec les annotations de liaison JAXB de la XSD. Utilisez ensuite unmarshaller pour le désamorcer en objet Java.

Modifier

les classes Java: Generated

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

Avez-vous une classe que vous unmarshalling à? On dirait qu'il aurait besoin des éléments suivants:

/** 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 
} 

Et puis utilisez un XmlTypeAdapter pour cartographier les éléments XML à la classe appropriée.

Questions connexes