2010-06-03 5 views
4

J'ai hérité d'un projet qui utilise fortement JAXB pour mapper des messages XML sur des objets Java. Le problème que j'ai est que certaines des données que je reçois (dans ce cas, un fichier XML imbriqué de forme inconnue) ne doit PAS être unmarshalled, mais plutôt capturé comme une chaîne.JAXB - NE PAS mélanger les éléments imbriqués - possible?

Un exemple vous aidera

<a> 
    <b></b> 
    <c></c> 
    <d> 
     <!-- "Unknown" XML here --> 
     <maybeE></maybeE> 
     <maybeF></maybeF> 
     <!-- etc etc --> 
    <d/> 
</a> 

Je voudrais que le JAXB à unmarshall « b » et « c », mais « d » il capture le XML imbriqué comme une chaîne dire non analysable.

Donc, appeler:

getD() 

reviendriez chaîne:

"<maybeE></maybeE><maybeF></maybeF>" 
+0

afficher vos annotations JAXB – Bozho

Répondre

4

Vous ne pouvez pas capturer le contenu imbriqué en tant que chaîne, mais vous pouvez capturer comme un DOM, par exemple

@XmlRootElement(name="a") 
public class A { 

    @XmlElement 
    private String b; 

    @XmlElement 
    private String c; 

    @XmlAnyElement 
    private List<Element> content; 
} 

Quelle que soit <a> contient, ce qui ne correspond pas à <b> ou <c>, seront entreposés sous content. Vous pouvez ensuite convertir ces objets Element en chaînes, si vous le souhaitez.

+0

Causée par: com. sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 nombre d'exceptions IllegalAnnotation org.w3c.dom.Element est une interface et JAXB ne peut pas gérer les interfaces. –

+0

@Lawrence: Oups, mon mauvais. Fixé. – skaffman

+0

Merci - cela a parfaitement fonctionné –

1

J'ai trouvé ce qui précède très utile; J'ai eu un problème de mappage similaire où j'avais du HTML qui n'était pas échappé ou codé stocké dans un fichier xml - et je voulais mapper cela à une propriété String.

I utilisé l'annotation:

@XmlElementWrapper(name="operations") 
@XmlAnyElement 
private List<Node> operations; 

ensuite utilisé un transformateur pour imprimer l'arborescence du noeud:

public String getOperationsAsString() throws Exception{ 
    StringBuilder builder = new StringBuilder(); 
    for (Node node: operations) { 
     StringWriter writer = new StringWriter(); 
     Transformer transformer = TransformerFactory.newInstance().newTransformer(); 
     transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); 
     transformer.transform(new DOMSource(node), new StreamResult(writer)); 
     builder.append(writer.toString()); 
    } 
    return builder.toString(); 
} 
1

@ Andrew B: Votre code peut même être amélioré:

public String getOperationsAsString() throws Exception{ 
    StringWriter writer = new StringWriter(); 
    Transformer transformer = TransformerFactory.newInstance().newTransformer(); 
    transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); 
    for (Node node: operations) { 
     transformer.transform(new DOMSource(node), new StreamResult(writer)); 
    } 
    return writer.toString(); 
} 

De cette façon, vous ne créez une seule fois Transformer et vous n'avez pas besoin de StringBuilder. StringWriter écrit déjà dans un StringBuffer en interne.

+0

Merci pour le conseil, je blâme Intellij IDEA pour me rendre négligé :) –

0

Vous pouvez conserver un document XML inconnu à l'aide de l'annotation @XmlAnyElement. Par défaut, cela le gardera comme DOM. Si vous voulez stocké dans un autre format (comme String), vous pouvez spécifier un DomHandler:

Exemple complet

Questions connexes