JAXB: comment marshall carte en <key>valeur</key>
La question est à propos de JAXB Carte de triage - il y a beaucoup d'exemples sur la façon de marhsall une Carte, dans une structure comme suit:
<map>
<entry>
<key> KEY </key>
<value> VALUE </value>
</entry>
<entry>
<key> KEY2 </key>
<value> VALUE2 </value>
</entry>
<entry>
...
</map>
En fait, c'est pris en charge nativement par JAXB. Ce dont j'ai besoin, cependant, est le XML où la clé est le nom de l'élément, de la valeur et de son contenu:
<map>
<key> VALUE </key>
<key2> VALUE2 </key2>
...
</map>
Je n'ai pas réussir la mise en œuvre de ma Carte d'adaptateur de la façon dont elle est recommandée par JAXB développeurs (https://jaxb.dev.java.net/guide/Mapping_your_favorite_class.html), que j'ai besoin, il - dynamique le nom de l'attribut 🙂
Est qu'il ya une solution pour cela?
P. S. Actuellement, j'ai créer une classe de conteneur pour chaque typiques ensemble de paires clé-valeur, je veux marshall en XML, il fonctionne, mais je dois créer beaucoup trop de ces helper conteneurs.
- La même question a été répondu par: stackoverflow.com/questions/6820092/jaxb-hashmap-unmappable/...
- Remarque: C'est une mauvaise idée de serialise une carte en <key>valeur</key>, car une clé de démarrage avec un chiffre produira mal formé XML (xml, les balises ne sont pas autorisés à commencer par un chiffre). Ainsi, dans le cas où vous aimez vraiment faire ce que vous avez à faire assurez-vous que les touches sont valides des balises XML.
Vous devez vous connecter pour publier un commentaire.
le code fourni ne fonctionne pas pour moi.
J'ai trouvé un autre moyen à la Carte :
MapElements :
MapAdapter :
La rootElement :
J'ai trouvé le code dans ce site :
http://www.developpez.net/forums/d972324/java/general-java/xml/hashmap-jaxb/
<key>key</key> <value>value</value>
. PAS<key>value</key>
. J'ai assez bien copié et le rythme de ce code. Cela a été la "meilleure solution"?Il y a peut être une raison valable pourquoi vous voulez le faire, mais la génération de ce type de XML est généralement à éviter. Pourquoi? Car cela signifie que les éléments XML de votre carte sont dépendants sur le runtime contenu de votre carte. Et comme XML est généralement utilisé comme une interface externe ou de la couche d'interface ce n'est pas souhaitable. Laissez-moi vous expliquer.
Le Schéma Xml (xsd) définit l'interface du contrat de vos documents XML. En plus d'être en mesure de générer le code à partir du fichier XSD, JAXB peut aussi générer un schéma XML pour vous à partir du code. Cela vous permet de limiter la quantité de données échangées via l'interface convenu à l'avance, les structures définies dans le fichier XSD.
Dans le cas par défaut pour un
Map<String, String>
, à la génération XSD va restreindre l'élément de carte de contenir plusieurs éléments de saisie qui doivent contenir unxs:string
clé et unexs:string
valeur. C'est une jolie interface claire contrat.Ce que vous décrivez, c'est que vous voulez que le mappage xml contenir des éléments dont le nom sera déterminé par le contenu de la carte au moment de l'exécution. Alors générés XSD peut seulement indiquer que la carte doit contenir une liste des éléments dont le type est inconnu au moment de la compilation. C'est quelque chose que vous devriez éviter lors de la définition d'une interface de contrat.
Pour obtenir un contrat strict dans ce cas, vous devez utiliser un type énuméré comme la clé de la carte au lieu d'une Chaîne. E. g.
De cette façon, les clés qui vous voulez devenir des éléments XML sont connus au moment de la compilation afin de JAXB devrait être en mesure de générer un schéma qui permettrait de limiter les éléments de la carte pour les éléments à l'aide de l'une des clés prédéfinies de la CLÉ ou de la TOUCHE2.
D'autre part, si vous souhaitez simplifier par défaut généré structure
À quelque chose de plus simple comme cela
Vous pouvez utiliser un MapAdapter qui convertit la Carte à un tableau de MapElements comme suit:
Je suis toujours travailler sur une meilleure solution, mais en utilisant MOXy JAXB, j'ai été capable de gérer le XML suivant:
Vous devez utiliser un @XmlJavaTypeAdapter sur votre Carte de propriété:
La mise en œuvre de la XmlAdapter est comme suit:
La AdpatedMap classe est là toute la magie se produit, nous allons utiliser le DOM pour représenter le contenu. Nous tromper JAXB intro affaire avec un DOM grâce à la combinaison de @XmlAnyElement et une propriété de type de l'Objet:
Cette solution nécessite la MOXy JAXB mise en œuvre. Vous pouvez configurer le JAXB exécution pour utiliser le MOXy mise en œuvre par l'ajout d'un fichier nommé jaxb.propriétés avec votre modèle de classes avec l'entrée suivante:
La démonstration suivante de code peut être utilisé pour vérifier le code:
Je ne vois rien qui a vraiment répondu à cette question, très bien.
J'ai trouvé quelque chose qui marche très bien ici:
Utilisation JAXB XMLAnyElement type de style de retour dynamique des noms d'élément
Je l'ai modifié un peu pour soutenir la table de hachage arbres. Vous pouvez ajouter d'autres collections.
Puis à le mettre en œuvre:
Alimentation par un simple Marshaller donne de sortie qui ressemble à ceci:
(Désolé, ne peut pas ajouter des commentaires)
Blaise dans la réponse ci-dessus, si vous modifiez:
à:
alors cela devrait se débarrasser de la
<mapProperty>
tag, et ainsi de vous donner:SINON:
Vous pouvez également le modifier:
et puis vous pouvez vous débarrasser de
AdaptedMap
tout à fait, et il suffit de changerMapAdapter
de marshall à unDocument
objet directement. J'ai uniquement testé avec de l'ordonnancement, de sorte qu'il peut être unmarshalling questions.Je vais essayer de trouver le temps de frapper un exemple complet de ce, et de modifier ce post en conséquence.
J'ai la solution sans adaptateur. Transitoire carte convertis au format xml-éléments et vice versa:
Ma sortie comme espected:
Vous pouvez utiliser l'élément de la paire nom/valeur. J'ai besoin d'attributs...
Amusez-vous!
Semble que cette question est une sorte de doublon avec un autre, où j'ai récupérer quelques maréchal/unmarshal solutions dans un seul post. Vous pouvez le vérifier ici: Dynamique des noms de balise avec JAXB.
En bref:
@xmlAnyElement
devrait être crééXmlAdapter
peut être utilisé de paire avec@XmlJavaTypeAdapter
àla conversion entre la classe de conteneur et de Map<>;
Lors de l'utilisation de xml-api-1.0, vous pouvez sérialiser et désérialiser ce:
L'aide de ce code:
J'ai trouvé la solution la plus simple.
Maintenant, il va générer dans vous sortie xml comme ceci: