[英]JAXB unmarshall: where does ElementNSImpl come from?
When I unmarshall a certain object I don't get back the type of the object but the type ElementNSImpl
that appears to have my data in it but why won't JAXB unmarshall it into my JAXB classes? 当我解组某个对象时,我没有得到对象的类型,但是类型ElementNSImpl
看起来有我的数据,但为什么JAXB不会将它解组到我的JAXB类中?
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Asset", propOrder = {
"platformContentOrFeatureContentOrAirspace",
...
})
@XmlSeeAlso({
...
})
public abstract class Asset {
@XmlElements({
@XmlElement(name = "PlatformContent", type = AnyPlatform.class),
@XmlElement(name = "FeatureContent", type = AnyFeature.class),
@XmlElement(name = "Airspace", type = Airspace.class)
})
protected Object platformContentOrFeatureContentOrAirspace;
...
public Object getPlatformContentorFeatureContentorAirspace(){
return platformContentOrFeatureContentOrAirspace;
}
...
}
Here is a schema fragment: 这是一个模式片段:
<complexType name="Asset">
<complexContent>
<restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
<sequence>
<choice minOccurs="0">
<element name="PlatformContent" type="temp:TargetNamespaceURI}AnyPlatform"/>
<element name="FeatureContent" type="{temp:TargetNamespaceURI}AnyFeature"/>
<element ref="{temp:TargetNamespaceURI}Airspace"/>
</choice>
</sequence>
</restriction>
</complexContent>
</complexType>
UPDATE: In this case I am trying to unmarshall XML that contains a PlatformContent tag. 更新:在这种情况下,我试图解组包含PlatformContent标记的XML。 If I take out the @XmlTransient
annotation I get an exception saying that it can't instantiate AnyPlatform. 如果我取出@XmlTransient
注释,我会得到一个异常,说它无法实例化AnyPlatform。 I am very new to JAXB but I realize this may be a false step and side stepping my problem to leave the @XmlTransient
in. 我是JAXB的新手,但我意识到这可能是一个错误的步骤,并且在我离开@XmlTransient
问题。
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "AnyPlatform", propOrder = {
"fooOrBarOrBaz"
})
@XmlTransient //This may be needed to parse correctly.
@XmlSeeAlso({
AnyPlatformDerivedType1.class,
AnyPlatformDerivedType2.class
})
public abstract class AnyPlatform {
@XmlElements({
@XmlElement(name = "Foo", type = Foo.class),
@XmlElement(name = "Bar", type = Bar.class),
@XmlElement(name = "Baz", type = Baz.class),
})
protected PlatformType fooOrBarOrBaz;
public PlatformType getFooOrBarOrBaz() {
return fooOrBarOrBaz;
}
}
Here is the schema fragment 这是架构片段
<xs:complexType name="AnyPlatform" abstract="true">
<xs:choice>
<xs:element ref="Foo"/>
<xs:element ref="Bar"/>
<xs:element ref="Baz"/>
</xs:choice>
</xs:complexType>
When @XmlTransient is taken out I get this exception: 当取出@XmlTransient时,我得到以下异常:
javax.xml.bind.UnmarshalException: Unable to create an instance of AnyPlatform
- with linked exception:
[java.lang.InstantiationException]
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:726)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:247)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.createInstance(UnmarshallingContext.java:690)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.StructureLoader.startElement(StructureLoader.java:171)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiTypeLoader.startElement(XsiTypeLoader.java:65)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:559)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:538)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:153)
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:380)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2787)
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:118)
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:643)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:243)
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:125)
at App.parse(App.java:66)
at MainWindow$1.actionPerformed(MainWindow.java:57)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.AbstractButton.doClick(AbstractButton.java:376)
at javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:833)
at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:877)
at java.awt.Component.processMouseEvent(Component.java:6535)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
at java.awt.Component.processEvent(Component.java:6300)
at java.awt.Container.processEvent(Container.java:2236)
at java.awt.Component.dispatchEventImpl(Component.java:4891)
at java.awt.Container.dispatchEventImpl(Container.java:2294)
at java.awt.Component.dispatchEvent(Component.java:4713)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
at java.awt.Container.dispatchEventImpl(Container.java:2280)
at java.awt.Window.dispatchEventImpl(Window.java:2750)
at java.awt.Component.dispatchEvent(Component.java:4713)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.awt.EventQueue$4.run(EventQueue.java:731)
at java.awt.EventQueue$4.run(EventQueue.java:729)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Caused by: java.lang.InstantiationException
at sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.java:48)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at com.sun.xml.internal.bind.v2.ClassFactory.create0(ClassFactory.java:118)
at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.createInstance(ClassBeanInfoImpl.java:270)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.createInstance(UnmarshallingContext.java:684)
... 60 more
UPDATE 2 Here is the XML in question: 更新2这是有问题的XML:
<p:AssetList>
<p:Asset>
<p:PlatformContent>
<p:Foo>
<!-- Foo's Data -->
</p:Foo>
</p:PlatformContent>
</p:Asset>
</p:AssetList>
UPDATE3 To add more clarity AnyPlatform is the base class for two derived classes. UPDATE3为了增加更多的清晰度,AnyPlatform是两个派生类的基类。 We will call them AnyPlatformDerivedClass1 and AnyPlatformDerivedClass2. 我们将它们称为AnyPlatformDerivedClass1和AnyPlatformDerivedClass2。 Here is what they look like: 这是他们的样子:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "AnyPlatformDerivedType1")
public class AnyPlatformDerivedType1
extends AnyPlatform
{
// Yes. These really are empty according to the schema.
}
They are blank on purpose according to the schema. 根据模式,它们是有目的的空白。 So this basically is just the same content with a different XML tag name. 所以这基本上只是具有不同XML标记名称的相同内容。
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "AnyPlatformDerivedType2")
public class AnyPlatformDerivedType2
extends AnyPlatform
{
// Yes. These really are empty according to the schema.
}
It will work sufficiently provided you use xsi:type as the discriminator and the concrete implementations are in the JAXBContext (either added directly or referenced via an XmlSeeAlso). 如果您使用xsi:type作为鉴别器并且具体实现在JAXBContext中(直接添加或通过XmlSeeAlso引用),它将充分发挥作用。 Here is an example: 这是一个例子:
class QuickTest {
@XmlRootElement
public static class Container {
@XmlElement
public Base base;
}
public static abstract class Base {
}
@XmlType(name="one")
public static class ChildOne extends Base {
}
@XmlType(name="two")
public static class ChildTwo extends Base {
}
private static final String MESSAGE = "<container xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><base xsi:type=\"one\"/></container>";
public static void main(String [] args) throws Exception {
JAXBContext context = JAXBContext.newInstance(Container.class, Base.class, ChildOne.class, ChildTwo.class);
Container con = (Container) context.createUnmarshaller().unmarshal(new StringReader(MESSAGE));
System.out.println(con.base.getClass());
//Prints QuickTest$ChildOne
}
}
I ended up removing the abstract keyword from AnyPlatform. 我最终从AnyPlatform中删除了abstract关键字。 Everything worked as expected, and right now its unlikely for me that it will be needed in the future. 一切都按预期工作,现在我不太可能在将来需要它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.