JAXB解组与命名空间..如何?

时间:2017-03-18 12:56:31

标签: java xml jaxb unmarshalling

假设我的有效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 unmarshaller会抛出异常。

我是第一次这样做,所以我真的不知道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 ...

3 个答案:

答案 0 :(得分:3)

来自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.
}

如果你没有,那么假设你的Dataorg.example包中,假设org.example 中的一些元素,只要你有{{} 1}} ,或者它会期望默认命名空间中的元素。

答案 1 :(得分:2)

如果xml文档中有命名空间,则还需要在jaxb注释中使用该命名空间。

E.g。像这样:

@XmlRootElement(name = "A", namespace="something")
@XmlAccessorType (XmlAccessType.FIELD)
public class Data{

答案 2 :(得分:0)

您只需要将一个@XmlAttribute添加到A(与相应的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名称空间而不是属性。