0

I have an XML file to configure a program. The XML configuration is un-marshalled with jaxb. I figured it would be a useful thing to generate an XSD file from these classes to make it easier for other developers to change the settings and to avoid errors.

One can use a XSD file without a namespace but than the jaxb2 post-processing tools won't work (I am stuck with the name "schema1.xsd" without having the possibility to change that on creation).

Below you can see how to "import" a XSD file into your XML file without namespace:

<rootTag
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="file:///C:/path/to/the/file/schema1.xsd">
<subTags>
</subTags>
</rootTag>

I found some blogs stating that one should add a namespace to the @XmlRootElement like `@XmlRootElement(namespace = "myNameSpace") but what shall I do when I have classes using instances of other classes?

Below you can see a simplification of my classes:

@XmlRootElement(name = "library")
@XmlAccessorType(XmlAccessType.FIELD)
public class Library {
    // creates a wrapper around a List
    @XmlElementWrapper(name = "books")
    // lists this tag
    @XmlElement(name = "book")
    private List<Book> books = new ArrayList<>();

    private Address address;

    private String nameOfLibrary;
@XmlRootElement(name = "book")
@XmlAccessorType(XmlAccessType.FIELD)
public class Book {
    private String title;
    private String author;
}
@XmlRootElement(name = "address")
@XmlAccessorType(XmlAccessType.FIELD)
public class Address {
    private String street;
    private String town;
}

When I add the namespace only to my first class (Library) than jaxb generates a schema1.xsd file only for Library.java with the namespace which imports a second XSD file schema2.xsd whit all the other objects.

When I add the namespcae to every XmlRootElement and XmlElement, there is still a seperation between schema2.xsd and schema1.xsd

Below you can see the plugin settings:

<plugins>
<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxb2-maven-plugin</artifactId>
    <executions>
        <execution>
            <id>schemagen</id>
            <goals>
                <goal>schemagen</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <sources>
            <source>src/main/java/de/soptim/za/tools/backup/checking/config</source>
        </sources>
        <outputDirectory>src/main/resources/schema</outputDirectory>
        <clearOutputDir>false</clearOutputDir>
    </configuration>
</plugin>
</plugins>
<dependencies>
<dependency>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxb2-maven-plugin</artifactId>
    <version>2.5.0</version>
</dependency>

<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-core</artifactId>
    <version>3.0.0</version>
</dependency>
</dependencies>

Maybe I am also misunderstanding the namespace concept, I am rather confused right now.

Wumba
  • 99
  • 1
  • 12

1 Answers1

0

I assume your JAXB-annotated classes (Library, Address, Book) are all in a common package, which seems to be de.soptim.za.tools.backup.checking.config. Then you can put a package-info.java file into this package, annotate the package with @XmlSchema and specify a namespace there.

@XmlSchema(namespace = "http://mynamespace.com",
           elementFormDefault = XmlNsForm.QUALIFIED,
           attributeFormDefault = XmlNsForm.UNSET)
package de.soptim.za.tools.backup.checking.config;

import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;

See also the API doc of @XmlSchema and this related question.

For marshalling/unmarshalling this namespace will apply to all your JAXB classes of that package (except of course where you explicitly set another namespace in any individual @XmlElement, @XmlElementWrapper, @XmlAttribute or @XmlRootElement annotation within your classes).

And when generating schemas from the classes of this package you should only get one XSD file generated, because your classes use only one namespace.

Thomas Fritsch
  • 9,639
  • 33
  • 37
  • 49