[英]JAXB - flag 'required' from XmlAttribute being ignored on primitive types
嘗試使用JAXB庫中的schemagen工具為我的項目生成Schema時遇到了一些問題。 問題是注釋@XmlAttribute
沒有被正確解析。
- src
- teste
- entity
因此,問題是對於某些類,由scanmagen任務完全忽略XmlAttribute
required
的標志。
我將在這里粘貼一些類和生成的模式的示例,以便您可以了解正在發生的事情
package teste.entity;
import javax.xml.bind.annotation.XmlAttribute;
public abstract class Class2 {
@XmlAttribute(required=false)
public String stringNotRequired;
@XmlAttribute(required=true)
public String stringRequired;
@XmlAttribute(required=false)
public int anotherIntNotRequired;
@XmlAttribute(required=true)
public int anotherIntRequired;
}
package teste.entity;
import javax.xml.bind.annotation.XmlAttribute;
public class Class1 extends Class2 {
@XmlAttribute(required=true)
public Integer integerRequired;
@XmlAttribute(required=false)
public Integer integerNotRequired;
@XmlAttribute(required=false)
public int intNotRequired;
@XmlAttribute(required=true)
public int intRequired;
public Class1() {
}
}
我的package-info.java
@XmlSchema(xmlns = @XmlNs(prefix = "t", namespaceURI = "http://test.com"),
namespace = "http://test.com",
elementFormDefault = XmlNsForm.UNQUALIFIED,
attributeFormDefault = XmlNsForm.UNQUALIFIED)
package teste.entity;
import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
當我運行schemagen
任務時,我得到了這個輸出:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="unqualified" version="1.0" targetNamespace="http://test.com" xmlns:t="http://test.com" xmlns:tns="http://test.com" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="class1">
<xs:complexContent>
<xs:extension base="tns:class2">
<xs:sequence/>
<xs:attribute name="integerRequired" type="xs:int" use="required"/>
<xs:attribute name="integerNotRequired" type="xs:int"/>
<xs:attribute name="intNotRequired" type="xs:int" use="required"/>
<xs:attribute name="intRequired" type="xs:int" use="required"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="class2" abstract="true">
<xs:sequence/>
<xs:attribute name="stringNotRequired" type="xs:string"/>
<xs:attribute name="stringRequired" type="xs:string" use="required"/>
<xs:attribute name="anotherIntNotRequired" type="xs:int" use="required"/>
<xs:attribute name="anotherIntRequired" type="xs:int" use="required"/>
</xs:complexType>
</xs:schema>
這是我的Ant任務
<target name="generate-schema" >
<path id="mycp">
<fileset dir="lib/jaxb/lib\">
<include name="*.jar"/>
</fileset>
<fileset dir="lib" >
<include name="*.jar"/>
</fileset>
<fileset dir="dist" >
<include name="*.jar"/>
</fileset>
</path>
<taskdef name="schemagen" classname="com.sun.tools.jxc.SchemaGenTask">
<classpath refid="mycp"/>
</taskdef>
<mkdir dir="schema"/>
<schemagen srcdir="src/teste/entity" destdir="schema" >
<classpath refid="mycp"/>
<schema namespace="http://test.com" file="full.xsd" />
</schemagen>
</target>
我是否需要在命名空間的類上進行注釋才能正確輸出?
大概。 我創建了一個類似於你的設置。
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
中指定的任何前綴。)
鑒於上面的文件XJC的SchemaGen
產生了所需的結果 - 如果我有一個必需的屬性,那么它將被生成; 如果我設置required=false
,那么它不會。
這里的主要內容是Test
類上的@XmlType
注釋。 如果你手工制作你的課程,你就離不開它。 ( @XmlRootElement
不是必需的,因此如果你需要它,它取決於你的用例。)這告訴JAXB當SchemaGen
處理它時, Test
類(它代表一種模式類型 )屬於哪個命名空間。
package-info.java
幾乎用於相同的目的,但是在模式級別。 如果包中包含此文件(以及上面顯示的注釋)和SchemaGen
遇到,那么它將知道該包中的類(模式類型)屬於包級別注釋中指定的命名空間。 (同樣,如果你手工完成這是必須的。)除此之外, SchemaGen
使用此文件中聲明的命名空間將輸出發送到您在<schema namespace="http://test.com" file="test.xsd" />
指定的文件<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教程中有一個簡短的部分 ,遺憾的是,它沒有特別說明原始Java類型和XML模式類型。
您所遇到的缺點不是我認為的JAXB缺陷,而是Java 奇怪 :原始類型不能為空,這同時也是好的和壞的。
您可以通過更改原始屬性來解決此問題
@XmlAttribute
public int attribute;
@XmlAttribute
public Integer attribute;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.