DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workkloads.

Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • How to Convert XLS to XLSX in Java
  • Thread-Safety Pitfalls in XML Processing
  • Loading XML into MongoDB
  • SmartXML: An Alternative to XPath for Complex XML Files

Trending

  • *You* Can Shape Trend Reports: Join DZone's Software Supply Chain Security Research
  • Segmentation Violation and How Rust Helps Overcome It
  • Chaos Engineering for Microservices
  • Zero Trust for AWS NLBs: Why It Matters and How to Do It
  1. DZone
  2. Coding
  3. Languages
  4. How Does JAXB Compare to XMLBeans?

How Does JAXB Compare to XMLBeans?

By 
Blaise Doughan user avatar
Blaise Doughan
·
Feb. 01, 12 · Interview
Likes (0)
Comment
Save
Tweet
Share
25.4K Views

Join the DZone community and get the full member experience.

Join For Free

In previous posts I compared JAXB (JSR-222) to Simple and XStream when starting from Java objects.  In this post I'll compare JAXB to XMLBeans when starting from an XML schema.   I will use XMLBeans 2.5.0 (December 2009) which is the latest release.


XML Schema (customer.xsd)

Below is the XML schema that will be used to generate our domain models.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns="http://www.example.com"
    targetNamespace="http://www.example.com"
    elementFormDefault="qualified">
 
    <xs:element name="customer">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="name" type="xs:string"/>
                <xs:element name="address" type="address"/>
                <xs:element
                    name="phone-number"
                    type="phone-number"
                    minOccurs="0"
                    maxOccurs="unbounded"/>
             </xs:sequence>
        </xs:complexType>
    </xs:element>
 
    <xs:complexType name="address">
        <xs:sequence>
            <xs:element name="street" type="xs:string"/>
            <xs:element name="city" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
 
    <xs:complexType name="phone-number">
        <xs:simpleContent>
            <xs:extension base="xs:string">
                <xs:attribute name="type" type="xs:string"/>
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>
 
</xs:schema>


Generating the Classes

XMLBeans

Below is the call to generate the XMLBeans classes from our XML schema.  For the purposes of this example we will use the -srconly flag to generate only the source.

1
scomp -d out -srconly customer.xsd

Below are all the artifacts that are generated by XMLBeans.  The XML Schema Binary (XSB) files contain metadata need to perform binding and validation:
  • com/example
    • Address.java
    • CustomerDocument.java
    • PhoneNumber.java
  • com/example/impl
    • AddressImpl.java
    • CustomerDocumentImpl.java
    • PhoneNumberImpl.java
  • schemaorg_apache_xmlbeans
    • element/http_3A_2F_2Fwww_2Eexample_2Ecom
      • customer.xsb
    • javaname/com/example
      • Address.xsb
      • CustomerDocument.xsb
      • PhoneNumber.xsb
    •  
      • CustomerDocument
        •  Customer.xsb
    • namespace/http_3A_2F_2Fwww_2Eexample_2Ecom
      • xmlns.xsb
    • src
      • customer.xsd
    •  system/s16C99350D7D3A2544A7BFD5E35CA8BC8
      •  address6f49type.xsb
      •  customer3fdddoctype.xsb
      •  customer11d7elemtype.xsb
      •  customerelement.xsb
      •  index.xsb
      •  phonenumber9c83type.xsb
      •  TypeSystemHolder.class
    • type/http_3A_2F_2Fwww_2Eexample_2Ecom
      • address.xsb
      • phone_2Dnumber.xsb
JAXB

Below is the call to generate the JAXB classes from an XML schema:

1
xjc -d out customer.xsd 

Below are all the artifacts that are generated by JAXB. Note how many fewer artifacts are created:
  • com.example
    • Address.java
    • Customer.java
    • ObjectFactory.java
    • package-info.java
    • PhoneNumber.java

Java Model - XMLBeans

XMLBeans produces a set of Java interfaces that are backed by implementation classes.  Below we will examine one of these pairs.

Address

This is one of the interfaces that is generated by XMLBeans.  There are a few interesting things worth noting:
  • This interface exposes POJO properties (line 24), and a DOM like model (line 29).
  • This interface includes a factory (line 66).  This factory is used for creating instances of the Address object (line 68), and for unmarshalling instances of Address from XML (line 75).

package com.example;
 
 
/**
 * An XML address(@http://www.example.com).
 *
 * This is a complex type.
 */
public interface Address extends org.apache.xmlbeans.XmlObject
{
    public static final org.apache.xmlbeans.SchemaType type = (org.apache.xmlbeans.SchemaType)
        org.apache.xmlbeans.XmlBeans.typeSystemForClassLoader(Address.class.getClassLoader(), "schemaorg_apache_xmlbeans.system.s16C99350D7D3A2544A7BFD5E35CA8BC8").resolveHandle("address6f49type");
     
    /**
     * Gets the "street" element
     */
    java.lang.String getStreet();
     
    /**
     * Gets (as xml) the "street" element
     */
    org.apache.xmlbeans.XmlString xgetStreet();
     
    /**
     * Sets the "street" element
     */
    void setStreet(java.lang.String street);
     
    /**
     * Sets (as xml) the "street" element
     */
    void xsetStreet(org.apache.xmlbeans.XmlString street);
     
    /**
     * Gets the "city" element
     */
    java.lang.String getCity();
     
    /**
     * Gets (as xml) the "city" element
     */
    org.apache.xmlbeans.XmlString xgetCity();
     
    /**
     * Sets the "city" element
     */
    void setCity(java.lang.String city);
     
    /**
     * Sets (as xml) the "city" element
     */
    void xsetCity(org.apache.xmlbeans.XmlString city);
     
    /**
     * A factory class with static methods for creating instances
     * of this type.
     */
     
    public static final class Factory
    {
        public static com.example.Address newInstance() {
          return (com.example.Address) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newInstance( type, null ); }
         
        public static com.example.Address newInstance(org.apache.xmlbeans.XmlOptions options) {
          return (com.example.Address) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newInstance( type, options ); }
         
        /** @param xmlAsString the string value to parse */
        public static com.example.Address parse(java.lang.String xmlAsString) throws org.apache.xmlbeans.XmlException {
          return (com.example.Address) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xmlAsString, type, null ); }
         
        public static com.example.Address parse(java.lang.String xmlAsString, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException {
          return (com.example.Address) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xmlAsString, type, options ); }
         
        /** @param file the file from which to load an xml document */
        public static com.example.Address parse(java.io.File file) throws org.apache.xmlbeans.XmlException, java.io.IOException {
          return (com.example.Address) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( file, type, null ); }
         
        public static com.example.Address parse(java.io.File file, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException {
          return (com.example.Address) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( file, type, options ); }
         
        public static com.example.Address parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException {
          return (com.example.Address) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( u, type, null ); }
         
        public static com.example.Address parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException {
          return (com.example.Address) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( u, type, options ); }
         
        public static com.example.Address parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException {
          return (com.example.Address) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( is, type, null ); }
         
        public static com.example.Address parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException {
          return (com.example.Address) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( is, type, options ); }
         
        public static com.example.Address parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException {
          return (com.example.Address) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( r, type, null ); }
         
        public static com.example.Address parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException {
          return (com.example.Address) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( r, type, options ); }
         
        public static com.example.Address parse(javax.xml.stream.XMLStreamReader sr) throws org.apache.xmlbeans.XmlException {
          return (com.example.Address) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( sr, type, null ); }
         
        public static com.example.Address parse(javax.xml.stream.XMLStreamReader sr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException {
          return (com.example.Address) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( sr, type, options ); }
         
        public static com.example.Address parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException {
          return (com.example.Address) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( node, type, null ); }
         
        public static com.example.Address parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException {
          return (com.example.Address) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( node, type, options ); }
         
        /** @deprecated {@link org.apache.xmlbeans.xml.stream.XMLInputStream} */
        public static com.example.Address parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException {
          return (com.example.Address) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xis, type, null ); }
         
        /** @deprecated {@link org.apache.xmlbeans.xml.stream.XMLInputStream} */
        public static com.example.Address parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException {
          return (com.example.Address) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xis, type, options ); }
         
        /** @deprecated {@link org.apache.xmlbeans.xml.stream.XMLInputStream} */
        public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException {
          return org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); }
         
        /** @deprecated {@link org.apache.xmlbeans.xml.stream.XMLInputStream} */
        public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException {
          return org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); }
         
        private Factory() { } // No instance of this class allowed
    }
}
AddressImpl

Below is the source for the implementation class:

/**
 * XML Type:  address
 * Namespace: http://www.example.com
 * Java type: com.example.Address
 *
 * Automatically generated - do not modify.
 */
package com.example.impl;
/**
 * An XML address(@http://www.example.com).
 *
 * This is a complex type.
 */
public class AddressImpl extends org.apache.xmlbeans.impl.values.XmlComplexContentImpl implements com.example.Address
{
    private static final long serialVersionUID = 1L;
     
    public AddressImpl(org.apache.xmlbeans.SchemaType sType)
    {
        super(sType);
    }
     
    private static final javax.xml.namespace.QName STREET$0 =
        new javax.xml.namespace.QName("http://www.example.com", "street");
    private static final javax.xml.namespace.QName CITY$2 =
        new javax.xml.namespace.QName("http://www.example.com", "city");
     
     
    /**
     * Gets the "street" element
     */
    public java.lang.String getStreet()
    {
        synchronized (monitor())
        {
            check_orphaned();
            org.apache.xmlbeans.SimpleValue target = null;
            target = (org.apache.xmlbeans.SimpleValue)get_store().find_element_user(STREET$0, 0);
            if (target == null)
            {
                return null;
            }
            return target.getStringValue();
        }
    }
     
    /**
     * Gets (as xml) the "street" element
     */
    public org.apache.xmlbeans.XmlString xgetStreet()
    {
        synchronized (monitor())
        {
            check_orphaned();
            org.apache.xmlbeans.XmlString target = null;
            target = (org.apache.xmlbeans.XmlString)get_store().find_element_user(STREET$0, 0);
            return target;
        }
    }
     
    /**
     * Sets the "street" element
     */
    public void setStreet(java.lang.String street)
    {
        synchronized (monitor())
        {
            check_orphaned();
            org.apache.xmlbeans.SimpleValue target = null;
            target = (org.apache.xmlbeans.SimpleValue)get_store().find_element_user(STREET$0, 0);
            if (target == null)
            {
                target = (org.apache.xmlbeans.SimpleValue)get_store().add_element_user(STREET$0);
            }
            target.setStringValue(street);
        }
    }
     
    /**
     * Sets (as xml) the "street" element
     */
    public void xsetStreet(org.apache.xmlbeans.XmlString street)
    {
        synchronized (monitor())
        {
            check_orphaned();
            org.apache.xmlbeans.XmlString target = null;
            target = (org.apache.xmlbeans.XmlString)get_store().find_element_user(STREET$0, 0);
            if (target == null)
            {
                target = (org.apache.xmlbeans.XmlString)get_store().add_element_user(STREET$0);
            }
            target.set(street);
        }
    }
     
    /**
     * Gets the "city" element
     */
    public java.lang.String getCity()
    {
        synchronized (monitor())
        {
            check_orphaned();
            org.apache.xmlbeans.SimpleValue target = null;
            target = (org.apache.xmlbeans.SimpleValue)get_store().find_element_user(CITY$2, 0);
            if (target == null)
            {
                return null;
            }
            return target.getStringValue();
        }
    }
     
    /**
     * Gets (as xml) the "city" element
     */
    public org.apache.xmlbeans.XmlString xgetCity()
    {
        synchronized (monitor())
        {
            check_orphaned();
            org.apache.xmlbeans.XmlString target = null;
            target = (org.apache.xmlbeans.XmlString)get_store().find_element_user(CITY$2, 0);
            return target;
        }
    }
     
    /**
     * Sets the "city" element
     */
    public void setCity(java.lang.String city)
    {
        synchronized (monitor())
        {
            check_orphaned();
            org.apache.xmlbeans.SimpleValue target = null;
            target = (org.apache.xmlbeans.SimpleValue)get_store().find_element_user(CITY$2, 0);
            if (target == null)
            {
                target = (org.apache.xmlbeans.SimpleValue)get_store().add_element_user(CITY$2);
            }
            target.setStringValue(city);
        }
    }
     
    /**
     * Sets (as xml) the "city" element
     */
    public void xsetCity(org.apache.xmlbeans.XmlString city)
    {
        synchronized (monitor())
        {
            check_orphaned();
            org.apache.xmlbeans.XmlString target = null;
            target = (org.apache.xmlbeans.XmlString)get_store().find_element_user(CITY$2, 0);
            if (target == null)
            {
                target = (org.apache.xmlbeans.XmlString)get_store().add_element_user(CITY$2);
            }
            target.set(city);
        }
    }
}

Java Model - JAXB

JAXB implementations produce annotated POJOs.  The generated classes closely resemble the ones we created by hand in the comparisons to Simple and XStream.

Address


//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 in JDK 6
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2012.01.23 at 01:19:09 PM EST
//
 
 
package com.example;
 
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
 
 
/**
 * <p>Java class for address complex type.
 *
 * <p>The following schema fragment specifies the expected content contained within this class.
 *
 * <pre>
 * <complexType name="address">
 *   <complexContent>
 *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       <sequence>
 *         <element name="street" type="{http://www.w3.org/2001/XMLSchema}string"/>
 *         <element name="city" type="{http://www.w3.org/2001/XMLSchema}string"/>
 *       </sequence>
 *     </restriction>
 *   </complexContent>
 * </complexType>
 * </pre>
 *
 *
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "address", propOrder = {
    "street",
    "city"
})
public class Address {
 
    @XmlElement(required = true)
    protected String street;
    @XmlElement(required = true)
    protected String city;
 
    /**
     * Gets the value of the street property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *    
     */
    public String getStreet() {
        return street;
    }
 
    /**
     * Sets the value of the street property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *    
     */
    public void setStreet(String value) {
        this.street = value;
    }
 
    /**
     * Gets the value of the city property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *    
     */
    public String getCity() {
        return city;
    }
 
    /**
     * Sets the value of the city property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *    
     */
    public void setCity(String value) {
        this.city = value;
    }
 
}
Demo Code

In the demo code we will unmarshal an XML file, add a phone number to the resulting customer object, and then marshal the customer back to XML.

XMLBeans

With XMLBeans the generated domain model is used to unmarshal (line 12) and marshal (line 19).  The generated model also contains methods for interacting with collections (line 15), this is necessary as XMLBeans represent collection properties as arrays.

package com.example;
 
import java.io.File;
import com.example.CustomerDocument.Customer;
 
public class Demo {
 
    public static void main(String[] args) throws Exception {
        File xml = new File("src/com/example/input.xml");
 
        CustomerDocument customerDocument =
            CustomerDocument.Factory.parse(xml);
        Customer customer = customerDocument.getCustomer();
 
        PhoneNumber homePhoneNumber = customer.addNewPhoneNumber();
        homePhoneNumber.setType("home");
        homePhoneNumber.set("555-HOME");
 
        customerDocument.save(System.out);
    }
 
}

JAXB

JAXB separates the marshal/unmarshal calls into the standard runtime APIs (lines 9, 13 and 22).  A java.util.List is used for collection properties (line 18).


package com.example;
 
import java.io.File;
import javax.xml.bind.*;
 
public class Demo {
 
    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance("com.example");
 
        File xml = new File("src/com/example/input.xml");
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        Customer customer = (Customer) unmarshaller.unmarshal(xml);
 
        PhoneNumber homePhoneNumber = new PhoneNumber();
        homePhoneNumber.setType("home");
        homePhoneNumber.setValue("555-HOME");
        customer.getPhoneNumber().add(homePhoneNumber);
 
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(customer, System.out);
    }
 
}
Summary

Both XMLBeans and JAXB produce Java models that make it easy for developers to interact with XML.  The JAXB model however is annotated POJOs which has the following advantages:

  • JPA annotations could easily be applied to the JAXB model enabling the model to be persisted in a relational database.
  • Once generated the JAXB model could be modified to handle changes in the XML schema, the XMLBeans model would need to be regenerated.
  • Starting with Java SE 6 no additional compile/runtime dependencies are required for the JAXB model. 
  • There are multiple JAXB implementations available:  EclipseLink MOXy, Metro, Apache JaxMe, etc.
  • JAXB is the standard binding layer for JAX-WS (SOAP) and JAX-RS (RESTful) Web Services.

 

From http://blog.bdoughan.com/2012/01/how-does-jaxb-compare-to-xmlbeans.html

XML

Opinions expressed by DZone contributors are their own.

Related

  • How to Convert XLS to XLSX in Java
  • Thread-Safety Pitfalls in XML Processing
  • Loading XML into MongoDB
  • SmartXML: An Alternative to XPath for Complex XML Files

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!