Нужны ли аннотации к классам для пространства имен, чтобы получить вывод правильно?
Возможно.Я создал настройку, аналогичную вашей.
Test.java
package test;
...
@XmlType(name = "test", namespace = "http://test.com", propOrder = "b")
@XmlRootElement(name = "test", namespace = "http://test.com")
public final class Test {
@XmlAttribute(required = false)
public String a;
@XmlElement
public String b;
public Test() {}
}
package-info.java
@XmlSchema(xmlns = @XmlNs(prefix = "tns", namespaceURI = "http://test.com"),
namespace = "http://test.com",
elementFormDefault = XmlNsForm.QUALIFIED,
attributeFormDefault = XmlNsForm.QUALIFIED)
package test;
import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
build.xml
(фрагмент, основанный на вводе OP
<schemagen srcdir="<path-to-test-package>" destdir=".">
<classpath refid="<classpath-refid>" />
<schema namespace="http://test.com" file="test.xsd" />
</schemagen>
test.xsd
(вывод)
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema
attributeFormDefault="qualified"
elementFormDefault="qualified" version="1.0"
targetNamespace="http://test.com"
xmlns:tns="http://test.com"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="test" type="tns:test"/>
<xs:complexType name="test" final="extension restriction">
<xs:sequence>
<xs:element name="b" type="xs:string" minOccurs="0"/>
</xs:sequence>
<xs:attribute ref="tns:a"/>
</xs:complexType>
<xs:attribute name="a" type="xs:string"/>
</xs:schema>
(я использовал префикс tns
, потому что JAXB будет генерировать и использовать его вместо любого префикса, которыйбыл указан в @XmlNs
.)
Учитывая файлы выше SchemaGen
XJC, дает желаемые результаты - если у меня есть обязательный атрибут, то он будет сгенерирован как таковой;если я установлю required=false
, то не будет.
Главное здесь - аннотация @XmlType
для класса Test
.Вы просто не можете жить без этого, если вы создаете свои классы вручную.(@XmlRootElement
не является обязательным, поэтому зависит от вашего варианта использования, хотите вы этого или нет.) Это сообщает JAXB, какое пространство имен делает класс Test
(который представляет схему типа путь) принадлежит, когда SchemaGen
обрабатывает его.
package-info.java
служит почти той же цели, но на уровне схема .Если пакет содержит этот файл (и аннотации, показанные выше) и встречается SchemaGen
, то он будет знать, что классы (типы схем) в этом пакете принадлежат пространству имен, указанному в аннотациях уровня пакета.(Опять же, если вы делаете что-то вручную, это обязательно.) Кроме этого, SchemaGen
использует пространство имен, объявленное в этом файле, для отправки вывода в файл, указанный вами в <schema namespace="http://test.com" file="test.xsd" />
.Без него имя сгенерированного файла всегда будет schema1.xsd
(или похожим).
Несколько пакетов
Если вы хотите сгруппировать несколько классов, расположенных в нескольких пакетах, в одно пространство имен, то у вас будетприменить одинаковые примечания уровня пакета ко всем пакетам (как в приведенном выше фрагменте package-info.java
- используемый префикс пространства имен должен быть tns
из-за ограничения JAXB, описанного ранее).
schemagen
конечно, нужно заказать компиляцию обоих пакетов.В вашей build.xml
задача schemagen
srcdir
должна охватывать оба пакета.
Если у вас есть структура, подобная этой
.
|-- x
| |-- A.java # JAXB
| |-- B.java # POJO
| `-- package-info.java # http://test.com
`-- y
|-- C.java # JAXB
`-- package-info.java # http://test.com
, вы можете указать schemagen
задачу:компилировать только A
и C
вот так
<schemagen srcdir="." destdir="." >
<schema namespace="http://test.com" file="test.xsd" />
<include name="x/A.java" />
<include name="y/C.java" />
</schemagen>
Необязательные и обязательные атрибуты
В официальном руководстве JAXB есть короткий раздел *1081* по атрибутам, которыйк сожалению, ничего не говорится о примитивных типах Java и, в частности, типах XML-схем.
Недостаток, который вы испытываете, на мой взгляд, не является дефектом JAXB, скорее это явление Java oddity : примитивные типы не могут быть нулевыми, что хорошо и плохо одновременно.
Вы можете решить эту проблему, изменив свой атрибут примитива
@XmlAttribute
public int attribute;
@XmlAttribute
public Integer attribute;
(у меня естьнашла ветку списка рассылки , касающуюся этой же проблемы , может быть, она вам интересна.)