解组时JAXB意外元素

时间:2014-02-22 12:24:58

标签: java xml jaxb

我是JAXB的新手,我在解组时遇到了麻烦。 我使用以下 XSD 来生成JAXB类:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
       targetNamespace="http://last.fm/ge0rgi"
       xmlns="http://last.fm/ge0rgi"
       elementFormDefault="qualified">

<xs:complexType name="lfm-response-type">
    <xs:choice>
        <xs:element name="error" type="error-type" minOccurs="1"
                    maxOccurs="1" />
        <xs:element name="lovedtracks" type="lovedtracks-type"
                    minOccurs="1" maxOccurs="1" />
    </xs:choice>
    <xs:attribute type="status-type" name="status" use="required" />
</xs:complexType>

<xs:simpleType name="status-type">
    <xs:restriction base="xs:string">
        <xs:enumeration value="ok"/>
        <xs:enumeration value="failed"/> 
    </xs:restriction>
</xs:simpleType>

<xs:complexType name="error-type">
    <xs:simpleContent>
        <xs:extension base="xs:string">
            <xs:attribute type="xs:integer" name="code" />
        </xs:extension>
    </xs:simpleContent>
</xs:complexType>

<xs:complexType name="lovedtracks-type">
    <xs:sequence>
        <xs:element name="track" type="track-type" minOccurs="0"
                    maxOccurs="unbounded" />
    </xs:sequence>
    <xs:attribute name="user" type="xs:string" use="required"/>
    <xs:attribute name="page" type="xs:integer" use="required"/>
    <xs:attribute name="perPage" type="xs:integer"  use="required"/>
    <xs:attribute name="totalPages" type="xs:integer" use="required"/>
    <xs:attribute name="total" type="xs:integer" use="required"/>
</xs:complexType>

<xs:complexType name="date-type">
    <xs:simpleContent>
        <xs:extension base="xs:string">
            <!-- Unix timestamp min and max not set -->
            <xs:attribute name="uts" type="xs:integer" />
        </xs:extension>
    </xs:simpleContent>
</xs:complexType>

<xs:complexType name="artist-type">
    <xs:sequence>
        <xs:element name="name" type="xs:string" minOccurs="1"
                    maxOccurs="1" />
        <xs:element name="mbid" type="xs:string" minOccurs="1"
                    maxOccurs="1" />
        <xs:element name="url" type="xs:anyURI" minOccurs="1"
                    maxOccurs="1" />
    </xs:sequence>
</xs:complexType>

<xs:simpleType name="size-type">
    <xs:restriction base="xs:string">
        <xs:enumeration value="small" />
        <xs:enumeration value="medium" />
        <xs:enumeration value="large" />
        <xs:enumeration value="extralarge" />
    </xs:restriction>
</xs:simpleType>

<xs:complexType name="image-type">
    <xs:simpleContent>
        <xs:extension base="xs:anyURI">
            <xs:attribute name="size" type="size-type" />
        </xs:extension>
    </xs:simpleContent>
</xs:complexType>

<xs:complexType name="streamable-type">
    <xs:simpleContent>
        <xs:extension base="xs:integer">
            <xs:attribute name="fulltrack" type="xs:integer"/>
        </xs:extension>
    </xs:simpleContent>
</xs:complexType>

<xs:complexType name="track-type">
    <xs:sequence>
        <xs:element name="name" type="xs:string" minOccurs="1"
                    maxOccurs="1" />
        <xs:element name="mbid" type="xs:string" minOccurs="1"
                    maxOccurs="1" />
        <xs:element name="url" type="xs:anyURI" minOccurs="1"
                    maxOccurs="1" />
        <xs:element name="date" type="date-type" minOccurs="1"
                    maxOccurs="1" />
        <xs:element name="artist" type="artist-type" minOccurs="1"
                    maxOccurs="1" />
        <xs:element name="image" type="image-type" minOccurs="0"
                    maxOccurs="unbounded" />
        <xs:element name="streamable" type="streamable-type" minOccurs="1" maxOccurs="1" />
    </xs:sequence>

</xs:complexType>

<xs:element name="lfm" type="lfm-response-type" />

然后我在LfmResponseType类的顶部添加了这一行: @XmlRootElement(name = "lfm", namespace ="\"http://last.fm/ge0rgi")

XML的一部分看起来像这样:

<lfm status="ok"
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns='http://last.fm/ge0rgi'
xsi:schemaLocation='http://last.fm/ge0rgi lovedtracks.xsd'>
<lovedtracks user="RJ" page="1" perPage="50" totalPages="13"
             total="633" >
    <track>
        <name>Badge</name>
        <mbid>5b78d6ef-8a86-457c-bee3-4bc6fe234df9</mbid>
        <url>http://www.last.fm/music/Cream/_/Badge</url>
        <date uts="1392473900">15 Feb 2014, 14:18</date>
        <artist>
            <name>Cream</name>
            <mbid>04cd0cfd-bfd1-4c36-bc38-95c35e2c045f</mbid>
            <url>http://www.last.fm/music/Cream</url>
        </artist>
        <image size="small">http://userserve-ak.last.fm/serve/34s/60060455.png
        </image>
        <image size="medium">http://userserve-ak.last.fm/serve/64s/60060455.png
        </image>
        <image size="large">http://userserve-ak.last.fm/serve/126/60060455.png
        </image>
        <image size="extralarge">http://userserve-ak.last.fm/serve/300x300/60060455.png
        </image>
        <streamable fulltrack="0">0</streamable>
    </track>
...

解组代码为:

JAXBContext context = JAXBContext.newInstance(LfmResponseType.class);
    Unmarshaller unmarshaller = context.createUnmarshaller();
    LfmResponseType response = (LfmResponseType) unmarshaller.unmarshal(new File("src/jaxbtest/lovedtracks.xml")); 

例外

UnmarshalException: unexpected element (uri:"http://last.fm/ge0rgi", local:"lfm"). Expected elements are <{"http://last.fm/ge0rgi}lfm>

据我所知,这是一个命名空间问题,但我必须知道如何修复它。

编辑:生成的课程 LfmResponseType

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "lfm-response-type", propOrder = {
"error",
"lovedtracks"
})
@XmlRootElement(name = "lfm", namespace ="\"http://last.fm/ge0rgi\"")

public class LfmResponseType {

protected ErrorType error;
protected LovedtracksType lovedtracks;
@XmlAttribute(name = "status", required = true)
protected StatusType status;


public ErrorType getError() {
    return error;
}


public void setError(ErrorType value) {
    this.error = value;
}


public LovedtracksType getLovedtracks() {
    return lovedtracks;
}


public void setLovedtracks(LovedtracksType value) {
    this.lovedtracks = value;
}


public StatusType getStatus() {
    return status;
}

public void setStatus(StatusType value) {
    this.status = value;
}

}

1 个答案:

答案 0 :(得分:2)

您只需使用JAXBContext注册整个生成的包:

JAXBContext context = JAXBContext.newInstance("fm.last.ge0rgi");

此外,您无需添加@XMlRootElement标记,您可以这样做:

    JAXBElement<LfmResponseType> response = (JAXBElement<LfmResponseType>)  unmarshaller.unmarshal(is);
    LfmResponseType responseType = response.getValue());