[英]JAXB binding to remove propOrder
我寫了一個XSD:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
targetNamespace="http://api.synthesys/models/generated/simple/chat"
xmlns:drsc="http://api.synthesys/models/generated/simple/chat"
xmlns:simplify="http://jaxb2-commons.dev.java.net/basic/simplify"
jaxb:extensionBindingPrefixes="simplify"
jaxb:version="2.1">
<xsd:element name="conversation">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="start-time" type="xsd:dateTime" minOccurs="1" maxOccurs="1"/>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<!-- for code generation, allowing direct and distinct access to the messages and events -->
<xsd:annotation>
<xsd:appinfo>
<simplify:as-element-property/>
</xsd:appinfo>
</xsd:annotation>
<!--messages-->
<xsd:element name="message">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="author" minOccurs="1" maxOccurs="1" type="xsd:string"/>
<xsd:element name="text" minOccurs="1" maxOccurs="1" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<!--room events: entering or exiting the room-->
<xsd:element name="event">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="who" minOccurs="1" maxOccurs="1" type="xsd:string"/>
<xsd:element name="what" minOccurs="1" maxOccurs="1" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:choice>
<!--end time millis-->
<xsd:element name="end-time" type="xsd:dateTime" minOccurs="1" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
並且我編寫了一個示例XML文件:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<mine:conversation xmlns:mine="http://api.synthesys/models/generated/simple/chat">
<start-time>2017-09-10T12:00:00.000Z</start-time>
<event>
<who>John</who>
<what>entered the room</what>
</event>
<message>
<author>John</author>
<text>hello</text>
</message>
<event>
<who>Jane</who>
<what>entered the room</what>
</event>
<message>
<author>Jane</author>
<text>goodbye, John</text>
</message>
<event>
<who>Jane</who>
<what>left the room</what>
</event>
<event>
<who>John</who>
<what>left the room</what>
</event>
<end-time>2017-09-10T12:01:00.000Z</end-time>
</mine:conversation>
借助maven-jaxb2-plugin
我已經能夠從這種模式生成一個類,如下所示:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"startTime",
"messages",
"events",
"endTime"
})
@XmlRootElement(name = "conversation")
public class Conversation {
@XmlElement(name = "start-time", required = true, type = String.class)
@XmlJavaTypeAdapter(Adapter1 .class)
@XmlSchemaType(name = "dateTime")
protected XMLGregorianCalendar startTime;
@XmlElement(name = "message")
protected List<Conversation.Message> messages;
@XmlElement(name = "event")
protected List<Conversation.Event> events;
@XmlElement(name = "end-time", required = true, type = String.class)
@XmlJavaTypeAdapter(Adapter1 .class)
@XmlSchemaType(name = "dateTime")
protected XMLGregorianCalendar endTime;
問題是,當我嘗試使用JAXB像這樣解組我的示例xml文件時:
class MarshalUnmarshalTest extends Specification {
def "test"(){
setup:
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
JAXBContext context = JAXBContext.newInstance(synthesys.api.models.generated.simple.chat.Conversation.class)
Marshaller marshaller = context.createMarshaller()
Unmarshaller unmarshaller = context.createUnmarshaller()
ByteArrayOutputStream bos = new ByteArrayOutputStream();
context.generateSchema(new StructuredDataUtils.StructuredDataSchemaOutputResolver(bos));
Schema schema = sf.newSchema(new StreamSource(new ByteArrayInputStream(bos.toByteArray())));
marshaller.setSchema(schema)
unmarshaller.setSchema(schema)
File input = new File("src/test/resources/data/genericChat/simple-valid.xml")
when:
def object = unmarshaller.unmarshal(input.newInputStream())
then:
object instanceof synthesys.api.models.generated.simple.chat.Conversation
}
}
我收到此錯誤:
javax.xml.bind.UnmarshalException
- with linked exception:
[org.xml.sax.SAXParseException; lineNumber: 8; columnNumber: 14; cvc-complex-type.2.4.a: Invalid content was found starting with element 'message'. One of '{event, end-time}' is expected.]
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.createUnmarshalException(AbstractUnmarshallerImpl.java:335)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.createUnmarshalException(UnmarshallerImpl.java:563)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:249)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:214)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:204)
at synthesys.api.models.generated.standard.chat.MarshalUnmarshalTest.test(MarshalUnmarshalTest.groovy:31)
Caused by: org.xml.sax.SAXParseException; lineNumber: 8; columnNumber: 14; cvc-complex-type.2.4.a: Invalid content was found starting with element 'message'. One of '{event, end-time}' is expected.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:203)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:134)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:437)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:368)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:325)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(XMLSchemaValidator.java:458)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.reportSchemaError(XMLSchemaValidator.java:3237)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleStartElement(XMLSchemaValidator.java:1796)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.startElement(XMLSchemaValidator.java:746)
at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorHandlerImpl.startElement(ValidatorHandlerImpl.java:570)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.ValidatingUnmarshaller.startElement(ValidatingUnmarshaller.java:86)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:163)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:509)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:379)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2786)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:117)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:649)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:243)
... 4 more
真正讓我感到沮喪的是,此示例文件在使用xmllint --noout --schema path/to/schema.xsd path/to/sample.xml
時進行了驗證。 在我看來,主要的問題是,生成的Conversation
類定義了一個propOrder
,它比模式實際的限制更多。
誰能指出我如何配置簡化插件以不生成此propOrder? 或者,我如何才能利用綁定來消除該限制? 我確實想保持當前行為,其中我生成的類同時具有List<Message> messages
屬性和List<Event> events
屬性,而不是單個List<Object> messagesOrEvents
免責聲明:我是JAXB2簡化插件和JAXB2注釋插件的作者 。
問題是簡化屬性(就像您所做的那樣)可以有效地更改XML的結構。 它不再是message
, event
, end-time
的任何順序。 簡化后是一些固定的順序。 這就是您為Java模型中易於使用的結構所付出的代價。
誰能指出我如何配置簡化插件以不生成此propOrder?
不會propOrder
插件不會生成propOrder
,而XJC會生成。 simple插件僅將異構屬性“轉換”為幾個簡單的同類屬性。 它與propOrder
。
它可以自定義生成@XmlType
使用注釋JAXB2注釋插件 ,但我不肯定是否propOrder
是問題。 老實說,我對您在元素順序方面遇到問題感到驚訝。 我一直以為JAXB在解組時並不關心順序。
如果需要,請在https://github.com/highsource/maven-jaxb2-plugin-support/tree/master/s/simplify下發布您的最小示例項目,我來看一下。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.