2017-02-19 11 views
0

私はXML文書を読み込み、それをJava Beansにデコードしようとしています。私は読書の部分を解決しましたが、私は問題に取り組んでいます。私は基本的にXMLドキュメントのすべての子ノードをデコードしようとしています。ルートは "catalog"です。 XMLDecoderを使用してこれを行うにはどうすればよいですか?JAXB XML文書を読む

XMLDecoderの:

private static Book jaxbXMLToObject() { 
    try { 
     JAXBContext context = JAXBContext.newInstance(Book.class); 
     Unmarshaller un = context.createUnmarshaller(); 
     Book book = (Book) un.unmarshal(new File("PATH")); 
     return book; 
    } catch (JAXBException e) { 
     e.printStackTrace(); 
    } 
    return null; 
} 

私は次のドキュメント

<?xml version="1.0"?> 
    <catalog> 
     <book id="1"> 
      <author>Isaac Asimov</author> 
      <title>Foundation</title> 
      <genre>Science Ficition</genre> 
      <price>164</price> 
      <publish_date>1951-08-21</publish_date> 
      <description>Foundation is the first novel in Isaac Asimovs Foundation Trilogy (later expanded into The Foundation Series). Foundation is a cycle of five interrelated short stories, first published as a single book by Gnome Press in 1951. Collectively they tell the story of the Foundation, an institute to preserve the best of galactic civilization after the collapse of the Galactic Empire.</description> 
     </book> 
    </catalog> 

を読んで、ブックオブジェクト

@XmlRootElement(name = "book") 
@XmlType(propOrder = {"id", "price", "title", "author", "genre", "description"}) 
public class Book { 
    private int id; 
    private int price; 
    private String title; 
    private String author; 
    private String genre; 
    private String description; 
    private Date publish_date; 

    public Book() { 

    } 

にして、それを解析しようとしている...... エラーが発生します:jjavax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"catalog"). Expected elements are <{}book>

JAXBを使用して子ノードにのみアクセスするにはどうすればよいですか?

UPDATE

カタログクラス:

@XmlRootElement(name = "catalog") 

    public class Catalog { 
     @XmlElement(name = "book") 
     List<Book> books; 

     public List<Book> getBooks() { 
      return books; 
     } 

     public void setBooks(List<Book> books) { 
      this.books = books; 
     } 
    } 

Bookクラス:

@XmlAccessorType(XmlAccessType.FIELD) 
public class Book { 
    @XmlAttribute 
    int id; 
    private int price; 
    private String title; 
    private String author; 
    private String genre; 
    private String description; 
    private Date publish_date; 

    public Book() { 

    } 

    public Book(int id, int price, String title, String genre, String description, Date publicationDate) { 
     this.id = id; 
     this.price = price; 
     this.title = title; 
     this.genre = genre; 
     this.description = description; 
     this.publish_date = publicationDate; 
    } 

    public int getId() { 
     return id; 
    } 

    public int getPrice() { 
     return price; 
    } 

    public String getTitle() { 
     return title; 
    } 

    public String getGenre() { 
     return genre; 
    } 

    public String getDescription() { 
     return description; 
    } 

    public Date getPublicationDate() { 
     return publish_date; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    public void setPrice(int price) { 
     this.price = price; 
    } 

    public void setTitle(String title) { 
     this.title = title; 
    } 

    public void setGenre(String genre) { 
     this.genre = genre; 
    } 

    public void setDescription(String description) { 
     this.description = description; 
    } 

    public void setPublish_date(String publish_date) { 
     this.publish_date = new Date(); 
    } 

    public String getAuthor() { 
     return author; 
    } 

    public void setAuthor(String author) { 
     this.author = author; 
    } 

    public Date getPublish_date() { 
     return publish_date; 
    } 

    public String toJSON() { 
     ObjectMapper mapper = new ObjectMapper(); 

     try { 
      return mapper.writeValueAsString(this); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     return null; 
    } 

    @Override 
    public String toString() { 
     return "Book{" + 
       "id=" + id + 
       ", price=" + price + 
       ", title='" + title + '\'' + 
       ", genre='" + genre + '\'' + 
       ", description='" + description + '\'' + 
       ", publicationDate=" + publish_date + 
       '}'; 
    } 
} 

はDAO:すでにPOINとして

public class BooksDAO { 

    public BooksDAO() { 
    } 

    public List<Book> getBooks() { 
     Catalog catalog = jaxbXMLToObject(); 
     return catalog.getBooks(); 
    } 

    private static Catalog jaxbXMLToObject() { 
     try { 
      return JAXB.unmarshal(new File("PATH"), Catalog.class); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 
} 
+0

(のtoStringなど、ハッシュコード、つまりフィールドの可視性、適切なコンストラクタ、ゲッターは、等しい)のデモコードは最低限であり、あなたのニーズに合わせて変更する必要があります前に言いましたジャクソンジャクソンを使用して、XMLデータフォーマットの拡張機能を使用してXMLを読むことができますか? JAXBですか? XMLDecoderの使用は、XML Beanのシリアライゼーション/デシリアライゼーションに固有のXMLを扱うXMLEncoderのカウンターパートとして使用するように設計されているため、ここでは機能しません。 –

+0

JAXBも可能ですが、どのように私はそれをやっていくのだろうか?私は今JAXBを使ってやろうとしていますが、本を取ろうとしているときにこの愚かなカタログの問題が発生します。 – Lithicas

+0

あなたのXML文書のルート要素はBokではありません。それはカタログです。そして、カタログには本(またはより現実的な例ではいくつかのものがあります)があります。リストを含むCatalogクラスを作成します。ドキュメントをカタログに非マーシャルします(ブックではなく)。返されるCatalogオブジェクトから本を取得します。 TL; DR:Java Bean構造がXML構造と一致することを確認します。 –

答えて

1

JB Nizet氏は、あなたが囲んでいるCatalogオブジェクトを間違いなく必要としていると考えています。以下は、JAXBを使用して提供されるXMLドキュメントを非整列化し、そこから本を取り出すことができるようにする最低限です:

public class ReadXMLUsingJAXB { 

    static class Catalog { 
     @XmlElement(name = "book") 
     List<Book> books; 
    } 

    @XmlAccessorType(XmlAccessType.FIELD) 
    static class Book { 
     @XmlAttribute 
     int id; 
     String author; 
     String title; 
     String genre; 
     int price; 
     Date publish_date; 
     String description; 
    } 

    private static Book firstBookFromXML() { 
     Catalog catalog = JAXB.unmarshal(new File("PATH"), Catalog.class); 
     return catalog.books.get(0); 
    } 

    public static void main(String[] args) { 
     Book book = firstBookFromXML(); 
     System.out.println(book.id + ", " + book.author + ", " + book.title 
       + ", " + book.genre + ", " + book.price 
       + ", " + book.publish_date + ", " + book.description); 
    } 

} 

いくつかのものは、ここで言及する価値がある:

  1. @XmlAccessorType -annotationではありませんCatalogには@XmlElementと注釈を付けられたフィールドが1つしかないので必要です。
  2. アクセスタイプとしてFIELDを選択すると、@XmlTransientと注釈が付けられていない限り、すべてのフィールドが可視性に関係なく考慮されます。
  3. ブックIDはドキュメント内の属性なので、@XmlAttributeを使用してそのように宣言する必要があります。
  4. @XmlElementは、book-Elementsの名前を反映するために必要でした。 JAXBは、デフォルトでは、となり、要素と一致しないフィールド(またはプロパティ)の名前になります。すでに使用している場合は

としては

+0

私はあなたの提案に従って更新しました。しかし、非マーシャルはnullを返します。 (更新されたコードについては最初の投稿をチェックしてください)。 – Lithicas

+1

デモンストレーションコードをそのままコピーして貼り付けるとうまくいくはずです。更新された質問コードでは、getter *と* setterを追加したため、@ XmlAccessorType(XmlAccessType.FIELD)をCatalogクラスに追加する必要があります。 JAXBは非常に厄介なことがあります!編集:FIELDアクセサー型を使用するとゲッターやセッターは必要ありませんので、JAXBを幸せにするために追加する必要はないと思いません。 –

+0

ビンゴ:)おかげで助けて! – Lithicas