Eclipse Implementation of JAXB Extensions
Prev |  | Next

Links: Table of Contents | Single HTML | Single PDF

# Eclipse Implementation of JAXB Extensions

## 1. Overview

This page contains information about vendor-specific features provided by the Eclipse Implementation of JAXB.

Runtime Properties

  This document describes Eclipse Implementation of JAXB specific properties that affect the way that the Jakarta XML Binding runtime library behaves.

XJC Customizations

  This document describes additional binding customizations that can be used to control the generated source code.

DTD

  This document describes the Eclipse Implementation of JAXB's experimental support for W3C XML Schema features not currently described in the Jakarta XML Binding Specification as well as support for other schema languages (RELAX NG and DTD).

## 2. Runtime Properties

### 2.1. Marshaller Properties

The Eclipse Implementation of JAXB provides additional Marshaller properties that are not defined by the Jakarta XML Binding specification. These properties allow you to better control the marshalling process, but they only work with the Eclipse Implementation of JAXB; they may not work with other Jakarta XML Binding providers.

#### 2.1.1. Index of Marshaller Properties

- Namespace Prefix Mapping

- Indentation

- Character Escaping Control

- XML Declaration Control

- Jaxb Annotation Control

#### 2.1.2. Namespace Prefix Mapping

Property name: | `org.glassfish.jaxb.namespacePrefixMapper`
Type: | `org.glassfish.jaxb.runtime.marshaller.NamespacePrefixMapper`
Default value: | null

The Eclipse Implementation of JAXB provides a mechanism for users to control declarations of namespace URIs and what prefixes they will be bound to. This is the general procedure:

1. The application developer provides an implementation of `org.glassfish.jaxb.runtime.marshaller.NamespacePrefixMapper`.

2. This class is then set on the marshaller via the RI specific property `org.glassfish.jaxb.namespacePrefixMapper`.

3. Each time the marshaller sees a URI, it performs a callback on the mapper: "What prefix do you want for this namespace URI?"

4. If the mapper returns something, the marshaller will try to use it.

The `org.glassfish.jaxb.runtime.marshaller.NamespacePrefixMapper` class has the following method that you need to implement:

    /**
     * Implemented by the user application to determine URI -> prefix
     * mapping.
     *
     * This is considered as an interface, though it's implemented
     * as an abstract class to make it easy to add new methods in
     * a future.
     *
     * @author
     *     Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
     */
    public abstract class NamespacePrefixMapper {

        private static final String[] EMPTY_STRING = new String[0];

        /**
         * Returns a preferred prefix for the given namespace URI.
         *
         * This method is intended to be overrided by a derived class.
         *
         * <p>
         * As noted in the return value portion of the javadoc, there
         * are several cases where the preference cannot be honored.
         * Specifically, as of JAXB RI 2.0 and onward:
         *
         * <ol>
         * <li>
         * If the prefix returned is already in use as one of the in-scope
         * namespace bindings. This is partly necessary for correctness
         * (so that we don't unexpectedly change the meaning of QNames
         * bound to {@link String}), partly to simplify the marshaller.
         * <li>
         * If the prefix returned is "" yet the current {@link JAXBContext}
         * includes classes that use the empty namespace URI. This allows
         * the JAXB RI to reserve the "" prefix for the empty namespace URI,
         * which is the only possible prefix for the URI.
         * This restriction is also to simplify the marshaller.
         * </ol>
         *
         * @param namespaceUri
         *      The namespace URI for which the prefix needs to be found.
         *      Never be null. "" is used to denote the default namespace.
         * @param suggestion
         *      When the content tree has a suggestion for the prefix
         *      to the given namespaceUri, that suggestion is passed as a
         *      parameter. Typicall this value comes from the QName.getPrefix
         *      to show the preference of the content tree. This parameter
         *      may be null, and this parameter may represent an already
         *      occupied prefix.
         * @param requirePrefix
         *      If this method is expected to return non-empty prefix.
         *      When this flag is true, it means that the given namespace URI
         *      cannot be set as the default namespace.
         *
         * @return
         *      null if there's no prefered prefix for the namespace URI.
         *      In this case, the system will generate a prefix for you.
         *
         *      Otherwise the system will try to use the returned prefix,
         *      but generally there's no guarantee if the prefix will be
         *      actually used or not.
         *
         *      return "" to map this namespace URI to the default namespace.
         *      Again, there's no guarantee that this preference will be
         *      honored.
         *
         *      If this method returns "" when requirePrefix=true, the return
         *      value will be ignored and the system will generate one.
         *
         * @since JAXB 1.0.1
         */
        public abstract String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix);

        /**
         * Returns a list of namespace URIs that should be declared
         * at the root element.
         *
         * <p>
         * By default, the JAXB RI 1.0.x produces namespace declarations only when
         * they are necessary, only at where they are used. Because of this
         * lack of look-ahead, sometimes the marshaller produces a lot of
         * namespace declarations that look redundant to human eyes. For example,
         * <pre><xmp>
         * <?xml version="1.0"?>
         * <root>
         *   <ns1:child xmlns:ns1="urn:foo"> ... </ns1:child>
         *   <ns2:child xmlns:ns2="urn:foo"> ... </ns2:child>
         *   <ns3:child xmlns:ns3="urn:foo"> ... </ns3:child>
         *   ...
         * </root>
         * </xmp></pre>
         *
         * <p>
         * The JAXB RI 2.x mostly doesn't exhibit this behavior any more,
         * as it declares all statically known namespace URIs (those URIs
         * that are used as element/attribute names in JAXB annotations),
         * but it may still declare additional namespaces in the middle of
         * a document, for example when (i) a QName as an attribute/element value
         * requires a new namespace URI, or (ii) DOM nodes as a portion of an object
         * tree requires a new namespace URI.
         *
         * <p>
         * If you know in advance that you are going to use a certain set of
         * namespace URIs, you can override this method and have the marshaller
         * declare those namespace URIs at the root element.
         *
         * <p>
         * For example, by returning <code>new String[]{"urn:foo"}</code>,
         * the marshaller will produce:
         * <pre><xmp>
         * <?xml version="1.0"?>
         * <root xmlns:ns1="urn:foo">
         *   <ns1:child> ... </ns1:child>
         *   <ns1:child> ... </ns1:child>
         *   <ns1:child> ... </ns1:child>
         *   ...
         * </root>
         * </xmp></pre>
         * <p>
         * To control prefixes assigned to those namespace URIs, use the
         * {@link #getPreferredPrefix(String, String, boolean)} method.
         *
         * @return
         *      A list of namespace URIs as an array of {@link String}s.
         *      This method can return a length-zero array but not null.
         *      None of the array component can be null. To represent
         *      the empty namespace, use the empty string <code>""</code>.
         *
         * @since
         *      JAXB RI 1.0.2
         */
        public String[] getPreDeclaredNamespaceUris() {
            return EMPTY_STRING;
        }

        /**
         * Similar to {@link #getPreDeclaredNamespaceUris()} but allows the
         * (prefix,nsUri) pairs to be returned.
         *
         * <p>
         * With {@link #getPreDeclaredNamespaceUris()}, applications who wish to control
         * the prefixes as well as the namespaces needed to implement both
         * {@link #getPreDeclaredNamespaceUris()} and {@link #getPreferredPrefix(String, String, boolean)}.
         *
         * <p>
         * This version eliminates the needs by returning an array of pairs.
         *
         * @return
         *      always return a non-null (but possibly empty) array. The array stores
         *      data like (prefix1,nsUri1,prefix2,nsUri2,...) Use an empty string to represent
         *      the empty namespace URI and the default prefix. Null is not allowed as a value
         *      in the array.
         *
         * @since
         *      JAXB RI 2.0 beta
         */
        public String[] getPreDeclaredNamespaceUris2() {
            return EMPTY_STRING;
        }

        /**
         * Returns a list of (prefix,namespace URI) pairs that represents
         * namespace bindings available on ancestor elements (that need not be repeated
         * by the JAXB RI.)
         *
         * <p>
         * Sometimes JAXB is used to marshal an XML document, which will be
         * used as a subtree of a bigger document. When this happens, it's nice
         * for a JAXB marshaller to be able to use in-scope namespace bindings
         * of the larger document and avoid declaring redundant namespace URIs.
         *
         * <p>
         * This is automatically done when you are marshalling to {@link XMLStreamWriter},
         * {@link XMLEventWriter}, {@link DOMResult}, or {@link Node}, because
         * those output format allows us to inspect what's currently available
         * as in-scope namespace binding. However, with other output format,
         * such as {@link OutputStream}, the JAXB RI cannot do this automatically.
         * That's when this method comes into play.
         *
         * <p>
         * Namespace bindings returned by this method will be used by the JAXB RI,
         * but will not be re-declared. They are assumed to be available when you insert
         * this subtree into a bigger document.
         *
         * <p>
         * It is <b>NOT</b> OK to return  the same binding, or give
         * the receiver a conflicting binding information.
         * It's a responsibility of the caller to make sure that this doesn't happen
         * even if the ancestor elements look like:
         * <pre><xmp>
         *   <foo:abc xmlns:foo="abc">
         *     <foo:abc xmlns:foo="def">
         *       <foo:abc xmlns:foo="abc">
         *         ... JAXB marshalling into here.
         *       </foo:abc>
         *     </foo:abc>
         *   </foo:abc>
         * </xmp></pre>
         *
         * @return
         *      always return a non-null (but possibly empty) array. The array stores
         *      data like (prefix1,nsUri1,prefix2,nsUri2,...) Use an empty string to represent
         *      the empty namespace URI and the default prefix. Null is not allowed as a value
         *      in the array.
         *
         * @since JAXB RI 2.0 beta
         */
        public String[] getContextualNamespaceDecls() {
            return EMPTY_STRING;
        }
    }

See the Sample Apps sample application for a detailed example.

#### 2.1.3. Indentation

Property name: | `org.glassfish.jaxb.indentString`
Type: | `java.lang.String`
Default value: | " " (four whitespaces)

This property controls the string used for the indentation of XML. An element of depth k will be indented by printing this string k times. Note that the "`jaxb.formatted.output`" property needs to be set to "true" for the formatting/indentation of the output to occur. See the API documentation for `jakarta.xml.bind.Marshaller` interface for details of this property.

#### 2.1.4. Character Escaping Control

Property name: | `org.glassfish.jaxb.characterEscapeHandler`
Type: | `org.glassfish.jaxb.core.marshaller.CharacterEscapeHandler`
Default value: | null

By default, the marshaller implementation of the Eclipse Implementation of JAXB tries to escape characters so they can be safely represented in the output encoding (by using Unicode numeric character references of the form &#dddd;)

Unfortunately, due to various technical reasons, the default behavior may not meet your expectations. If you need to handle escaping more adroitly than the default manner, you can do so by doing the following:

1. Write a class that implements the `org.glassfish.jaxb.core.marshaller.CharacterEscapeHandler` interface.

2. Create a new instance of it.

3. Set that instance to the Marshaller by using this property.

See the Sample Apps sample application for more details.

#### 2.1.5. XML Declaration Control

Property name: | `org.glassfish.jaxb.xmlDeclaration`
Type: | `boolean`
Default value: | true

This experimental JAXB RI 1.0.x property has been adopted as a standard in Eclipse Implementation of JAXB. The Eclipse Implementation of JAXB will continue to support this property, but client code should be using the Marshaller.JAXB_FRAGMENT property instead. Please refer to the Marshaller javadoc for a complete description of the behavior.

In Eclipse Implementation of JAXB, calling:

    marshaller.setProperty("org.glassfish.jaxb.xmlDeclaration", true);

is equivalent to calling:

    marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);

JAXB 1.0 generated code and clients will continue to work exactly the same on the Jakarta XML Binding runtime as they did on the JAXB 1.0 runtime.

Enabling fragment marshalling could be useful if you are inserting the output of the XML into another XML.

#### 2.1.6. XML Preamble Control

Property name: | `org.glassfish.jaxb.xmlHeaders`
Type: | `java.lang.String`
Default value: | null

This property allows you to specify an XML preamble (<?xml ...> declaration) and any additional PIs, comments, DOCTYPE declaration that follows it. This property takes effect only when you are marshalling to `OutputStream`, `Writer`, or `StreamResult`. Note that this property interacts with the `Marshaller.JAXB_FRAGMENT` property. If that property is untouched or set to false, then Eclipse Implementation of JAXB would always write its XML preamble, so this property can be only used to write PIs, comments, DOCTYPE, etc. On the other hand, if it is set to true, then Jakarta XML Binding will not write its own XML preamble, so this property may contain custom XML preamble.

#### 2.1.7. Jaxb Annotation Control

Property name: | `XmlAccessorFactory`
Type: | `boolean`
Default value: | false

This property provides support for a custom org.glassfish.jaxb.runtime.v2.runtime.reflect.Accessor implementation. It allows the user to control the access to class fields and properties.

In Eclipse Implementation of JAXB, set the property to enable:

    marshaller.setProperty("XmlAccessorFactory", true);

## 3. XJC Customizations

### 3.1. Customizations

The Eclipse Implementation of JAXB provides additional customizations that are not defined by the Jakarta XML Binding specification. Note the following:

- These features may only be used when the Eclipse Implementation of JAXB XJC binding compiler is run in the `-extension` mode.

- All of the Eclipse Implementation of JAXB vendor extensions are defined in the "`http://java.sun.com/xml/ns/jaxb/xjc`" namespace.

- The namespaces containing extension binding declarations are specified to a Eclipse Implementation of JAXB processor by the occurrence of the global attribute `@jaxb:extensionBindingPrefixes` within an instance of `<xs:schema>` element. The value of this attribute is a whitespace-separated list of namespace prefixes. For more information, please refer to section 6.1.1 of the Jakarta XML Binding Specification.

#### 3.1.1. Index of Customizations

- SCD Support

- Extending a Common Super Class - Extending a Common Super Class

- Extending a Common Super Interface - Extending a Common Super Interface

- Enhanced <jaxb:javaType> - Enhanced <jaxb:javaType> customization

- Experimental simpler & better binding mode - Experimental simpler & better binding mode

- Alternative Derivation-by-restriction Binding Mode - Alternative derivation-by-restriction binding mode

- Allow separate compilations to perform element substitutions - Allow separate compilations to perform element substitutions

#### 3.1.2. SCD Support

The Eclipse Implementation of JAXB supports the use of schema component designator as a means of specifying the customization target (of all standard Jakarta XML Binding customizations as well as vendor extensions explained below.) To use this feature, use the `scd` attribute on <bindings> element instead of the `schemaLocation` and `node` attributes.

    <bindings xmlns:tns="http://example.com/myns"
              xmlns="https://jakarta.ee/xml/ns/jaxb" version="3.0">
        <bindings
                ...
                scd="tns:foo">
            <!-- this customization applies to the global element declaration -->
            <!-- 'foo' in the http://example.com/myns namespace -->
            <class name="FooElement"/>
        </bindings>
        <bindings
                ...
                scd="~tns:bar">
            <!-- this customization applies to the global type declaration -->
            <!-- 'bar' in the http://example.com/myns namespace -->
            <class name="BarType"/>
        </bindings>
    </bindings>

Compared to the standard XPath based approach, SCD allows more robust and concise way of identifying a target of a customization. For more about SCD, refer to the scd example. Note that SCD is a W3C working draft, and may change in the future.

#### 3.1.3. Extending a Common Super Class

The `<xjc:superClass>` customization allows you to specify the fully qualified name of the Java class that is to be used as the super class of all the generated implementation classes. The `<xjc:superClass>` customization can only occur within your `<jaxb:globalBindings>` customization on the `<xs:schema>` element:

    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
               xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb"
               xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
               jaxb:extensionBindingPrefixes="xjc"
               jaxb:version="3.0">

        <xs:annotation>
            <xs:appinfo>
                <jaxb:globalBindings>
                    <xjc:superClass
                            name="org.acme.RocketBooster"/>
                </jaxb:globalBindings>
            </xs:appinfo>
        </xs:annotation>

        ...

    </xs:schema>

In the sample above, the `<xjc:superClass>` customization will cause all of the generated implementation classes to extend the named class, `org.acme.RocketBooster`.

#### 3.1.4. Extending a Common Super Interface

The `<xjc:superInterface>` customization allows you to specify the fully qualified name of the Java interface that is to be used as the root interface of all the generated interfaces. The `<xjc:superInterface>` customization can only occur within your `<jaxb:globalBindings>` customization on the `<xs:schema>` element:

    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
               xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb"
               xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
               jaxb:extensionBindingPrefixes="xjc"
               jaxb:version="3.0">

        <xs:annotation>
            <xs:appinfo>
                <jaxb:globalBindings>
                    <xjc:superInterface
                            name="org.acme.RocketBooster"/>
                </jaxb:globalBindings>
            </xs:appinfo>
        </xs:annotation>

        ...

    </xs:schema>

In the sample above, the `<xjc:superInterface>` customization will cause all of the generated interfaces to extend the named interface, `org.acme.RocketBooster`.

#### 3.1.5. Enhanced <jaxb:javaType>

The <xjc:javaType> customization can be used just like the standard <jaxb:javaType> customization, except that it allows you to specify an `XmlAdapter`-derived class, instead of parse&print method pair.

This customization can be used in all the places <jaxb:javaType> is used, but nowhere else:

    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
               xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb"
               xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
               jaxb:extensionBindingPrefixes="xjc"
               jaxb:version="3.0">

        ...

        <xsd:simpleType name="LayerRate_T">
            <xsd:annotation>
                <xsd:appinfo>
                    <xjc:javaType name="org.acme.foo.LayerRate"
                                  adapter="org.acme.foo.LayerRateAdapter"/>
                </xsd:appinfo>
            </xsd:annotation>

            ... gory simple type definition here ...

        </xsd:simpleType>
    </xsd:schema>

In the above example, `LayerRate_T` simple type is adapted by `org.acme.foo.LayerRateAdapter`, which extends from `XmlAdapter`.

    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
               xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb"
               xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
               jaxb:extensionBindingPrefixes="xjc"
               jaxb:version="3.0">

        <xsd:annotation>
            <xsd:appinfo>
                <jaxb:globalBindings>
                    <xjc:javaType name="org.acme.foo.MyDateType"
                                  xmlType="xsd:dateTime"
                                  adapter="org.acme.foo.MyAdapterImpl"/>
                </jaxb:globalBindings>
            </xsd:appinfo>
        </xsd:annotation>

        ...

    </xsd:schema>

In the above example, all the use of `xsd:dateTime` type is adapter by `org.acme.foo.MyAdapterImpl` to `org.acme.foo.MyDateType`

#### 3.1.6. Experimental simpler & better binding mode

This experimental binding mode can be enabled as a part of the global binding. See below:

    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
               xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb"
               xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
               jaxb:extensionBindingPrefixes="xjc"
               jaxb:version="3.0">

        <xs:annotation>
            <xs:appinfo>
                <jaxb:globalBindings generateValueClass="false">
                    <xjc:simple/>
                </jaxb:globalBindings>
            </xs:appinfo>
        </xs:annotation>

        ...

    </xs:schema>

When enabled, XJC produces Java source code that are more concise and easier to use. Improvements include:

1. Some content model definitions, such as `A,B,A`, which used to cause an XJC compilation error and required manual intervention, now compile out of the box without any customization.

2. Some content model definitions that used to bind to a non-intuitive Java class now binds to a much better Java class:

       <!-- schema -->
       <xs:complexType name="foo">
           <xs:choice>
               <xs:sequence>
                   <xs:element name="a" type="xs:int"/>
                   <xs:element name="b" type="xs:int"/>
               </xs:sequence>
               <xs:sequence>
                   <xs:element name="b" type="xs:int"/>
                   <xs:element name="c" type="xs:int"/>
               </xs:sequence>
           </xs:choice>
       </xs:complexType>

       // before
       class Foo {
           List<JAXBElement<Integer>> content;
       }

       // in <xjc:simple> binding
       class Foo {
           Integer a;
           int b; // notice that b is effectively mandatory, hence primitive
           Integer c;
       }

3. When repetable elements are bound, the method name will become plural.

       <!-- schema -->
       <xs:complexType name="person">
           <xs:sequence>
               <xs:element name="child" type="xs:string"
                           maxOccurs="unbounded"/>
               <xs:element name="parent" type="xs:string"
                           maxOccurs="unbounded"/>
           </xs:sequence>
       </xs:complexType>

       // before
       public class Person {
           protected List<String> child;
           protected List<String> parent;
       }

       // in <xjc:simple> binding
       public class Person {
           protected List<String> children;
           protected List<String> parents;
       }

Once again, readers are warned that this is an experimental binding mode, and therefore the binding is subject to change in future versions of the Eclipse Implementation of JAXB without notice. Please send feedbacks on this binding to jaxb-impl-dev@eclipse.org

#### 3.1.7. Alternative Derivation-by-restriction Binding Mode

Normally, the Jakarta XML Binding specification requires that a derivation-by-restriction be mapped to an inheritance betwee n two Java classes. This is necessary to preserve the type hierarchy, but one of the downsides is that the derived class does not really provide easy-to-use properties that reflect the restricted content model.

This experimental <xjc:treatRestrictionLikeNewType> changes this behavior by not preserving the type inheritance to Java. Instead, it generates two unrelated Java classes, both with proper properties. For example, given the following schema:

    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
               xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
               jaxb:extensionBindingPrefixes="xjc"
               xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb"
               jaxb:version="3.0"
               elementFormDefault="qualified">

        <xs:annotation>
            <xs:appinfo>
                <jaxb:globalBindings>
                    <xjc:treatRestrictionLikeNewType/>
                </jaxb:globalBindings>
            </xs:appinfo>
        </xs:annotation>

        <xs:complexType name="DerivedType">
            <xs:complexContent>
                <xs:restriction base="ResponseOptionType">
                    <xs:sequence>
                        <xs:element name="foo" type="xs:string"/>
                    </xs:sequence>
                </xs:restriction>
            </xs:complexContent>
        </xs:complexType>

        <xs:complexType name="ResponseOptionType">
            <xs:sequence>
                <xs:element name="foo" type="xs:string"
                            maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:complexType>

    </xs:schema>

The generated `Derived` class will look like this (comment and annotations removed for brevity):

    public class DerivedType {
        protected String foo;

        public String getFoo() { return foo; }
        public void setFoo(String value) { this.foo = value; }
    }

In contrast, without this customization the `Derived` class would look like the following:

    public class DerivedType extends ResponseOptionType {

        // it simply inherits List<String> ResponseOptionType.getFoo()

    }

#### 3.1.8. Allow separate compilations to perform element substitutions

In an attempt to make the generated code easier to use, the Jakarta XML Binding specification sometimes choose bindings based on how certain feature is used. One of them is element substitution feature. If no actual element substitution happens in the schema, Jakarta XML Binding assumes that the element is not used for substitution, and generates code that assumes it.

Most of the time this is fine, but when you expect other "extension" schemas to be compiled later on top of your base schema, and if those extension schemas do element substitutions, this binding causes a problem ( see example.)

<xjc:substitutable> customization is a work around for this issue. It explicitly tells XJC that a certain element is used for element substitution head, even though no actual substitution might be present in the current compilation. This customization should be attached in the element declaration itself, like this:

    <xs:element name="Model" type="Model">
        <xs:annotation>
            <xs:appinfo>
                <xjc:substitutable/>
            </xs:appinfo>
        </xs:annotation>
    </xs:element>

## 4. DTD

### 4.1. DTD

The Eclipse Implementation of JAXB is shipped with experimental DTD support, which lets you compile XML DTDs.

To compile a DTD `test.dtd`, run the XJC binding compiler as follows:

    $ xjc.sh -dtd test.dtd

All the other command-line options of the XJC binding compiler can be applied. Similarly, the xjc ant task supports DTD. The generated code will be no different from what is generated from W3C XML Schema. You'll use the same Jakarta XML Binding API to access the generated code, and it is portable in the sense that it will run on any Jakarta XML Binding implementation.

#### 4.1.1. Customization

The customization syntax for DTD is roughly based on the ver.0.21 working draft of the Jakarta XML Binding specification, which is available at xml.coverpages.org. The deviations from this document are:

- The `whitespace` attribute of the `conversion` element takes " `preserve`", " `replace`", and " `collapse`" instead of " `preserve`"," `normalize`", and " `collapse`" as specified in the document.

- The `interface` customization just generates marker interfaces with no method.

## 5. Develop Plugins

This document describes how to write an XJC plugin to extend the code generation of XJC.

### 5.1. What Can A Plugin Do?

An XJC plugin participates in the code generation from a schema. It can define its own customizations that users can use to control it, it can access the code that the Eclipse Implementation of JAXB generates, it can generate additional classes/methods/fields/annotations/comments, and it can also replace some of the pluggability points in the compilation process, such as XML name -> Java name conversion.

As a show case of what a plugin can do, take a look at plugins hosted at JAXB2-commons.

#### 5.1.1. Quick Start

To write a plugin, do the following simple steps.

1. Write a class, say, `org.acme.MyPlugin` by extending `com.sun.tools.xjc.Plugin`. See javadoc for how to implement methods.

2. Write the name of your plugin class in a text file and put it as `/META-INF/services/com.sun.tools.xjc.Plugin` in your jar file.

Users can then use your plugins by declaring an XJC ant task with your jar files.

    <taskdef name="xjc" classname="com.sun.tools.xjc.XJCTask">
        <classpath>
            <fileset dir="jaxb-ri/lib" includes="*.jar"/>
            <fileset dir="your-plugin" includes="*.jar"/>
        </classpath>
    </taskdef>

#### 5.1.2. Resources

Although we will do our best to maintain the compatibility of the interfaces, it is still subject to change at this point.

Prev |  | Next
Tools | Home | Frequently Asked Questions