Je suis nouveau dans l'utilisation des espaces de noms en xml, donc je suis un peu confus et je voudrais des éclaircissements. J'ai un service Java où je reçois des documents xml avec de nombreux espaces de noms différents et pendant que je le fais fonctionner, je sens que je dois avoir fait quelque chose de mal, donc je veux vérifier. Dans mon package- info.Java J'ai mon annotation de schéma telle que:
@javax.xml.bind.annotation.XmlSchema(
xmlns={
@javax.xml.bind.annotation.XmHS(prefix="train", namespaceURI="http://mycompany/train"),
@javax.xml.bind.annotation.XmHS(prefix="passenger", namespaceURI="http://mycompany/passenger")
},
elementFormDefault = javax.xml.bind.annotation.XmlNsForm=QUALIFIED
)
J'ai un Train.Java annoté au niveau de la classe avec:
@XmlRootElement(name="Train", namespace="http://mycompany/train")
et chaque champ de la classe annoté avec:
@XmlElement(name="Color") for example
Le train contient une liste de passagers, il y a donc une propriété
private Set<Passenger> passengers;
et cette collection est annotée avec:
@XmlElementWrapper(name="Passengers")
@XmlElements(@XmlElement(name="Passenger", namespace="http://mycompany/passenger"))
Ensuite, dans Passenger.Java, la classe elle-même est annotée avec:
@XmlElement(name="Passenger", namespace="http://mycompany/passenger")
Enfin, pour les champs individuels dans Passenger.Java, ils sont annotés comme ceci:
@XmlElement(name="TicketNumber", namespace="http://mycompany/passenger")
Donc, quand j'ai un xml qui ressemble à:
<train:Train>
<train:Color>Red</train:Color>
<train:Passengers>
<train:Passenger>
<passenger:TicketNumber>T101</passenger:TicketNumber>
</train:Passenger>
</train:Passengers>
</train:Train>
Maintenant, je démasque ce xml que j'ai reçu et la propriété Train's Color est définie et la propriété TicketNumber du passager est définie. Mais je ne sais pas pourquoi j'ai besoin d'ajouter l'URL de l'espace de noms sur l'annotation XmlElement sur TicketNumber pour que cela fonctionne, mais je n'avais pas besoin de le faire pour la propriété Color sur Train. Si je supprime l'attribut namespace de l'annotation XmlElement sur TicketNumber, la valeur du xml ne sera pas mappée à l'objet, sauf si je supprime également le préfixe d'espace de noms de la requête xml. J'ai l'impression que depuis que j'ai l'attribut namespace défini sur le XmlRootElement for Passenger, je ne devrais pas avoir besoin de le faire pour chaque champ de la classe, tout comme je n'en avais pas besoin pour Train, donc je suppose que je doit avoir configuré quelque chose de mal. Quelqu'un peut me diriger dans la bonne direction? Merci!
Vous trouverez ci-dessous une explication du fonctionnement des espaces de noms dans JAXB (JSR-222) en fonction de votre modèle.
MODÈLE Java
info-paquet
Vous trouverez ci-dessous une version modifiée de votre @XmlSchema
annotation. Il contient des informations clés:
namespace
- L'espace de noms par défaut qui sera utilisé pour qualifier les éléments globaux (ceux correspondant à @XmlRootElement
et @XmlElementDecl
annotations (et éléments locaux basés sur la valeur elementFormDefault
) qui n'ont pas d'autre espace de noms spécifié.elementFormDefault
par défaut, seuls les éléments globaux sont qualifiés d'espace de noms mais en définissant la valeur sur XmlNsForm.QUALIFIED
tous les éléments sans espace de nom explicite spécifié seront qualifiés avec la valeur namespace
.xmlns
est l'ensemble de préfixes préféré qu'un implément JAXB doit utiliser pour ces espaces de noms (bien qu'ils puissent utiliser d'autres préfixes).@XmlSchema(
namespace="http://mycompany/train",
elementFormDefault = XmlNsForm.QUALIFIED,
xmlns={
@XmlNs(prefix="train", namespaceURI="http://mycompany/train"),
@XmlNs(prefix="passenger", namespaceURI="http://mycompany/passenger")
}
)
package forum15772478;
import javax.xml.bind.annotation.*;
Train
Puisque tous les éléments correspondant à la classe Train
correspondent au namespace
spécifié sur le @XmlSchema
annotation, nous n'avons pas besoin de spécifier d'informations sur l'espace de noms.
@XmlRootElement
l'annotation correspond à un élément global.@XmlElementWrapper
et @XmlElement
les annotations correspondent aux éléments locaux.package forum15772478;
import Java.util.List;
import javax.xml.bind.annotation.*;
@XmlRootElement(name="Train")
public class Train {
private List<Passenger> passengers;
@XmlElementWrapper(name="Passengers")
@XmlElement(name="Passenger")
public List<Passenger> getPassengers() {
return passengers;
}
public void setPassengers(List<Passenger> passengers) {
this.passengers = passengers;
}
}
Passager
Si tous les éléments correspondant aux propriétés de la classe Passenger
seront dans le http://mycompany/passenger
namespace, vous pouvez alors utiliser le @XmlType
annotation pour remplacer le namespace
du @XmlSchema
annotation.
package forum15772478;
import javax.xml.bind.annotation.*;
@XmlType(namespace="http://mycompany/passenger")
public class Passenger {
private String ticketNumber;
@XmlElement(name="TicketNumber")
public String getTicketNumber() {
return ticketNumber;
}
public void setTicketNumber(String ticketNumber) {
this.ticketNumber = ticketNumber;
}
}
Vous pouvez également remplacer l'espace de noms au niveau de la propriété.
package forum15772478;
import javax.xml.bind.annotation.*;
public class Passenger {
private String ticketNumber;
@XmlElement(
namespace="http://mycompany/passenger",
name="TicketNumber")
public String getTicketNumber() {
return ticketNumber;
}
public void setTicketNumber(String ticketNumber) {
this.ticketNumber = ticketNumber;
}
}
CODE DEMO
Le code de démonstration suivant peut être exécuté pour prouver que tout fonctionne:
Démo
package forum15772478;
import Java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Train.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum15772478/input.xml");
Train train = (Train) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(train, System.out);
}
}
input.xml/Output
Dans le XML ci-dessous, j'ai ajouté les déclarations d'espace de noms nécessaires qui manquaient dans le document XML dans votre question.
<train:Train
xmlns:train="http://mycompany/train"
xmlns:passenger="http://mycompany/passenger">
<train:Color>Red</train:Color>
<train:Passengers>
<train:Passenger>
<passenger:TicketNumber>T101</passenger:TicketNumber>
</train:Passenger>
</train:Passengers>
</train:Train>
POUR PLUS D'INFORMATIONS