2010-12-18 3 views
4

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
bekommen

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?

Antwort

4

Ich würde einen StAX-Parser nutzen, um diese Informationen zu erhalten (siehe Beispiel unten). Erstellen Sie einen XMLStreamReader für die Eingabe. Stellen Sie den XMLStreamReader mit der Methode nextTag() dem Stammelement voran. Dann greifen Sie das noNamespaceSchemaLocation-Attribut des Root-Elements. Übergeben Sie dann den XMLStreamReader an Unmarshal (XMLStreamReader) Methode auf Unmarshaller.

2

Sie haben es mit dem Standort Ihres Schemas zur Verfügung zu stellen, indem eine Datei unserer Outputstream Referenzen:

http://download.oracle.com/javase/6/docs/api/javax/xml/bind/Marshaller.html

EDIT:

Sorry, nach weiteren Lesen Sie eigentlich die Lage des das Schema, nicht die XML-Datei, und es gibt einige Beispiele online.Die meisten von ihnen wie diese:

http://robaustin.wikidot.com/how-to-improve-perforamance-of-jaxb

Zeigen Sie, wie im Schema Lage passieren ein Kontext Class Loader verwendet wird.

EDIT:

Per Ihre Kommentare:

http://download.oracle.com/javase/6/docs/api/javax/xml/bind/Marshaller.html#getSchema%28%29

GetSchema() den Wert null zurück, wenn kein Schema auf dem Einweiser gesetzt ist. Aus diesem Grund können Sie die gewünschte Eigenschaft nicht erhalten, weil sie (das Schema) nicht existiert.

+0

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. –

+0

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. –

+0

Kein Problem Stas :) Siehe meine letzte Bearbeitung. –