укажите тип IDREF в XML-схеме
я генерирую объекты Java из схемы XML с помощью xjc. Я хотел бы ссылаться на один и тот же элемент несколько раз в документе, используя IDREF. Я также хотел бы ограничить объекты, на которые ссылается IDREF, определенным типом. Я хотел бы сделать это для целей проверки схемы, но также и для того, чтобы в коде Java ссылочный объект возвращался как определенный тип вместо объекта типа. Например, скажем, мне нужна схема для описания следующий:
<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>
Я могу определить player
такой:
<xs:element name="player" type="xs:IDREF" maxOccurs="unbounded"/>
но тогда в коде Java, когда я пытаюсь получить плеер, он вернется как объект типа, и я должен бросить его человеку. В этот момент, если кто-то ошибочно ссылается на объект Team, у меня есть ошибки, с которыми можно было бы справиться при проверке. Я хочу указать что-то вроде этого:
<xs:element name="player" type="xs:IDREF"
reftype="person"
maxOccurs="unbounded" />
но насколько я могу сказать, что нет способа указать тип, как я сделал здесь с надуманным атрибутом 'reftype'. Можно ли это сделать, используя IDREF? Если нет, то есть ли другой способ?
2 ответов
вы можете просто применить baseType
привязка к вашему player
элемент. Что-то вроде:
<jaxb:bindings node="xsd:element[@name='player']">
<jaxb:property>
<jaxb:baseType name="....Person"/>
</jaxb:property>
</jaxb:bindings>
возможно, Вам потребуется определить правильное расположение привязки для вашей схемы.
пример из моего кода:
схема:
<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>
горячие клавиши:
<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>
сгенерированный код:
@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;
см.: https://svn.java.net/svn/hj3~svn/trunk/ejb/tests/issues-jpa2/src/main/resources/
ответ лексикора дал мне то, что мне нужно (и я предлагаю проголосовать за его ответ над моим). Однако я использую встроенные аннотации вместо отдельного файла Привязок. Вот как это выглядит со встроенными аннотациями, используя мой пример 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>