jaxbcontext 生成不完整的模式?
我在使用 JAXB 时遇到了一个奇怪的问题。我已经使用 xjc 从 XSD 生成 java 类,一切看起来都不错。如果我使用 schemagen,它会生成与我的原始 xsd 匹配的正确架构。但是,如果我使用 JAXBContext.generateSchema(),则生成的模式不完整。
我使用 Oracle Java 1.6.0_29 和 jaxb-2.2.4-1.jar 作为实现。我附上了 java 代码(生成架构)、下面的 xsd 以及 jaxb 调用的输出。
CalculateBorrowingDataResponse.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema
version="1.1"
attributeFormDefault="unqualified"
elementFormDefault="qualified"
targetNamespace="http://www.domain.com/ClientServices/LendingSimulation/CalculateBorrowingDataResponse"
xmlns:lssSt="http://www.domain.com/ClientServices/LendingSimulation/CalculateBorrowingDataResponse"
xmlns:cbdRes="http://www.domain.com/ClientServices/LendingSimulation/CalculateBorrowingDataResponse"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!-- CalculateBorrowingData -->
<xsd:complexType name="CalculateBorrowingDataResponseType">
<xsd:sequence>
<xsd:element name="loanAgmt" type="cbdRes:LoanAgreementType" minOccurs="1" maxOccurs="1" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="LoanAgreementType">
<xsd:sequence>
<xsd:element name="borrowingBasedPmtAmt" type="lssSt:borrowingBasedPmtAmt" minOccurs="0" maxOccurs="1" />
<xsd:element name="maxPmtAmt" type="lssSt:maxPmtAmt" minOccurs="0" maxOccurs="1" />
<xsd:element name="borrowingCapacityMin" type="lssSt:borrowingCapacityMin" minOccurs="0" maxOccurs="1" />
<xsd:element name="borrowingCapacityMax" type="lssSt:borrowingCapacityMax" minOccurs="0" maxOccurs="1" />
<xsd:element name="propertyValueMinAmt" type="lssSt:propertyValueMinAmt" minOccurs="0" maxOccurs="1" />
<xsd:element name="propertyValueMaxAmt" type="lssSt:propertyValueMaxAmt" minOccurs="0" maxOccurs="1" />
</xsd:sequence>
</xsd:complexType>
<xsd:element name="calculateBorrowingDataResponse" type="cbdRes:CalculateBorrowingDataResponseType"/>
<xsd:simpleType name="borrowingBasedPmtAmt">
<xsd:restriction base="xsd:decimal" >
<xsd:totalDigits value="19" />
<xsd:fractionDigits value="4" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="maxPmtAmt">
<xsd:restriction base="xsd:decimal" >
<xsd:totalDigits value="19" />
<xsd:fractionDigits value="4" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="borrowingCapacityMin">
<xsd:restriction base="xsd:decimal" >
<xsd:totalDigits value="19" />
<xsd:fractionDigits value="4" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="borrowingCapacityMax">
<xsd:restriction base="xsd:decimal" >
<xsd:totalDigits value="19" />
<xsd:fractionDigits value="4" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="propertyValueMinAmt">
<xsd:restriction base="xsd:decimal" >
<xsd:totalDigits value="19" />
<xsd:fractionDigits value="4" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="propertyValueMaxAmt">
<xsd:restriction base="xsd:decimal" >
<xsd:totalDigits value="19" />
<xsd:fractionDigits value="4" />
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
Java 代码:
// Creating the XML tree
JAXBContext jc = JAXBContext.newInstance( CalculateBorrowingDataResponseType.class );
Unmarshaller u = jc.createUnmarshaller();
// generate the schemas
final List<ByteArrayOutputStream> schemaStreams = new ArrayList<ByteArrayOutputStream>();
jc.generateSchema(new SchemaOutputResolver(){
@Override
public Result createOutput(String namespaceUri, String suggestedFileName) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
schemaStreams.add(out);
StreamResult streamResult = new StreamResult(out);
streamResult.setSystemId("");
return streamResult;
}});
// convert to a list of string
List<String> schemas = new ArrayList<String>();
for( ByteArrayOutputStream os : schemaStreams )
{
schemas.add(os.toString());
System.out.println( os.toString());
}
jaxbContext.generateSchema() 的输出:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema elementFormDefault="qualified" version="1.0" targetNamespace="http://www.domain.com/ClientServices/LendingSimulation/CalculateBorrowingDataResponse" xmlns:tns="http://www.domain.com/ClientServices/LendingSimulation/CalculateBorrowingDataResponse" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="CalculateBorrowingDataResponseType">
<xs:sequence>
<xs:element name="loanAgmt" type="tns:LoanAgreementType"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="LoanAgreementType">
<xs:sequence>
<xs:element name="borrowingBasedPmtAmt" type="xs:decimal" minOccurs="0"/>
<xs:element name="maxPmtAmt" type="xs:decimal" minOccurs="0"/>
<xs:element name="borrowingCapacityMin" type="xs:decimal" minOccurs="0"/>
<xs:element name="borrowingCapacityMax" type="xs:decimal" minOccurs="0"/>
<xs:element name="propertyValueMinAmt" type="xs:decimal" minOccurs="0"/>
<xs:element name="propertyValueMaxAmt" type="xs:decimal" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
如您所见,输出架构非常匹配,保存并保存,只是它缺少calculateBorrowingDataResponse 的元素定义!但是,如果我使用 schemagen, 生成calculateBorrowingDataResponse 元素。
我的 SchemaOutputResolver 设置中是否缺少某些内容或执行了不正确/不完整的操作?或者这是 Jaxb RI 中的一个错误?
I've run into a strange problem with JAXB. I've used xjc to generate my java classes from my XSD and all looks good. If I use schemagen, it produces a proper schema that matches my original xsd. However, if I use JAXBContext.generateSchema(), then the generated schema is incomplete.
I'm using Oracle Java 1.6.0_29 and jaxb-2.2.4-1.jar as the implementation. I'm enclosing the java code (which generates the schema), and the xsd below as well as the output of the jaxb call.
CalculateBorrowingDataResponse.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema
version="1.1"
attributeFormDefault="unqualified"
elementFormDefault="qualified"
targetNamespace="http://www.domain.com/ClientServices/LendingSimulation/CalculateBorrowingDataResponse"
xmlns:lssSt="http://www.domain.com/ClientServices/LendingSimulation/CalculateBorrowingDataResponse"
xmlns:cbdRes="http://www.domain.com/ClientServices/LendingSimulation/CalculateBorrowingDataResponse"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!-- CalculateBorrowingData -->
<xsd:complexType name="CalculateBorrowingDataResponseType">
<xsd:sequence>
<xsd:element name="loanAgmt" type="cbdRes:LoanAgreementType" minOccurs="1" maxOccurs="1" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="LoanAgreementType">
<xsd:sequence>
<xsd:element name="borrowingBasedPmtAmt" type="lssSt:borrowingBasedPmtAmt" minOccurs="0" maxOccurs="1" />
<xsd:element name="maxPmtAmt" type="lssSt:maxPmtAmt" minOccurs="0" maxOccurs="1" />
<xsd:element name="borrowingCapacityMin" type="lssSt:borrowingCapacityMin" minOccurs="0" maxOccurs="1" />
<xsd:element name="borrowingCapacityMax" type="lssSt:borrowingCapacityMax" minOccurs="0" maxOccurs="1" />
<xsd:element name="propertyValueMinAmt" type="lssSt:propertyValueMinAmt" minOccurs="0" maxOccurs="1" />
<xsd:element name="propertyValueMaxAmt" type="lssSt:propertyValueMaxAmt" minOccurs="0" maxOccurs="1" />
</xsd:sequence>
</xsd:complexType>
<xsd:element name="calculateBorrowingDataResponse" type="cbdRes:CalculateBorrowingDataResponseType"/>
<xsd:simpleType name="borrowingBasedPmtAmt">
<xsd:restriction base="xsd:decimal" >
<xsd:totalDigits value="19" />
<xsd:fractionDigits value="4" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="maxPmtAmt">
<xsd:restriction base="xsd:decimal" >
<xsd:totalDigits value="19" />
<xsd:fractionDigits value="4" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="borrowingCapacityMin">
<xsd:restriction base="xsd:decimal" >
<xsd:totalDigits value="19" />
<xsd:fractionDigits value="4" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="borrowingCapacityMax">
<xsd:restriction base="xsd:decimal" >
<xsd:totalDigits value="19" />
<xsd:fractionDigits value="4" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="propertyValueMinAmt">
<xsd:restriction base="xsd:decimal" >
<xsd:totalDigits value="19" />
<xsd:fractionDigits value="4" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="propertyValueMaxAmt">
<xsd:restriction base="xsd:decimal" >
<xsd:totalDigits value="19" />
<xsd:fractionDigits value="4" />
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
Java code:
// Creating the XML tree
JAXBContext jc = JAXBContext.newInstance( CalculateBorrowingDataResponseType.class );
Unmarshaller u = jc.createUnmarshaller();
// generate the schemas
final List<ByteArrayOutputStream> schemaStreams = new ArrayList<ByteArrayOutputStream>();
jc.generateSchema(new SchemaOutputResolver(){
@Override
public Result createOutput(String namespaceUri, String suggestedFileName) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
schemaStreams.add(out);
StreamResult streamResult = new StreamResult(out);
streamResult.setSystemId("");
return streamResult;
}});
// convert to a list of string
List<String> schemas = new ArrayList<String>();
for( ByteArrayOutputStream os : schemaStreams )
{
schemas.add(os.toString());
System.out.println( os.toString());
}
Output of jaxbContext.generateSchema():
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema elementFormDefault="qualified" version="1.0" targetNamespace="http://www.domain.com/ClientServices/LendingSimulation/CalculateBorrowingDataResponse" xmlns:tns="http://www.domain.com/ClientServices/LendingSimulation/CalculateBorrowingDataResponse" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="CalculateBorrowingDataResponseType">
<xs:sequence>
<xs:element name="loanAgmt" type="tns:LoanAgreementType"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="LoanAgreementType">
<xs:sequence>
<xs:element name="borrowingBasedPmtAmt" type="xs:decimal" minOccurs="0"/>
<xs:element name="maxPmtAmt" type="xs:decimal" minOccurs="0"/>
<xs:element name="borrowingCapacityMin" type="xs:decimal" minOccurs="0"/>
<xs:element name="borrowingCapacityMax" type="xs:decimal" minOccurs="0"/>
<xs:element name="propertyValueMinAmt" type="xs:decimal" minOccurs="0"/>
<xs:element name="propertyValueMaxAmt" type="xs:decimal" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
As you can see, the output schema matches very closely, save and except that it is missing the element definition of calculateBorrowingDataResponse! If I use schemagen, however, the
calculateBorrowingDataResponse element is generated.
Am I missing something in my SchemaOutputResolver setup or doing something incorrect/incomplete? Or is this a bug in the Jaxb RI?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
JAXB 的更改
对
需要上述类包内的
package-info.java
文件(由xjc
从 XSD 生成)中定义的信息。它不会创建相关的 XSD 元素,因为
CalculateBorrowingDataResponseType
没有@XmlRootElement
注释。为什么
xjc
不从一开始就创建一个?请参阅互联网上最权威的解释 关于此事。如果您向
JAXBContext.newInstance(...)
提供包名称,为什么您的代码会生成上述元素,即使CalculateBorrowingDataResponseType
仍然缺少@XmlRootAnnotation< /代码>?
我还没有任何想法!现在我有了!Change
to
JAXB needs the information defined in the
package-info.java
file (generated byxjc
from your XSD) inside the above class' package.It doesn't creates the XSD element in question, because
CalculateBorrowingDataResponseType
doesn't have an@XmlRootElement
annotation.Why didn't
xjc
create one from the beginning? See the most authoritative explanation on the Internets regarding this matter.And why does your code generates the aforementioned element if you supply a package name to
JAXBContext.newInstance(...)
even thoughCalculateBorrowingDataResponseType
still missing the@XmlRootAnnotation
?I haven't got the faintest idea!Now I have!生成的
ObjectFactory
类中的以下内容是导致生成该元素的原因:为了让 JAXBContext 处理
ObjectFactory
类,您需要将其包含在类数组中传递以创建 JAXBContext:或者在生成的类的包名称上创建 JAXBContext:
完整示例
我得到以下生成的 XML 模式,其中包含
calculateBorrowingDataResponse
元素:The following from the generated
ObjectFactory
class is what causes that element to be generated:In order to have the
ObjectFactory
class processed by the JAXBContext you either need to included in array of classes passed to create the JAXBContext:Or to create the JAXBContext on the package name of the generated classes:
Full Example
I get the following generated XML schema, that contains the
calculateBorrowingDataResponse
element:为什么您认为在 roundrip 'schema1->XJC->schema2' 中 schema1 和 schema 2 应该相同?您是否有 XJC 为“calculateBorrowingDataResponse”元素生成的 Java 类?我不这么认为 - 那么你会如何期望它出现在生成的模式中?
Why do you think that in roundrip 'schema1->XJC->schema2' schema1 and schema 2 should be identical? Do you have Java class generated for 'calculateBorrowingDataResponse' element by XJC? I don't think so - how would you expect it to be in generated schema then?