2011-06-14 75 views
11

我想在子對象和父對象之間的類中使用雙向導航方法。 在我的情況下IDREF是不夠的,因爲我不想指定父代的ID。 是明確的,從這樣的一個xsd:JAXB/XJC親子導航

<complexType name="A"> 
    <xs:sequence> 
     <element name="b" type="B" minOccurs="0" maxOccurs="unbounded"></element> 
    </xs:sequence> 
    <attribute name="id" type="ID"></attribute> 
</complexType> 
<complexType name="B"> 
    <attribute name="id" type="ID"></attribute> 
</complexType> 

我想類看起來是這樣的:

class A { 
    ... 
    public List<B> getB() { ...} 
    ... 
    } 
class B { 
    ... 
    public A getA() { 
    ... 
} 

和我的XML必須是這樣的:

<a id="a1"> 
    <b id="b1"/> 
    <b id="b2"/> 
    ... 
</a> 

後解組,我希望能夠導航A到B,並從B到A(通過b.getA())! 這是一個非常基本的功能,但我沒有找到一個簡單的方法來實現...

任何想法??

在此先感謝

+0

這可能有助於你:http://stackoverflow.com/questions/5319024/using-jaxb-to-cross-reference-xmlids-from-two-xml-files – Cris 2011-06-14 11:47:11

回答

13

您可以create a methodvoid afterUnmarshal(Unmarshaller, Object parent)被調用......嗯,解編後設置你的對象樹,你需要它。

+0

非常感謝這是基於xsd的最簡單的解決方案。 – fedevo 2011-06-14 13:08:31

+0

但是,如果在每次生成運行中從XSD創建類,我該如何利用此方法?我無法修改由XJC創建的類。 – migu 2011-11-29 10:09:36

+0

現在我明白了:Unmarshaller的javadoc評論很具誤導性,他說「'Class defined'事件回調方法允許任何JAXB映射類通過使用以下方法簽名定義方法來指定其自己特定的回調方法。」 - 實際上,偵聽器不需要是JAXB映射的類!只需實現一個監聽器類來完成工作並將其註冊到解組器實例。而已。 – migu 2011-11-29 10:28:38

0
<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> 
    <xs:complexType name="A"> 
    <xs:sequence> 
     <xs:element name="b" type="B" minOccurs="0" maxOccurs="unbounded"> 
     </xs:element> 
    </xs:sequence> 
    <xs:attribute name="id" type="xs:ID"></xs:attribute> 
</xs:complexType> 
<xs:complexType name="B"> 
<xs:sequence> 
    <xs:element name="a" type="A" minOccurs="1" maxOccurs="1"/> 
    </xs:sequence> 
</xs:complexType> 
<xs:attribute name="id" type="xs:ID"></xs:attribute> 
</xs:schema> 

嘗試......

3

注:我是EclipseLink JAXB (MOXy)鉛和JAXB的成員(JSR-222)專家小組。

Eclipse JAXB(MOXy)提供@XmlInverseReference擴展來處理此用例。目前,它不能被XJC生成,必須應用到域模型直接:

class A { 
    ... 
    public List<B> getB() { ...} 
    ... 
    } 

class B { 
    ... 
    @XmlInverseReference(mappedBy="b") 
    public A getA() { 
    ... 
} 

更多信息

+0

謝謝,但我的入口點是xsd ... – fedevo 2011-06-14 13:10:26

3

除了musiKk答案如果您使用xjc從xsd生成域模型類。 要在所有的模型類添加引用父類,你應該:

  1. 創建延伸Unmarshaller.Listener

    public abstract class BaseClass extends Unmarshaller.Listener { 
        protected Object parent; 
    
        public void afterUnmarshal(Unmarshaller unmarshaller, Object parent)  { 
         this.parent = parent; 
        } 
    
        public Object getParent(){ 
         return parent; 
        } 
    } 
    
  2. 告訴XJC所有的模型類應該通過創建全球XJC綁定擴展您的BaseClass基類配置

    <jaxb:globalBindings> 
        <xjc:superClass name="com.acme.BaseClass" /> 
    </jaxb:globalBindings>