2011-02-01 23 views
12

Vì vậy, chúng ta có một loại XSD theo hình thức:JAXB Tag List tạo lớp bên

<xs:complexType name="Foo"> 
    <xs:all> 
     <xs:element name="Bars"> 
      <xs:complexType> 
       <xs:sequence> 
        <xs:element name="Bar" type="barType" maxOccurs="unbounded"/> 
       </xs:sequence> 
      </xs:complexType> 
     </xs:element> 
    </xs:all> 
</xs:complexType>  

để đại diện cho XML:

<Foo> 
    <!-- Elements snipped for brevity--> 
    <Bars> 
     <Bar> 
      <!-- Bar Element --> 
     </Bar> 
    </Bars> 
</Foo> 

XJC tạo ra kết quả gần đúng. Điều khó chịu duy nhất là "Bars" được tạo ra như là một lớp bên trong lưu trữ một danh sách các Bars. Có anyway để có Bars là một danh sách trong Foo trong khi vẫn giữ lại XML ở trên?

Trả lời

1

Bạn có thể làm như sau:

package example; 

import java.util.List; 

import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlElementWrapper; 
import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement(name="Foo") 
public class Foo { 

    private List<Bar> bar; 

    public List<Bar> getBar() { 
     return bar; 
    } 

    @XmlElementWrapper(name="Bars") 
    @XmlElement(name="Bar") 
    public void setBar(List<Bar> bar) { 
     this.bar = bar; 
    } 

} 

package example; 

public class Bar { 

} 

Sau đó, bạn có thể xử lý XML của bạn bằng cách sử dụng đoạn mã sau;

package example; 

import java.io.File; 

import javax.xml.bind.JAXBContext; 
import javax.xml.bind.Marshaller; 
import javax.xml.bind.Unmarshaller; 

public class Demo { 

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

     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     Foo foo = (Foo) unmarshaller.unmarshal(new File("src/forum128/input.xml")); 

     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(foo, System.out); 
    } 
} 
+0

Thật không may tôi đang cố gắng chuyển từ tệp xsd sang tệp java. – Jim

+0

Tôi đang tìm kiếm một cái gì đó như thế này trong [câu hỏi của tôi ở đây] (http://stackoverflow.com/questions/9240837/how-to-write-my-xsd-in-order-to-match-the-desired-xml -and-java-format-using-jaxb). Có thể tạo chú thích '@ XmlElementWrapper' bằng XJC không? Tôi không muốn sửa đổi mã được tạo theo cách thủ công ... –

+0

Blaise: trước hết, cảm ơn bạn rất nhiều cho tất cả các bài đăng của bạn cũng như blog của bạn (ví dụ: [bài đăng này] (http://blog.bdoughan.com/2010 /09/jaxb-collection-properties.html) cũng đề cập đến điều này). Luôn luôn siêu rõ ràng và cho điểm. Tôi cũng đang tìm kiếm một giải pháp đơn giản (tức là không liên quan đến một plugin xjc) mà sẽ cho phép chúng tôi chỉ tạo ra '@ XmlElementWrapper' bởi xjc. Sẽ rất gọn gàng để có thể khai báo một phần tử là "void" hoặc "pass-through" trong tệp .xsd, nghĩa là tất cả các phần tử con của nó sẽ tự động được cha mẹ chứa (hoặc cao hơn nếu cha mẹ cũng có lá cờ đó). –

2

Có thể mẫu dưới đây sẽ giúp.

XML Schema

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
    <xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

     <xs:complexType name="test"> 
     <xs:sequence> 
      <xs:element name="dataList" type="xs:string" nillable="true" minOccurs="0" maxOccurs="unbounded"/> 
      <xs:element name="str" type="xs:string" minOccurs="0"/> 
     </xs:sequence> 
     </xs:complexType> 
    </xs:schema> 

lớp Java:

public class Test { 

    protected List<String> dataList; 
    protected String str; 
    public List<String> getDataList() { 
     if (dataList == null) { 
      dataList = new ArrayList<String>(); 
     } 
     return this.dataList; 
    } 

    public String getStr() { 
     return str; 
    } 

    public void setStr(String value) { 
     this.str = value; 
    } 

} 

EDIT 1:

Bạn có thể đảo ngược kỹ sư từ mã java để XSD. trong JAVA_HOME/bin có tệp thực thi schemagen.

Cung cấp mã java của bạn và nó sẽ tạo lược đồ XSD cho bạn sử dụng lớp java của bạn.

see this link

schemagen myObj1.java myObj2.java 
+0

xsd này mô tả xml như (tôi nghĩ) mà không phải là khá những gì tôi cần. – Jim

+0

@Jim Xem chỉnh sửa của tôi ở trên. – fmucar

6

Khi bạn xác định Bars như một loại phức tạp, Bars sẽ được tạo ra như lớp tách ra. Như thế này tôi thấy lược đồ cũng dễ đọc hơn. Các thanh sẽ không được liệt kê trong Foo trừ khi bạn thay đổi maxOccurs thành một giá trị cao hơn 1 - bạn không thể làm điều này trên xs: tất cả nhưng bạn có thể sử dụng xs: sequence.

... 
    <xs:complexType name="Foo"> 
     <xs:all> 
      <xs:element name="Bars" type="Bars" /> 
     </xs:all> 
    </xs:complexType> 

    <xs:complexType name="Bars"> 
     <xs:sequence> 
      <xs:element name="Bar" type="barType" maxOccurs="unbounded" /> 
     </xs:sequence> 
    </xs:complexType> 
... 

Sau khi chạy XJC: Foo.java:

... 
    @XmlAccessorType(XmlAccessType.FIELD) 
    @XmlType(name = "Foo", propOrder = { 

    }) 
    public class Foo { 

     @XmlElement(name = "Bars", required = true) 
     protected Bars bars; 

     public Bars getBars() { 
      return bars; 
     } 

     public void setBars(Bars value) { 
      this.bars = value; 
     } 
    } 

Bars.java:

... 
    @XmlAccessorType(XmlAccessType.FIELD) 
    @XmlType(name = "Bars", propOrder = { 
     "bar" 
    }) 
    public class Bars { 

     @XmlElement(name = "Bar", required = true) 
     protected List<String> bar; 

     ... 
    } 

Với xs: seqence để có được danh sách các Bars (maxOccurs = "vô biên"): XSD:

... 
    <xs:complexType name="Foo"> 
     <xs:sequence> 
      <xs:element name="Bars" type="Bars" maxOccurs="unbounded" /> 
     </xs:sequence> 
    </xs:complexType> 

    <xs:complexType name="Bars"> 
     <xs:sequence> 
      <xs:element name="Bar" type="barType" maxOccurs="unbounded" /> 
     </xs:sequence> 
    </xs:complexType> 
    ... 

Foo.java: Plugin

... 
@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "Foo", propOrder = { 
    "bars" 
}) 
public class Foo { 

    @XmlElement(name = "Bars", required = true) 
    protected List<Bars> bars; 

    public List<Bars> getBars() { 
     if (bars == null) { 
      bars = new ArrayList<Bars>(); 
     } 
     return this.bars; 
    } 
} 
4

Bjarne Hansen cho XJC (https://github.com/dmak/jaxb-xew-plugin) sẽ cho phép bạn ở lại với "Bars" kèm theo yếu tố, tạo ra @XmlElementWrapper thuận tiện (name = "Bars") chú thích.

+1

Như đã đề cập trong một vài bài đăng/nhận xét khác về chủ đề này, plugin đó dường như không hoạt động với xjc gần đây. Tôi đã đập đầu của tôi về điều này trong hai ngày nay. Ngoài ra tôi thích sử dụng xjc từ dòng lệnh, và plugin này nhiều hơn hoặc ít hơn yêu cầu bạn viết một mục tiêu ant, cũng như tìm nơi heck jaxb.jar là, v.v. –

+0

@PierreD: Nếu plugin bị lỗi trên một số phiên bản của 'xjc' bạn cần, vui lòng đăng lên [plugin bugtracker] (https://github.com/dmak/jaxb-xew-plugin/issues). –

Các vấn đề liên quan