2010-12-29 37 views
6

Cần giúp đỡ với tình huống sau đây: Người dùng có thể tạo ra cấu trúc dữ liệu riêng của họ mà được lưu trữ như JAXB-ready nguồn XSD như dưới đây:làm thế nào để buộc schema biên soạn các lớp học để mở rộng lớp học cụ thể schema bên ngoài

<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

    <xs:element name="Group" type="Group"/> 
    <xs:element name="Parameter" type="Parameter"/> 

    <xs:complexType name="Group"> 
    <xs:sequence> 
     <xs:element name="caption" type="xs:string" minOccurs="0"/> 
     <xs:element name="parameters" type="Parameter" nillable="true" minOccurs="0" maxOccurs="unbounded"/> 
    </xs:sequence> 
    </xs:complexType> 

    <xs:complexType name="Parameter"> 
    <xs:sequence> 
     <xs:element name="key" type="xs:string" minOccurs="0"/> 
     <xs:element name="group" type="Group" minOccurs="0"/> 
     <xs:element name="value" type="xs:string" minOccurs="0"/> 
    </xs:sequence> 
    </xs:complexType> 
</xs:schema> 

Sau mới hoặc sơ đồ biến đổi xuất hiện nó sẽ tự động phân tích cú pháp bằng Schema trình biên dịch, nguồn java được tạo ra, biên soạn và đóng gói vào sử dụng lọ:

SchemaCompiler sc = XJC.createSchemaCompiler(); 
    // Input source for schema 
    InputSource is = new InputSource(new StringInputStream(objectPackage.getObjectSchema())); 
    // Parse 
    sc.parseSchema(is); 
    S2JJAXBModel model = sc.bind(); 
    // Generate source 
    JCodeModel jCodeModel = model.generateCode(null, null); 
    jCodeModel.build(packageSourceDirectory); 
    // Compile and package 
    // ...... 

và mọi thứ đều ok cho đến khi nó đã quyết định rằng mọi tầng lớp người dùng tạo phải mở rộng một lớp học cụ thể đã biết, nói UserRootObject:

package user.abc; 
public class Group extends com.mycompany.xml.UserRootObject { 
    // 
} 

package user.abc; 
public class Parameter extends com.mycompany.xml.UserRootObject { 
    // 
} 

Tất cả mọi thứ được khi đang bay, tôi không thể buộc người dùng chỉnh sửa file schema của họ, nhưng tôi có thể chuyển đổi chúng trước khi sang thế hệ mã. Có vẻ như tôi có hai tùy chọn để giới thiệu rằng UserRootObject: bằng cách nào đó thông qua JCodeModel hoặc bằng cách nào đó chuyển đổi tệp lược đồ trước khi tạo nguồn Java.

Trả lời

1

Tôi không tin rằng có một cách dễ dàng để thực hiện việc này bằng chính JAXB. Có một số tùy chọn tùy chỉnh có sẵn mà thường không được biết - đọc section 7 of JSR222 để biết chi tiết.

Nếu bạn có một số kiểm soát đối với lược đồ nhập, thì bạn có thể muốn xem xét việc sử dụng XSLT để chuyển đổi lược đồ. Tôi tin rằng điều này có thể được thực hiện bằng cách sử dụng một ví dụ javax.xml.transform.dom.DOMResult làm mục tiêu của phép biến đổi và sử dụng đầu ra dưới dạng cây DOM (ví dụ: gọi getNode() trên kết quả) làm đầu vào cho parseSchema. Một chuyển đổi cơ bản sẽ được thay thế:

<xs:complexType name="foo"> 
    <!-- CONTENTS --> 
</xs:complexType> 

với một cái gì đó như:

<xs:complexType name="foo"> 
    <xs:complexContent> 
    <xs:extension base="UserRootObject"> 
     <!-- CONTENTS --> 
    </xs:extension> 
    </xs:complexContent> 
</xs:complexType> 

Tất nhiên điều này chỉ làm việc cho các trường hợp đơn giản. Nếu bạn đã có kế thừa trong các tệp lược đồ của mình, thì bạn sẽ phải thực hiện một số lọc trong XSLT chỉ áp dụng phép biến đổi này thành các kiểu chưa được mở rộng.

+0

Cảm ơn! Có, tôi có thể chuyển đổi lược đồ theo cách đó nhưng làm thế nào để tôi nói với trình biên dịch lược đồ không tạo UserRootObject mà là 'làm cho tham chiếu' đến một lớp hiện có? Có thể ở tất cả? Điều đó sẽ tuyệt vời và giải quyết vấn đề. – Osw

+1

Bạn đúng trong tiêu chuẩn JAXB đó không bao gồm trường hợp sử dụng này, nhưng XJC cung cấp điều này như là một phần mở rộng. Để biết thêm chi tiết, hãy xem: http://stackoverflow.com/questions/4556179/how-to-force-schema-compiled-classes-to-extend-specific-class-outside-schema/4607476#4607476 –

5

Rất cám ơn D.Shawley đã chỉ ra phần đúng trong JSR 222. Đây là giải pháp cuối cùng có thể hữu ích và tiết kiệm thời gian cho người khác. Giản đồ gốc phải được chuyển đổi như sau:

<xs:schema version="1.0" 
       xmlns:xs="http://www.w3.org/2001/XMLSchema" 
       xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
       jaxb:version="2.0" > 

     <xs:element name="Group" type="Group"/> 
     <xs:element name="Parameter" type="Parameter"/> 


     <xs:complexType name="Group"> 
     <xs:complexContent> 
      <xs:extension base="UserRootObject"> 
      <xs:sequence> 
      <!-- params --> 
      </xs:sequence> 
      </xs:extension> 
     </xs:complexContent> 
     </xs:complexType> 

     <xs:complexType name="Parameter"> 
     <xs:complexContent> 
      <xs:extension base="UserRootObject"> 
      <xs:sequence> 
      <!-- params --> 
      </xs:sequence> 
      </xs:extension> 
     </xs:complexContent> 
     </xs:complexType> 

     <xs:complexType name="UserRootObject"> 
     <xs:annotation> 
      <xs:appinfo> 
      <jaxb:class name="UserRootObject" implClass="com.mycompany.xml.UserRootObject"/> 
      </xs:appinfo> 
     </xs:annotation> 
     </xs:complexType> 
    </xs:schema> 

Chuyển đổi có thể dễ dàng được thực hiện thông qua org.w3c.dom.Document inteface.

7

XJC có phần mở rộng cho mục đích này

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
      xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
      xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" 
      jaxb:extensionBindingPrefixes="xjc" 
      jaxb:version="2.0"> 

    <xs:annotation> 
     <xs:appinfo> 
      <jaxb:globalBindings> 
      <xjc:superClass name="com.mycompany.xml.UserRootObject"/> 
      </jaxb:globalBindings> 
     </xs:appinfo> 
    </xs:annotation> 
. 
. 
. 
</xs:schema> 

Để biết thêm thông tin xem:

Các chú thích giản đồ cũng có thể được cung cấp thông qua một tập tin bindings bên ngoài.Đối với một ví dụ xem:

+0

Giải pháp tốt. Chúc bạn ở đây trong năm 2010 :) Cá nhân tôi thích gắn bó với đặc tả JAXB và không dựa vào việc triển khai XJC, nhưng giải pháp có thể rất hữu ích và tiết kiệm thời gian cho người khác. Btw rằng "-extension" chế độ được đề cập là một chút khó hiểu, người ta sẽ phải kiểm tra xem chế độ này được kích hoạt cho biên dịch giản đồ biên dịch như trong trường hợp của tôi. – Osw

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