2013-04-29 14 views
10

Sto generando oggetti Java da uno schema XML utilizzando xjc. Vorrei fare riferimento allo stesso elemento più volte all'interno del documento utilizzando IDREF. Vorrei anche limitare gli oggetti referenziati da IDREF a un tipo specifico. Mi piacerebbe farlo ai fini della convalida dello schema, ma anche in modo che nel codice Java, l'oggetto di riferimento sia restituito come tipo specifico invece di tipo Oggetto. Ad esempio, dire che voglio uno schema per descrivere le seguenti:specificare il tipo per IDREF nello schema XML

<teams> 
    <team id="team1"> 
    <coach>coachz</coach> 
    <player>homestar</player> 
    <player>marzipan</player> 
    <player>strongsad</player> 
    <player>strongbad</player> 
    </team> 

    <team id="team2"> 
    <coach>bubs</coach> 
    <player>homesar</player> 
    <player>thecheat</player> 
    <player>poopsmith</player> 
    <player>bubs</player> 
    </team> 

    <team id="allstars"> 
    <coach>poopsmith</coach> 
    <player>coachz</player> 
    <player>bubs</player> 
    <player>kingoftown</player> 
    <player>strongbad</player> 
    </team> 
</teams> 

<people> 
<person id="coachz">Coach Z</person> 
<person id="homesar">Homesar</person> 
<person id="homestar">Homestar</person> 
<person id="strongbad">Strong Bad</person> 
<person id="strongsad">Strong Sad</person> 
<person id="marzipan">Marzipan</person> 
<person id="bubs">Bubs</person> 
<person id="kingoftown">King of Town</person> 
<person id="poopsmith">The Poopsmith</person> 
<person id="thecheat">The Cheat</person> 
</people> 

posso definire player in questo modo:

<xs:element name="player" type="xs:IDREF" maxOccurs="unbounded"/> 

ma poi nel codice Java, quando si tenta di recuperare un giocatore lo farà torna come tipo oggetto, e devo lanciarlo su una persona. A quel punto, se qualcuno ha erroneamente fatto riferimento a un oggetto Team, ho degli errori da trattare che potrebbero essere stati scoperti durante la convalida. Voglio specificare qualcosa di simile:

<xs:element name="player" type="xs:IDREF"reftype="person"maxOccurs="unbounded" />

Ma per quanto ne so, non c'è modo di specificare un tipo come ho fatto qui con l'attributo artificioso 'reftype'. Questo può essere fatto usando IDREF? Se no, c'è un altro metodo?

+0

Un riferimento a Homestar Runner? +1 –

risposta

11

È possibile applicare semplicemente il collegamento baseType all'elemento player. Qualcosa di simile:

<jaxb:bindings node="xsd:element[@name='player']"> 
    <jaxb:property> 
     <jaxb:baseType name="....Person"/> 
    </jaxb:property> 
</jaxb:bindings> 

Potrebbe essere necessario calcolare la posizione di rilegatura corretta per lo schema.

Esempio dal mio codice:

schema:

<xsd:complexType name="HJIII-53-A"> 
    <xsd:sequence> 
     <xsd:element name="b" type="xsd:IDREF"/> 
     <xsd:element name="b1" type="test:HJIII-53-B"/> 
     <xsd:element name="c" type="xsd:IDREFS"/> 
     <xsd:element name="c1" type="test:HJIII-53-C" minOccurs="0" maxOccurs="unbounded"/> 
    </xsd:sequence> 
</xsd:complexType> 

Attacchi:

<jaxb:bindings schemaLocation="schema.xsd" node="/xsd:schema"> 
    <jaxb:globalBindings localScoping="toplevel"> 
     <jaxb:serializable/> 
    </jaxb:globalBindings> 
    <jaxb:bindings node="xsd:complexType[@name='HJIII-53-A']//xsd:element[@name='b']"> 
     <jaxb:property> 
      <jaxb:baseType name="org.jvnet.hyperjaxb3.ejb.tests.issuesjpa2.HJIII53B"/> 
     </jaxb:property> 
    </jaxb:bindings> 
    <jaxb:bindings node="xsd:complexType[@name='HJIII-53-A']//xsd:element[@name='c']"> 
     <jaxb:property> 
      <jaxb:baseType name="org.jvnet.hyperjaxb3.ejb.tests.issuesjpa2.HJIII53C"/> 
     </jaxb:property> 
    </jaxb:bindings> 
</jaxb:bindings> 

codice generato:

@XmlElement(required = true, type = Object.class) 
@XmlIDREF 
@XmlSchemaType(name = "IDREF") 
protected org.jvnet.hyperjaxb3.ejb.tests.issuesjpa2.HJIII53B b; 
@XmlElement(required = true) 
protected org.jvnet.hyperjaxb3.ejb.tests.issuesjpa2.HJIII53B b1; 
@XmlList 
@XmlElement(required = true, type = Object.class) 
@XmlIDREF 
protected List<org.jvnet.hyperjaxb3.ejb.tests.issuesjpa2.HJIII53C> c; 
protected List<org.jvnet.hyperjaxb3.ejb.tests.issuesjpa2.HJIII53C> c1; 

See: https://svn.java.net/svn/hj3~svn/trunk/ejb/tests/issues-jpa2/src/main/resources/

+0

Ha funzionato come un fascino! Sto usando annotazioni in linea. Aggiungerò una risposta che mostra come l'ho fatto. – undefined

+0

ha! il jaxb binding è esattamente quello che stavo cercando. Grazie ! Purtroppo non sembra funzionare bene con la funzione hashcode generata da jaxb2-basics – Newtopian

10

La risposta del lessico mi ha dato ciò di cui ho bisogno (e suggerisco di votare la sua risposta al mio). Tuttavia sto usando annotazioni inline invece di un file di binding separato. Questo è ciò che appare con le annotazioni in linea, usando il mio esempio Homestar:

<xs:element name="player" type="xs:IDREF" maxoccurs="unbounded"> 
    <xs:annotation> 
    <xs:appinfo> 
     <jaxb:property> 
     <jaxb:baseType name="Person"/> 
     </jaxb:property> 
    </xs:appinfo> 
    </xs:annotation> 
</xs:element> 
Problemi correlati