2011-11-30 57 views
13

我嘗試過程中使用出貨的Java 7的JAXB實現我使用這些版本的一些XML文件:JAXB處理

501 ~ % xjc -version 
xjc 2.2.4 
502 ~ %java -version   
java version "1.7.0_01" 
Java(TM) SE Runtime Environment (build 1.7.0_01-b08) 
Java HotSpot(TM) Server VM (build 21.1-b02, mixed mode) 

XML架構的問題decalaration如下:

<xsd:complexType name="CategorizeType"> 
    <xsd:complexContent> 
     <xsd:extension base="se:FunctionType"> 
      <xsd:sequence> 
       <xsd:element ref="se:LookupValue"/> 
       <xsd:element ref="se:Value"/> 
       <xsd:sequence minOccurs="0" maxOccurs="unbounded"> 
        <xsd:element ref="se:Threshold"/> 
        <xsd:element ref="se:Value"/> 
       </xsd:sequence> 
       <xsd:element ref="se:Extension" minOccurs="0" /> 
      </xsd:sequence> 
      <xsd:attribute name="thresholdBelongsTo" 
        type="se:ThresholdBelongsToType" use="optional"/> 
     </xsd:extension> 
    </xsd:complexContent> 
</xsd:complexType> 

正如你所看到的,se有兩個顯式的出現:Type中的Value。但是,它不會停止使用xjc編譯。如果我有這種類型生成的Java類一看,我可以看到,它是theoritically可以使用以下方法來檢索的

<xsd:sequence minOccurs="0" maxOccurs="unbounded"> 
    <xsd:element ref="se:Threshold"/> 
    <xsd:element ref="se:Value"/> 
</xsd:sequence> 

元素:

public List<Object> getThresholdAndValue() { 
    if (thresholdAndValue == null) { 
     thresholdAndValue = new ArrayList<Object>(); 
    } 
    return this.thresholdAndValue; 
} 

不幸的是,如果我試圖讓列表的元素,我只能取回我的XML文件,其中CategorizeType實例定義如下注冊門檻的元素:

<Categorize thresholdsBelongTo="succeeding" fallbackValue="0"> 
    <LookupValue> 
     <ns3:ValueReference>OUI_EEE92</ns3:ValueReference> 
    </LookupValue> 
    <Value>0.3</Value> 
    <Threshold>30.0</Threshold> 
    <Value>0.4</Value> 
    <Threshold>40.0</Threshold> 
    <Value>0.45</Value> 
    <Threshold>45.0</Threshold> 
    <Value>0.5</Value> 
    <Threshold>50.0</Threshold> 
    <Value>0.55</Value> 
    <Threshold>55.0</Threshold> 
    <Value>0.6</Value> 
    <Threshold>60.0</Threshold> 
    <Value>0.7</Value> 
    <Threshold>70.0</Threshold> 
    <Value>0.8</Value> 
    <Extension> 
     <ExtensionParameter name="method">MANUAL</ExtensionParameter> 
    </Extension> 
</Categorize> 

瓦在檢索列表中,我只能看到閾值。

我做錯了什麼?它是Jaxb的內在侷限性嗎?

請注意,我不能改變的XML架構...

編輯:

我剛剛與-v選項運行XJC,我在全球獲得相同的輸出。隨着冗長:

xjc -verbose se/2.0/All.xsd 
parsing a schema... 
[WARNING] java.net.SocketException: Unexpected end of file from server 
    line 23 of file:/home/alexis/crap/SE-Schema-2.0/ows/2.0/ows19115subset.xsd 

[WARNING] java.net.SocketException: Unexpected end of file from server 
    line 22 of file:/home/alexis/crap/SE-Schema-2.0/filter/2.0/filterCapabilities.xsd 

compiling a schema... 
[INFO] generating codee 
unknown location 

沒有它:

xjc se/2.0/All.xsd 
parsing a schema... 
[WARNING] java.net.SocketException: Unexpected end of file from server 
    line 23 of file:/home/alexis/crap/SE-Schema-2.0/ows/2.0/ows19115subset.xsd 

[WARNING] java.net.SocketException: Unexpected end of file from server 
    line 22 of file:/home/alexis/crap/SE-Schema-2.0/ows/2.0/owsExceptionReport.xsd 

compiling a schema... 

下面的輸出只包含生成的文件的名稱和位置。

我忘了說這個xsd無法與隨Java 6提供的xjc一起編譯。最後嘗試過使用JAXB 2.1.10。現在我無法再現此行爲,因爲我現在使用Java 7的工作

EDIT2:

我只是嘗試自訂binginds,在意見提出。我綁定文件如下:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<jxb:bindings jxb:version="1.0" 
    xmlns:jxb="http://java.sun.com/xml/ns/jaxb" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" > 
    <jxb:bindings schemaLocation="schema.xsd" 
        node="//xsd:complexType[@name='CategorizeType']"> 
     <jxb:bindings 
        node="xsd:complexContent/xsd:extension/xsd:sequence/xsd:element[@ref='se:Value'][position()=1]"> 
      <jxb:property name="FirstValue"/> 
     </jxb:bindings> 
    </jxb:bindings> 
</jxb:bindings> 

的第一個值實例是由firstValue屬性在Java代碼中的確更換

@XmlElement(name = "Value", required = true) 
protected ParameterValueType firstValue; 
@XmlElements({ 
    @XmlElement(name = "Threshold", type = LiteralType.class), 
    @XmlElement(name = "Value", type = ParameterValueType.class) 
}) 
protected List<Object> thresholdAndValue; 

public ParameterValueType getFirstValue() { 
    return firstValue; 
} 
public void setFirstValue(ParameterValueType value) { 
    this.firstValue = value; 
} 
public List<Object> getThresholdAndValue() { 
    if (thresholdAndValue == null) { 
     thresholdAndValue = new ArrayList<Object>(); 
    } 
    return this.thresholdAndValue; 
} 

不幸的是,我仍然能獲得同樣的結果 - 我仍然不能在由getThresholdAndValues()返回的列表中查看我的值。我還在探索定製的方式...

+0

getThresholdAndValue方法的註釋是什麼?這是有趣的部分,而不是方法體。 – skaffman

+0

無。我可以在課堂上找到唯一的註釋,並在課堂上和屬性上進行設置。他們都沒有設置方法... – Agemen

+0

有趣的問題 - 請你可以發佈完整的模式? – davidfrancis

回答

1

我認爲你需要周圍

  <xsd:sequence minOccurs="0" maxOccurs="unbounded"> 
       <xsd:element ref="se:Threshold"/> 
       <xsd:element ref="se:Value"/> 
      </xsd:sequence> 

一個complexType元素可以插入XSLT轉換運行XJC之前的complexType添加到模式的定義?

+0

是的,這可能是一個解決方案。由於我以前從未使用XSLT,因此需要一些時間:-p。我已經確定這個清單是我的問題的關鍵,如果它是以單獨的複雜類型定義的話,它會簡單得多。但是因爲我不習慣XSLT,所以我沒有想到要使用它。我會嘗試它,因爲我可以自由定製XML的編譯(即使我無法觸及XML本身)。 – Agemen

+0

但是,我害怕的是,我不希望對使用此XSD定義的文件進行任何轉換。因此,如果沒有任何中間元素,我必須能夠讀取價值閾值列表... – Agemen

3

更新:對不起,我不得不放棄這一點,我也無法讓它工作(如果你可以改變你的模式,會更容易!)。我正在使用Codehaus JAXB maven plugin。我敢肯定,這是造成兩個價值元素,我試圖用XJB定製解決衝突:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<jxb:bindings jxb:version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <jxb:bindings schemaLocation="../xsd/example.xsd" node="/xsd:schema"> 
     <jxb:schemaBindings> 
      <jxb:package name="com.example" /> 
      <jxb:nameXmlTransform> 
       <jxb:elementName suffix="Element"/> 
      </jxb:nameXmlTransform> 
     </jxb:schemaBindings> 
    </jxb:bindings> 
</jxb:bindings> 

它絕對沒有影響。我試過<jxb:typeName suffix="Element"/>,它重命名了所有的JAXB類,所以我認爲jxb:elementName功能存在一個錯誤。

原貼:

我一直在看這一點,我可以複製你的問題。

我花了一些自由與您的架構來簡化的事情,但它仍然包含的基本要素。下面是我一直使用的是什麼:

<?xml version="1.0" encoding="UTF-8"?> 
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:se="http://com.example/example" 
     targetNamespace="http://com.example/example" 
    elementFormDefault="qualified"> 

    <xsd:element name="Categorize" type="se:CategorizeType" /> 

    <xsd:complexType name="FunctionType"> 
    </xsd:complexType> 

    <xsd:simpleType name="Value"> 
     <xsd:restriction base="xsd:string"/> 
    </xsd:simpleType> 

    <xsd:simpleType name="Threshold"> 
     <xsd:restriction base="xsd:string"/> 
    </xsd:simpleType> 

    <xsd:complexType name="CategorizeType"> 
     <xsd:complexContent> 
      <xsd:extension base="se:FunctionType"> 
       <xsd:sequence> 
        <xsd:element name="Value" type="se:Value" /> 
        <xsd:sequence minOccurs="0" maxOccurs="unbounded"> 
         <xsd:element name="Threshold" type="se:Threshold" /> 
         <xsd:element name="Value" type="se:Value" /> 
        </xsd:sequence> 
       </xsd:sequence> 
      </xsd:extension> 
     </xsd:complexContent> 
    </xsd:complexType> 
</xsd:schema> 

我已經刪除/屬性不相關的問題的任何元素,使用name/type代替ref,並定義的類型從提供的模式失蹤。

我產生JAXB CategorizeType類的樣子:

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "CategorizeType", propOrder = { 
    "value", 
    "thresholdAndValue" 
}) 
public class CategorizeType 
    extends FunctionType 
{ 

    @XmlElement(name = "Value", required = true) 
    protected String value; 
    @XmlElementRefs({ 
     @XmlElementRef(name = "Value", 
      namespace = "http://com.example/example", type = JAXBElement.class), 
     @XmlElementRef(name = "Threshold", 
      namespace = "http://com.example/example", type = JAXBElement.class) 
    }) 
    protected List<JAXBElement<String>> thresholdAndValue; 

    ... 
} 

當我解組你的XML,我Categorize.Value是0.8(而不是預期的0.3),並且每個ThresholdAndValue的(值在所有Strings我案件)是30.0, 40.0, 45.00.4, 0.45等缺失。

當我從模式中刪除第一個Value元素,然後取消編組時,我得到了所有期望的值,所以肯定存在衝突!

然而,當使用以下JAXB設置我馬歇爾:

ObjectFactory factory = new ObjectFactory(); 
CategorizeType catType = factory.createCategorizeType(); 
catType.setValue("0.3"); 
JAXBElement<String> thresh = factory.createCategorizeTypeThreshold("30.0"); 
JAXBElement<String> threshVal = factory.createCategorizeTypeValue("0.4"); 
JAXBElement<String> thresh2 = factory.createCategorizeTypeThreshold("40.0"); 
JAXBElement<String> threshVal2 = factory.createCategorizeTypeValue("0.45"); 
catType.getThresholdAndValue().add(thresh); 
catType.getThresholdAndValue().add(threshVal); 
catType.getThresholdAndValue().add(thresh2); 
catType.getThresholdAndValue().add(threshVal2); 
JAXBElement<CategorizeType> element = factory.createCategorize(catType); 
// marshall to XML here! 

我得到預期的輸出:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<Categorize xmlns="http://com.example/example"> 
    <Value>0.3</Value> 
    <Threshold>30.0</Threshold> 
    <Value>0.4</Value> 
    <Threshold>40.0</Threshold> 
    <Value>0.45</Value> 
</Categorize> 

我會繼續尋找這個!