Unmarshaller et le schéma de JAXB
J'ai une application qui peuvent enregistrer le fichier dans différents formats (xml). Donc je devrait résoudre le problème avec détermination dans ce format de fichier n'a été enregistré. Donc, je vois 2 solutions
- différents formats sont différents schémas, afin que je puisse la déterminer par eux.
J'ai mis les schémas dans la façon que je reçois de ici
marshaller.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, "bla-bla.xsd");
donc je suppose que je peux l'obtenir à l'aide de unmarshaller.getProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION)
mais il en jetant
javax.xml.bind.PropertyException:
jaxb.noNamespaceSchemaLocation
et getSchema()
retourner la valeur null
Donc, comment puis-je obtenir de l'emplacement du schéma?
- Spécifiant différents adaptateurs pour les différents haricots à l'aide de
setAdapter(Class<A> type, A adapter)
méthode
Quelle manière est-elle préférable? Si le premier, alors comment puis-je obtenir schéma de l'emplacement de l'étiquette?
upd exemple de code
supposons que nous avons bean
@XmlRootElement
public class Foo{
String bar;
public String getBar() {return bar; }
public void setBar(String bar) {this.bar = bar;}
}
et le code qui génère le schéma, enregistre Foo instances et charge ensuite.
public class Test {
final static String schemaLoc = "fooschema.xsd";
public static void write(File file, Foo foo, Schema schema) throws Throwable {
XMLEventWriter xsw = null;
try{
JAXBContext context = JAXBContext.newInstance(Foo.class);
XMLOutputFactory xof = XMLOutputFactory.newInstance();
OutputStream out = new FileOutputStream(file);
xsw = xof.createXMLEventWriter(out);
Marshaller m = context.createMarshaller();
m.setSchema(schema); //schema setted
System.out.println(">>>marchal : " + m.getSchema()); //check it
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, schemaLoc);
m.marshal(foo, xsw);
} finally{
xsw.close();
}
}
public static Foo load(File file) throws Throwable {
JAXBContext context = JAXBContext.newInstance(Foo.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
System.out.println("unmarshaller schema:" + unmarshaller.getSchema()); //I need get it here
// System.out.println("schema_prop:" + unmarshaller.getProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION));
InputStreamReader in = new InputStreamReader(new FileInputStream(file));
XMLEventReader xer = XMLInputFactory.newInstance()
.createXMLEventReader(in);
return Foo.class.cast(unmarshaller.unmarshal(xer));
}
private static File createSchema(String schemaLocation) throws Throwable{
final File target = new File(schemaLocation);
if(!target.exists()){
JAXBContext jaxbContext = JAXBContext.newInstance(Foo.class);
SchemaOutputResolver sor = new SchemaOutputResolver() {
public Result createOutput(String namespaceURI, String suggestedFileName)
throws IOException {
StreamResult result = new StreamResult(target);
result.setSystemId(target.toURI().toURL().toString());
return result;
}
};
jaxbContext.generateSchema(sor);
}
return target;
}
public static void main(String[] args) throws Throwable {
createSchema(schemaLoc);
File file = new File("temp.xml");
Foo foo = new Foo();
foo.setBar("test bar");
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = factory.newSchema(createSchema(schemaLoc));
write(file, foo, schema);
System.out.println("result " + load(file).getBar());
}
}
schéma qui génère
<xs:element name="foo" type="foo"/>
<xs:complexType name="foo">
<xs:sequence>
<xs:element name="bar" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
notre fichier temporaire
<?xml version="1.0"?>
<foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="fooschema.xsd">
<bar>test bar</bar></foo>
comme nous le voyons, il n'y a
xsi:noNamespaceSchemaLocation="fooschema.xsd"
Comment je peux obtenir ce texte à l'aide de JAXB?
OriginalL'auteur Stan Kurilin | 2010-12-18
Vous devez vous connecter pour publier un commentaire.
Je voudrais tirer parti d'une StAX analyseur pour obtenir cette information (voir l'exemple ci-dessous). Créer un XMLStreamReader sur l'entrée. L'avance de la XMLStreamReader à l'élément racine à l'aide de la nextTag() méthode. Prenez ensuite la noNamespaceSchemaLocation attribut de l'élément racine. Passer ensuite le XMLStreamReader à la unmarshal(XMLStreamReader) méthode sur Unmarshaller.
OriginalL'auteur bdoughan
Vous l'assurer avec l'emplacement de votre schéma en utilisant un fichier de notre fileoutputstream référence:
http://download.oracle.com/javase/6/docs/api/javax/xml/bind/Marshaller.html
EDIT:
Désolé, après lecture de plus, vous voulez l'emplacement du schéma, pas le fichier XML, et il y en a peu d'exemples en ligne. La plupart d'entre eux comme celui-ci:
http://robaustin.wikidot.com/how-to-improve-perforamance-of-jaxb
Montrer comment passer dans le schéma de l'emplacement à l'aide d'un contexte de classe loader.
EDIT:
Par vos commentaires:
http://download.oracle.com/javase/6/docs/api/javax/xml/bind/Marshaller.html#getSchema%28%29
getSchema() renvoie la valeur null si il n'y a pas de schéma sur le marshaller. C'est pourquoi vous ne pouvez pas obtenir la propriété que vous voulez, car il (le schéma) n'existe pas.
Mon anglais n'est pas parfait( je vais essayer de nouveau. Je sais comment obtenir Schéma à partir d'un fichier. Je ne sais pas comment obtenir le texte qu'avait écrit dans
xsi:noNamespaceSchemaLocation=
attribut à l'aide de unmarshaller.Pas de problème Stas 🙂 Voir mon dernier montage.
+1, parce que après les docs il doit l'aider, mais il ne le fait pas. J'ai ajouter un peu long exemple de code pour les clarifier.
OriginalL'auteur