2010-12-18 8 views
4

ファイルをさまざまな形式で保存できるアプリケーションがあります(すべてがxmlです)。だから私はどのフォーマットファイルが保存されたのかという問題を解決すべきです。だから、私は2つのソリューションを参照してくださいJAXBのアンマーシャラーとスキーマ

  • 異なったフォーマットは異なったスキーマを持っていますので、私はそれらによってそれを決定することができました。 私は

    marshaller.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, "bla-bla.xsd");

    here

から取得する方法でスキーマを設定するので、私は unmarshaller.getProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION)

を使用してそれを得ることができたとしますが、

javax.xml.bindのを投げます。 PropertyException: jaxb.noNamespaceSchemaLocation

およびgetSchema()戻り値 したがって、スキーマの場所はどのように取得できますか? setAdapter(Class<A> type, A adapter)方法が望ましいどのような方法

を使用して、異なるBeanの異なるアダプタを指定

  • ?最初の場合は、どのようにスキーマ・ロケーション・ラベルを取得できますか?

    UPD のコード例 私たちは豆

    @XmlRootElement 
    public class Foo{ 
        String bar; 
        public String getBar() {return bar; } 
        public void setBar(String bar) {this.bar = bar;} 
    } 
    

    とスキーマを生成するコードがあるとし、その後はFooのインスタンスと負荷を節約できます。生成

    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()); 
        } 
    
    } 
    

    スキーマは

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

    私たちの一時ファイル

    <?xml version="1.0"?> 
    <foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="fooschema.xsd"> 
    <bar>test bar</bar></foo> 
    

    我々が見るように、

    XSIがあります:のnoNamespaceSchemaLocation = "fooschema.xsd"

    JAXBを使用してこのテキストをどのように取得できますか?あなたは私たちのFileOutputStream参照ファイルを使用して、スキーマの場所でそれを提供する必要が

答えて

4

私はこの情報を得るためにStAXパーサを利用します(下記の例を参照)。入力にXMLStreamReaderを作成します。 nextTag()メソッドを使用してXMLStreamReaderをルート要素に進めます。次に、ルート要素のnoNamespaceSchemaLocation属性を取得します。その後、XMLStreamReaderをUnmarshallerのunmarshal(XMLStreamReader)メソッドに渡します。

import java.io.FileInputStream; 
import javax.xml.XMLConstants; 
import javax.xml.bind.JAXBContext; 
import javax.xml.bind.Unmarshaller; 
import javax.xml.stream.XMLInputFactory; 
import javax.xml.stream.XMLStreamReader; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext context = JAXBContext.newInstance(Categories.class); 

     XMLInputFactory xif = XMLInputFactory.newInstance(); 
     FileInputStream fis = new FileInputStream("input.xml"); 
     XMLStreamReader xsr = xif.createXMLStreamReader(fis); 
     xsr.nextTag(); 
     String noNamespaceSchemaLocation = xsr.getAttributeValue(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "noNamespaceSchemaLocation"); 
     System.out.println(noNamespaceSchemaLocation); 

     Unmarshaller um = context.createUnmarshaller(); 
     Categories response = (Categories) um.unmarshal(xsr); 
    } 
} 
2

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

はEDIT:

申し訳ありませんが、さらに読んだ後、あなたが実際の場所をしたいですXMLファイルではなくスキーマであり、オンラインでの例がかなりあります。このような彼らのほとんど:

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

は、コンテキストクラスローダを使用してスキーマの場所に渡す方法を表示します。

EDIT:あなたのコメントパー

:マーシャラーに設定されたスキーマが存在しない場合

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

GETSCHEMA()はnullを返します。そのため、(スキーマ)が存在しないため、必要なプロパティを取得できません。

+0

ありがとうございますが、それはデスクトップアプリケーションですので、インターネットなしで実行することができます/アプリケーションは、移動することができますなど。だから私が整列化するとき、私はスキーマラベルを指定することしかできません。アンマーシャリングでは、ラベルを使用してスキーマを生成できます。このためには、スキーマのラベルを取得する必要があります。 –

+0

私の英語は完璧ではありません(私はもう一度やり直します。ファイルからスキーマを取得する方法は分かっています)unmarshallerを使って 'xsi:noNamespaceSchemaLocation ='属性に書いたテキストがどうして得られないのですか? –

+0

Stas :)参照私の最後の編集。 –