Drewman
Drewman

Reputation: 947

JaxB - how to not map a specific XML node

Here is my problem:

I'm working on a project to migrate from Castor to JaxB. I am very new to JaxB and facing a problem which boggles my mind and yet, may be quite simple to solve. Here is a simple example :

class Data
{
    private Item item;
}

I have Data containing one Item. Here is how the output XML file (which I cannot change) looks like:

<Data>
    <Items>
        <Item>
        <Item>
    <Items>
<Data>

Even though Data contains only one Item, it should be presented in the output XML as an element in Items. The thing is, I do not want JaxB to generate a class or property for Items, only Data and Item.

How should my schema look like? Is there any way to specify in the schema that the specified item is stored in a node which has no class representation? Something which in my logic could look like that:

  <xs:element name="Data">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Items"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name="Items"> <!-- Do not generate plz -->
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Item" minOccurs="1" maxOccurs="1"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

Upvotes: 2

Views: 667

Answers (3)

Mike Summers
Mike Summers

Reputation: 2239

Using standard JAXB annotations:

class Data{
  @XmlElementWrapper(name="Items")
  @XmlElement(name="Item")
  private Item[] item;     // An array with just one Item
}

Upvotes: 0

bdoughan
bdoughan

Reputation: 149037

Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB 2 (JSR-222) expert group.

For the following fragment, there isn't a way to generate the classes in that way, because the standard JAXB APIs don't provide path based mapping.

  <xs:element name="Items"> <!-- Do not generate plz -->
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Item" minOccurs="1" maxOccurs="1"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

However, starting from Java classes you could use MOXy's @XmlPath extension to map this use case:

import org.eclipse.persistence.annotations.oxm.XmlPath;

class Data
{
    @XmlPath("Items/Item")
    private Item item;
}

For More Information

Upvotes: 1

tdrury
tdrury

Reputation: 2338

One option is to write your own jaxb plugin: you can find an introduction here: http://weblogs.java.net/blog/kohsuke/archive/2005/06/writing_a_plugi.html. Within your plugin, you generate code using the Codemodel API; I've blogged about that here: http://www.sdn.sap.com/irj/scn/weblogs?blog=/pub/wlg/21495. When XJC gets to your "Items" element, it will pass control to you and in your plugin, you'd simply ignore it and create the setter/getter for the underlying "Item" element instead. I'm sure there are other variations that are just as valid.

Upvotes: 0

Related Questions