Ich habe Anwendung, die Datei in verschiedenen Formaten speichern kann (alle von ihnen ist XML). Also sollte ich das Problem mit der Entscheidung lösen, in welchem Format die Datei gespeichert wurde. Also, ich sehe 2 LösungenUnmarshaller und Schema in JAXB
- verschiedene Formate haben unterschiedliche Schemata, so dass ich es von ihnen bestimmen konnte. Ich habe Schemata in Art und Weise, die ich von here
marshaller.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, "bla-bla.xsd");
so nehme ich, dass ich es unmarshaller.getProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION)
mit bekommen kann
aber es
javax.xml.bind werfen. PropertyException: jaxb.noNamespaceSchemaLocation
und getSchema()
null zurückgeben So, Wie bekomme ich Schema-Speicherort?
- Festlegen von verschiedenen Adaptern für verschiedene Bohnen mit
setAdapter(Class<A> type, A adapter)
Methode
welcher Weise ist vorzuziehen? Wenn zuerst, wie kann ich Schema-Standortbezeichnung erhalten?
upd Codebeispiel nehmen wir Bohne
@XmlRootElement
public class Foo{
String bar;
public String getBar() {return bar; }
public void setBar(String bar) {this.bar = bar;}
}
und Code, das Schema generiert, speichert Foo Instanzen und lädt dann.
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());
}
}
Schema, das
<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>
unsere temporäre Datei
<?xml version="1.0"?>
<foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="fooschema.xsd">
<bar>test bar</bar></foo>
wie wir sehen, gibt es
xsi erzeugt: noNamespaceSchemaLocation = "fooschema.xsd"
Wie kann ich diesen Text mit JAXB bekommen?
Danke, aber es ist Desktop-Anwendung, so kann es bei comp ausgeführt werden, ohne Internet/App kann verschoben werden und so weiter. Wenn ich Marshalling betreibe, kann ich nur das Schema-Label angeben. Beim Unmarshalling kann ich ein Schema mit Label erzeugen. Dafür brauche ich das Schema-Label. –
Mein Englisch ist nicht perfekt (Ich werde es erneut versuchen. Ich weiß, wie Schema aus der Datei abrufen. Ich weiß nicht, wie erhalten Text, der in 'xsi schrieb: noNamespaceSchemaLocation =' Attribut mit Unmarshaller. –
Kein Problem Stas :) Siehe meine letzte Bearbeitung. –