JAXB 解组与名称空间..如何?
JAXB unmarshaling with namespaces.. how?
假设我的有效 xml 如下所示:
<A xmlns="something">
<B>4</B>
</A>
我的代码是这样的:
@XmlRootElement(name = "A")
@XmlAccessorType (XmlAccessType.FIELD)
@Getter //from lombok
public class Data{
@XmlElement(name = "B")
private String b;
public Data(String b) {
this.b = b;
}
public Data() {
}
// Getter/setter generated by lombok.
}
我如何让它工作?如果我的 xml 标记有一些关联元素,如上面的 'xmlns',JAXB 解组器会抛出异常。
我是第一次这样做,所以我真的对 JAXB、解组等一无所知。我正在挣扎。 :)
任何帮助都会很好。
编辑
堆栈跟踪:
javax.xml.bind.UnmarshalException: unexpected element (uri:"something", local:"A"). Expected elements are <{}B>,<{}A>
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.Loader.reportError(Loader.java:242)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:109)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(UnmarshallingContext.java:1131)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:556)
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:374)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSContentDriver.scanRootElementHook(XMLNSDocumentScannerImpl.java:613)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3132)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:852)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:602)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:112)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:505)
at ...
如果您的 xml 文档中有名称空间,则您的 jaxb 注释中也需要有它。
例如像这样:
@XmlRootElement(name = "A", namespace="something")
@XmlAccessorType (XmlAccessType.FIELD)
public class Data{
来自 XmlRootElement
的来源:
public @interface XmlRootElement {
/**
* namespace name of the XML element.
* <p>
* If the value is "##default", then the XML namespace name is derived
* from the package of the class ( {@link XmlSchema} ). If the
* package is unnamed, then the XML namespace is the default empty
* namespace.
*/
String namespace() default "##default";
// else of file
您还应牢记此规则也适用于大多数 JAXB 注释,因此您需要指定根元素 以及其他元素 并显式指定命名空间,如下所示:
@XmlRootElement(namespace="something", name = "A")
@XmlAccessorType (XmlAccessType.FIELD)
@Getter //from lombok
public class Data{
@XmlElement(namespace="something", name = "B") // <-- mind this
private String b;
public Data(String b) {
this.b = b;
}
public Data() {
}
// Getter/setter generated by lombok.
}
如果你不这样做,它会期望,假设你的 Data
在 org.example
包中,命名空间 org.example
中的一些元素只要你有@XmlSchema(elementFormDefault=QUALIFIED)
,否则它将期望默认命名空间中的元素。
您只需要向 A 添加一个 @XmlAttribute(与相应的 getter/setter 一起)
@XmlRootElement(name = "A")
@XmlAccessorType (XmlAccessType.FIELD)
@Getter //from lombok
public class Data{
@XmlAttribute(name="xmln")
String attr;
@XmlElement(name = "B")
private String b;
public Data(String b) {
this.b = b;
}
public Data() {
}
// Getter/setter generated by lombok.
public String getAttr(){
return attr;
}
public void setAttr(String attr){
this.attr = attr;
}
}
编辑:这没有回答问题,因为问题是关于 xml 命名空间而不是属性。
假设我的有效 xml 如下所示:
<A xmlns="something">
<B>4</B>
</A>
我的代码是这样的:
@XmlRootElement(name = "A")
@XmlAccessorType (XmlAccessType.FIELD)
@Getter //from lombok
public class Data{
@XmlElement(name = "B")
private String b;
public Data(String b) {
this.b = b;
}
public Data() {
}
// Getter/setter generated by lombok.
}
我如何让它工作?如果我的 xml 标记有一些关联元素,如上面的 'xmlns',JAXB 解组器会抛出异常。
我是第一次这样做,所以我真的对 JAXB、解组等一无所知。我正在挣扎。 :) 任何帮助都会很好。
编辑 堆栈跟踪:
javax.xml.bind.UnmarshalException: unexpected element (uri:"something", local:"A"). Expected elements are <{}B>,<{}A>
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.Loader.reportError(Loader.java:242)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:109)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(UnmarshallingContext.java:1131)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:556)
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:374)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSContentDriver.scanRootElementHook(XMLNSDocumentScannerImpl.java:613)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3132)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:852)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:602)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:112)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:505)
at ...
如果您的 xml 文档中有名称空间,则您的 jaxb 注释中也需要有它。
例如像这样:
@XmlRootElement(name = "A", namespace="something")
@XmlAccessorType (XmlAccessType.FIELD)
public class Data{
来自 XmlRootElement
的来源:
public @interface XmlRootElement { /** * namespace name of the XML element. * <p> * If the value is "##default", then the XML namespace name is derived * from the package of the class ( {@link XmlSchema} ). If the * package is unnamed, then the XML namespace is the default empty * namespace. */ String namespace() default "##default"; // else of file
您还应牢记此规则也适用于大多数 JAXB 注释,因此您需要指定根元素 以及其他元素 并显式指定命名空间,如下所示:
@XmlRootElement(namespace="something", name = "A")
@XmlAccessorType (XmlAccessType.FIELD)
@Getter //from lombok
public class Data{
@XmlElement(namespace="something", name = "B") // <-- mind this
private String b;
public Data(String b) {
this.b = b;
}
public Data() {
}
// Getter/setter generated by lombok.
}
如果你不这样做,它会期望,假设你的 Data
在 org.example
包中,命名空间 org.example
中的一些元素只要你有@XmlSchema(elementFormDefault=QUALIFIED)
,否则它将期望默认命名空间中的元素。
您只需要向 A 添加一个 @XmlAttribute(与相应的 getter/setter 一起)
@XmlRootElement(name = "A")
@XmlAccessorType (XmlAccessType.FIELD)
@Getter //from lombok
public class Data{
@XmlAttribute(name="xmln")
String attr;
@XmlElement(name = "B")
private String b;
public Data(String b) {
this.b = b;
}
public Data() {
}
// Getter/setter generated by lombok.
public String getAttr(){
return attr;
}
public void setAttr(String attr){
this.attr = attr;
}
}
编辑:这没有回答问题,因为问题是关于 xml 命名空间而不是属性。