2011-07-13 18 views
20

Tôi có hàng chục và hàng chục .xsd tệp mà tôi muốn tự động tạo mã cho. Một vài tệp có tên trùng lặp xung đột khi tôi cố gắng tạo tất cả các tệp đó cùng một lúc.Có cách nào để xử lý các định nghĩa phần tử trùng lặp trên nhiều tệp .xsd trong JAXB không?

Tôi đang tập trung vào việc cố gắng làm cho 2 trong số này hoạt động.

Khi tôi nhận được 2 công việc này, tôi sẽ sửa phần còn lại. Nhưng bây giờ tôi chỉ tập trung vào 2 trong số những tệp này. Tôi không kiểm soát được họ, họ đến từ một nhà cung cấp và tuân theo một "" tiêu chuẩn "", do đó, chỉnh sửa chúng không phải là một tùy chọn vì nhiều lý do.

Tôi đang sử dụng maven-jaxb2-plugin để xử lý các tệp này.

Tôi đã thêm tệp binding.xjb như được đề xuất trong liên kết trong câu trả lời của mat b và các hướng dẫn khác mà tôi đã tìm thấy trên web. Nhưng tôi nhận được các lỗi sau, không có đầu ra.

<?xml version="1.0" encoding="UTF-8"?> 
<jxb:bindings version="2.1" 
       xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance" 
       xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" 
       xmlns:jxb="http://java.sun.com/xml/ns/jaxb" 
       xmlns:xs="http://www.w3.org/2001/XMLSchema" 
       xsi:schemaLocation=" http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"> 
    <jxb:bindings schemaLocation="mac-3.4.xsd"> 
    <jxb:schemaBindings> 
     <jxb:package name="my.company.mac"/> 
    </jxb:schemaBindings> 
    </jxb:bindings> 
    <jxb:bindings schemaLocation="mac-stylesheet-3.4.xsd"> 
    <jxb:schemaBindings> 
     <jxb:package name="my.company.stylesheet"/> 
    </jxb:schemaBindings> 
    </jxb:bindings> 
</jxb:bindings> 

cung cấp cho các lỗi sau

[ERROR] Error while parsing schema(s).Location [ file:/C:/Users/Jarrod%20Roberson/Projects/spa-tools/spa-lib/src/main/sc 
hema/mac-stylesheet-3.4.xsd{165,33}]. 
org.xml.sax.SAXParseException: 'halign' is already defined 

Yếu tố vi phạm là: (có rất nhiều người khác đây chỉ là một trong những đầu tiên đụng độ)

<xsd:simpleType name="halign"> 
    <xsd:restriction base="xsd:string"> 
    <xsd:enumeration value="left" /> 
    <xsd:enumeration value="center" /> 
    <xsd:enumeration value="right" /> 
    </xsd:restriction> 
</xsd:simpleType> 

Và là giống hệt nhau trong mỗi các tệp .xsd, làm cách nào để giải quyết sự trùng lặp này với chỉ một lớp đang được tạo hoặc mỗi lớp được tạo trong không gian tên gói của riêng chúng?

Đây không phải là phần tử trùng lặp duy nhất như thế này, có rất nhiều phần tử, vì vậy, việc cố gắng xóa chúng khỏi tệp cũng không phải là một tùy chọn.

halign này nằm trong nhiều tệp .xsd và tôi muốn đặt chúng trong gói riêng lẻ của chúng hoặc có thể yêu cầu trình biên dịch sử dụng trình biên dịch đầu tiên được tạo.

Đây là nơi tôi bắt đầu trước khi tôi thử tệp .xjb bên ngoài, bằng cách chỉ định package trong pom.xml.

Làm cách nào để định cấu hình ràng buộc bỏ qua các cấu hình trùng lặp, ánh xạ chúng thành các gói riêng biệt hoặc ánh xạ chúng tới các triển khai hiện có?

Trả lời

10

tôi có một giải pháp workaround nửa chặng đường đó, nhưng nó là rất nhiều thời gian chuyên sâu. Tôi phải tạo một <execution/> riêng cho mỗi một tệp có mục trùng lặp.

<executions> 
    <execution> 
    <id>jaxb-mac</id> 
    <phase>generate-sources</phase> 
    <goals> 
     <goal>generate</goal> 
    </goals> 
    <configuration> 
     <forceRegenerate>true</forceRegenerate> 
     <generatePackage>my.company.mac</generatePackage> 
     <schemaDirectory>src/main/schema</schemaDirectory> 
     <schemaIncludes> 
     <include>mac-3.4.xsd</include> 
     </schemaIncludes> 
    </configuration> 
    </execution> 
    <execution> 
    <id>jaxb-stylesheet</id> 
    <phase>generate-sources</phase> 
    <goals> 
     <goal>generate</goal> 
    </goals> 
    <configuration> 
     <forceRegenerate>true</forceRegenerate> 
     <generatePackage>my.company.stylesheet</generatePackage> 
     <schemaDirectory>src/main/schema</schemaDirectory> 
     <schemaIncludes> 
     <include>mac-stylesheet-3.4.xsd</include> 
     </schemaIncludes> 
    </configuration> 
    </execution> 

Các <forceRegenerate>true</forceRegenerate> là quan trọng hay chỉ <execution/> đầu tiên sẽ chạy và phần còn lại sẽ nghĩ rằng không có cần phải chạy vì tôi đang tạo ra vào cùng một thư mục.

Tôi vẫn muốn giải pháp ít tốn kém hơn để giải quyết các bản sao.

Tôi nghĩ rằng nếu tôi làm cho bậc thầy đầu tiên .xsd một mô-đun riêng biệt được xây dựng thành tệp .jar riêng của nó, tôi có thể sử dụng thẻ <episode/> và bỏ qua việc tạo ra cùng một phần tử trùng lặp. trong định nghĩa.

Tôi đã quyết định từ bỏ XML nếu hoàn toàn có thể và JAXB hoàn toàn. Có những cách mới hơn và tốt hơn để phân tích cú pháp XML và ánh xạ nó tới các đối tượng theo bản chỉnh sửa này.

+0

' 'không còn có sẵn trong' maven-jaxb2-plugin: 2.2'. – OrangeDog

1

Thêm một yếu tố <schemaBindings> để XSD:

<schemaBindings> 
    <package name="com.whatever.stuff" /> 
</schemaBindings> 

Source

+0

Tôi không muốn sửa đổi mã nguồn '.xsd' và tôi không thể nhận nhiều tệp' .xjb' bên ngoài để làm việc, hoặc bất kỳ ý tưởng nào. Tôi không thể tìm thấy giải thích rõ ràng về cách xử lý nhiều tệp thành nhiều gói. –

+0

"Tôi không muốn sửa đổi mã nguồn .xsd" - tại sao không? Có vẻ đơn giản là đủ. Nó chỉ là siêu dữ liệu. –

+0

Tôi có hàng trăm thứ này ... –

2

Nhận ra điều này là cũ, nhưng tôi đã có những lỗi tương tự và nó có thể giải quyết nó bằng cách không xác định một mục tiêu gói, ví dụ tùy chọn -b với XJC. Sau đó, các phần tử trùng lặp được tạo trong gói không gian tên của chính chúng và không xung đột.

+1

Nhận xét để đánh dấu phần này là câu trả lời * thực tế *, ít nhất là đối với tôi - loại bỏ phần tử '' trong cấu hình 'maven-jaxb2-plugin' của tôi trong pom đã sửa lỗi này cho tôi. – DaveyDaveDave

-1

tôi gửi giải pháp của tôi cho gradle, nó giải quyết vấn đề trùng lặp và does`not yêu cầu file xjb:

task generateJaxb() { 
    ext.sourcesDir = "${buildDir}/generated-sources/jaxb" 
    ext.classesDir = "${buildDir}/classes/jaxb" 
    ext.schemaDir = "src/resources/schemas" 
    ext.tmp = "${buildDir}/tmp/xjc" 

    doLast() { 
     project.ant { 
      taskdef name: "xjc", classname: "com.sun.tools.xjc.XJCTask", 
        classpath: configurations.jaxb.asPath 

      delete(dir: tmp) 
      mkdir(dir: tmp) 
      delete(dir: sourcesDir) 
      delete(dir: classesDir) 
      mkdir(dir: sourcesDir) 
      mkdir(dir: classesDir) 
     } 

     fileTree(schemaDir){ 
      include '**/*.xsd' 
      include '**/*.wsdl' 
     }.each{File file-> 
      //println file 
      project.ant { 
       taskdef name: "xjc", classname: "com.sun.tools.xjc.XJCTask", 
         classpath: configurations.jaxb.asPath 
       xjc(destdir: tmp, schema:"${file.getAbsolutePath()}") { 
        arg(value: "-wsdl") 
        produces(dir: tmp, includes: "**/*.java") 
       } 
       copy(todir: sourcesDir) { 
        fileset(dir: tmp, erroronmissingdir: false) { 
         include(name: "**/*.java") 
        } 
       } 
       delete(dir: tmp) 
       mkdir(dir: tmp) 
      } 
     } 
     project.ant { 
      javac(destdir: classesDir, source: 1.6, target: 1.6, debug: true, 
        debugLevel: "lines,vars,source", 
        classpath: configurations.jaxb.asPath) { 
       src(path: sourcesDir) 
       include(name: "**/*.java") 
       include(name: "*.java") 
      } 

      copy(todir: classesDir) { 
       fileset(dir: sourcesDir, erroronmissingdir: false) { 
        exclude(name: "**/*.java") 
       } 
      } 
     } 
    } 
} 

configurations { 
    jaxb 
} 

dependencies { 
    jaxb("com.sun.xml.bind:jaxb-xjc:2.2.4-1") 
    compile(files(generateJaxb.classesDir).builtBy(generateJaxb)) 
} 

jar { 
    from generateJaxb.classesDir 
} 
0

Chúng tôi đã có một vấn đề tương tự: chúng tôi đã có một file wsdl và hai tập tin XSD trong cùng danh mục. Tệp wsdl nhập hai tệp xsd. Vấn đề là JAXB đã xem xét tất cả ba tệp và vứt bỏ lỗi '... đã được xác định'. Nó đã cơ bản phàn nàn rằng nó đã thấy cùng một yếu tố trong cả hai tập tin wsdl và xsd.

Chúng ta có thể khắc phục vấn đề này trong maven cắm cấu hình (trong pom.xml) bằng cách thêm một loại trừ thẻ như trong ví dụ sau:

<build> 
    <plugins> 
     <plugin> 
      <groupId>org.jvnet.jaxb2.maven2</groupId> 
      <artifactId>maven-jaxb2-plugin</artifactId> 
      <version>0.12.3</version> 
      <executions> 
       <execution> 
        <goals> 
         <goal>generate</goal> 
        </goals> 
       </execution> 
      </executions> 
      <configuration> 
       <schemaLanguage>WSDL</schemaLanguage> 
       <generatePackage>mywsdl.wsdl</generatePackage> 
       <args><arg>-XautoNameResolution</arg></args> 
       <schemas> 
        <schema> 
         <fileset> 
          <excludes> 
           <exclude>*.xsd</exclude> 
          </excludes> 
         </fileset> 
        </schema> 
       </schemas> 
      </configuration> 
     </plugin> 
    </plugins> 
</build>