2012-09-05 86 views
0

我必須從我無法控制的外部系統中解組並處理XML。 XML是我認爲是俄羅斯娃娃格式,它不容易處理。適用於常見嵌套類型的JAXB綁定

XML共享在公共XSD文件中聲明的公共類型。但是,當JABX爲這些類型生成JAVA類時,每個外部類包含常見類型的嵌套聲明,就JAVA而言,它們使它們具有不同類型。

我想要有通用的JAVA函數來處理XML中的常見嵌套類型,但這不起作用,因爲這些常見類型在JAXB類中是不相關的。

這使得我的JAVA代碼需要處理這些常見的類型非常混亂,我一直在嘗試使用JAXB綁定來解決這個問題。但我沒有成功。所以我的問題是: 鑑於這種格式的XML/XSD可以通過綁定或其他方法生成常見類型的JAVA代碼?

所以一個例子;

XML CLASSA & CLASSB中有兩個類。兩者都包含一個類型爲testTYPE的值的複合類型,它是一個字符串。該的XSD是:

CLASSA.XSD

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns:nstype="http://www.test.com/nstypes" 
elementFormDefault="qualified"> 
<xs:import namespace="http://www.test.com/nstypes" schemaLocation="nstypes.xsd"/> 
    <xs:element name="CLASSA"> 
     <xs:complexType> 
      <xs:sequence> 
       <xs:element name="Prop" minOccurs="0"> 
        <xs:complexType> 
         <xs:sequence> 
          <xs:element name="PROP" minOccurs="0"> 
           <xs:complexType> 
            <xs:sequence> 
             <xs:element name="Value" type="nstype:testTYPE" minOccurs="0"/> 
            </xs:sequence> 
           </xs:complexType> 
          </xs:element> 
         </xs:sequence> 
        </xs:complexType> 
       </xs:element> 
      </xs:sequence> 
     </xs:complexType> 
    </xs:element> 
    </xs:schema> 

類B有一個idential結構,只是一個不同的名稱。

CLASSB.XSD

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns:nstype="http://www.test.com/nstypes" 
elementFormDefault="qualified"> 
<xs:import namespace="http://www.test.com/nstypes" schemaLocation="nstypes.xsd"/> 
    <xs:element name="CLASSB"> 
     <xs:complexType> 
      <xs:sequence> 
       <xs:element name="Prop" minOccurs="0"> 
        <xs:complexType> 
         <xs:sequence> 
          <xs:element name="PROP" minOccurs="0"> 
           <xs:complexType> 
            <xs:sequence> 
             <xs:element name="Value" type="nstype:testTYPE" minOccurs="0"/> 
            </xs:sequence> 
           </xs:complexType> 
          </xs:element> 
         </xs:sequence> 
        </xs:complexType> 
       </xs:element> 
      </xs:sequence> 
     </xs:complexType> 
    </xs:element> 
    </xs:schema> 

稱爲類型nstype價值的唯一元件:testTYPE在宣佈nstypes.xsd。它實際上是一個BASETYPE,它是一個String。

nstypes.xsd

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns:nstypes="http://www.test.com/nstypes" 
targetNamespace="http://www.test.com/nstypes" 
elementFormDefault="unqualified"> 
<xs:complexType name="BASETYPE"> 
    <xs:simpleContent> 
     <xs:extension base="xs:string"> 
      <xs:attribute name="TYPE" fixed="BASETYPE"/> 
      <xs:attribute name="derived" use="optional"/> 
      <xs:attribute name="readonly" use="optional"/> 
      <xs:attribute name="required" use="optional"/> 
     </xs:extension> 
    </xs:simpleContent> 
</xs:complexType> 
<xs:complexType name="testTYPE"> 
    <xs:simpleContent> 
     <xs:extension base="nstypes:BASETYPE"/> 
    </xs:simpleContent> 
</xs:complexType> 
</xs:schema> 

的XML用於CLASSA和CLASSB類似於

ClassA.xml

<?xml version="1.0" encoding="UTF-8"?> 
<CLASSA> 
    <Prop> 
     <PROP> 
      <Value>AAA</Value> 
     </PROP> 
    </Prop>  
</CLASSA> 

ClassB.xml

<?xml version="1.0" encoding="UTF-8"?> 
<CLASSB> 
    <Prop> 
     <PROP> 
      <Value>BBB</Value> 
     </PROP> 
    </Prop>  
</CLASSB> 

一旦JAXB類已經產生,我想寫出像這樣的代碼:

testJAXB

import java.io.InputStream; 

import org.generated.CLASSA.CLASSA; 
import org.generated.CLASSA.TestTYPE; 
import org.generated.CLASSB.CLASSB; 

public class testJAXB 
{ 
    // there is a util function  public static Object loadXML(String xmlFile, String fileName) throws Exception; 

    public static void main(String[] args) throws Exception 
    { 
     // create a ClassA & a ClassB 
     CLASSA anAClass = (CLASSA) loadXML("C:\\input\\ClassA.xml", "CLASSA"); 
     CLASSB anBClass = (CLASSB) loadXML("C:\\input\\ClassB.xml", "CLASSB"); 

     static void printClass(TestTYPE v) 
     { 
      // as CLASSA.TestTYPE is imported so v is a CLASSA.TestTYPE 
      System.out.println(v.toString()); 
     } 

     // this call will work as there is a printClass which takes a CLASSA.TestTYPE 
     printClass(anAClass.getProp().getPROP().getValue()); 

     // this call will not compile becase there is no printClass which takes a CLASSA.TestTYPE 
     printClass(anBClass.getProp().getPROP().getValue()); 

     System.out.println("complete."); 
    } 
} 

什麼其實我喜歡做的是有一個實現的函數printClass()。我想這將不得不採取一個org.generated.TestTYPE和所有的JAXB類將與org.generated.TestTYPEs ratehr比org.generated.CLASSA.TestTYPEs生成。 我希望能用一些綁定魔法來實現。如果任何人都能指引我,我會非常感激。

我有C++而不是JAVA背景,所以,如果我的一些術語不正確,請道歉。

傑羅姆

這就是我想看到的,但是從我XJC在CLASSA看到

public CLASSA.Prop getProp() 

其中CLASSA.Prop是含有

protected CLASSA.Prop.PROP 
靜態類

這是另一個靜態類,它包含一個

protected TestTYPE value; 

和TestTYPE是

org.generated.CLASSA.TestTYPE 

在CLASSB的TestTYPE是

org.generated.CLASSB.TestTYPE 

作爲兩個TestTYPE嵌套在不同類別的它們是不同類型的。

本質,運行XJC當我得到含有TestTYPE類兩個文件:

CLASSA/TestTYPE.JAVA

// 
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 in JDK 6 
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
// Any modifications to this file will be lost upon recompilation of the source schema. 
// Generated on: 2012.09.07 at 07:45:23 AM BST 
// 

package org.generated.CLASSA; 

import javax.xml.bind.annotation.XmlAccessType; 
import javax.xml.bind.annotation.XmlAccessorType; 
import javax.xml.bind.annotation.XmlType; 


/** 
* <p>Java class for testTYPE complex type. 
* 
* <p>The following schema fragment specifies the expected content contained within this class. 
* 
* <pre> 
* &lt;complexType name="testTYPE"> 
* &lt;simpleContent> 
*  &lt;extension base="&lt;http://www.test.com/nstypes>BASETYPE"> 
*  &lt;/extension> 
* &lt;/simpleContent> 
* &lt;/complexType> 
* </pre> 
* 
* 
*/ 
@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "testTYPE") 
public class TestTYPE 
    extends BASETYPE 
{ 


} 

and 

CLASSB/TestTYPE.JAVA

// 
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 in JDK 6 
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
// Any modifications to this file will be lost upon recompilation of the source schema. 
// Generated on: 2012.09.07 at 07:45:23 AM BST 
// 

package org.generated.CLASSB; 

import javax.xml.bind.annotation.XmlAccessType; 
import javax.xml.bind.annotation.XmlAccessorType; 
import javax.xml.bind.annotation.XmlType; 


/** 
* <p>Java class for testTYPE complex type. 
* 
* <p>The following schema fragment specifies the expected content contained within this class. 
* 
* <pre> 
* &lt;complexType name="testTYPE"> 
* &lt;simpleContent> 
*  &lt;extension base="&lt;http://www.test.com/nstypes>BASETYPE"> 
*  &lt;/extension> 
* &lt;/simpleContent> 
* &lt;/complexType> 
* </pre> 
* 
* 
*/ 
@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "testTYPE") 
public class TestTYPE 
    extends BASETYPE 
{ 


} 

回答

1

我不認爲JAXB會分解這樣的代碼。 IMO更簡單的解決方案是編寫類Prop的代碼並在綁定文件中定義B.Prop和A.Prop都依賴於同一個類。

例如使用classImpl屬性。 http://docs.oracle.com/cd/E17802_01/webservices/webservices/docs/2.0/tutorial/doc/JAXBUsing4.html#wp148576

+0

謝謝回答什麼,我想試試,並報告! – DUFF

+0

嗨,我已經看過這個,我認爲這是正確的做法。但它可能行不通。問題是你只能改變隱藏的實現。 getters和setter必須返回CLASSA或CLASSB包中的東西,所以它們仍然不是一個普通的java類(我認爲)。我已經在此問題上發佈了另一個問題[here](http://stackoverflow.com/questions/12655797/jaxb-bindings-customising-can-you-change-getter-setter-of-xjc-generated-class-t ) – DUFF

0

鑑於此格式的XML/XSD可以通過綁定或其他方法生成的常見類型的JAVA代碼是 ?

使用JDK的xjc tool

把所有的文件的目錄,然後執行:

xjc *.xsd 

你會看到,它生成的文件:

parsing a schema... 
compiling a schema... 
generated\CLASSA.java 
generated\CLASSB.java 
generated\ObjectFactory.java 
com\test\nstypes\BASETYPE.java 
com\test\nstypes\ObjectFactory.java 
com\test\nstypes\TestTYPE.java 
com\test\nstypes\package-info.java 

你會看到,在CLASSA.java你有一個返回你一個CLASSA.Prop上,你可以做另一個getProp()方法調用getProp():

在CLASSA您有:

public CLASSA.Prop getProp() 

在CLASSA.Prop您有:

public CLASSA.Prop.PROP getPROP() 

CLASSA.Prop.PROPcom.test.nstypes.TestTYPE類型,爲您的普通型不依賴於CLASSA或CLASSB的。

+0

這就是我想看到的,但是從我XJC在CLASSA – DUFF

+0

看到忽略評論,我會在回答中 – DUFF