Igor
Igor

Reputation: 866

cannot convert xml to jaxb

I have a problem converting a xml to java class, cannot see the problem.

public MyResponse getSmartFocusResponse(MyResponse myResponse, String data) throws JAXBException {
    try {
        JAXBContext jaxbContext = JAXBContext.newInstance(myResponse.getClass());
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();

        StringReader reader = new StringReader(data);
        MyResponse response = (MyResponse) unmarshaller.unmarshal(reader);

        return response;
    } catch (JAXBException e) {
        e.printStackTrace();
        throw e;
    }
}

here are the class I convert to:

@XmlRootElement(name = "response")
public class MyResult {

private InnerResult result;
private String responseStatus;

@XmlElement(name = "result")
public void setResult(InnerResult uploadStatus) {
    this.result = uploadStatus;
}

@XmlAttribute(name = "responseStatus")
public void setResponseStatus(String responseStatus) {
    this.responseStatus = responseStatus;
}

public InnerResult getResult() {
    return result;
}

public String getResponseStatus() {
    return responseStatus;
}

}


@XmlRootElement(name = "result")
public class InnerResult {

private String content;
private String attribute;

@XmlAttribute(name = "xsi:type")
public void setAttribute(String attribute) {
    this.attribute = attribute;
}

@XmlElement
public void setContent(String content) {
    this.content = content;
}

public String getAttribute() {
    return attribute;
}

public String getContent() {
    return content;
}

}

Finally, here is the XML I try to convert:

<response responseStatus="success">
    <result xsi:type="xs:string">
        connection closed
    </result>
</response>

The exception I catch is:

javax.xml.bind.UnmarshalException - with linked exception: [org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 120; The prefix "xsi" for attribute "xsi:type" associated with an element type "result" is not bound.]

Upvotes: 0

Views: 929

Answers (2)

bdoughan
bdoughan

Reputation: 149047

The Problem

The following XML document is not valid to a namespace aware parser as it will expect there to be a namespace associated with the prefix "xsi":

<response responseStatus="success">
    <result xsi:type="xs:string">
        connection closed
    </result>
</response>

Below is what the XML parser wants:

<response responseStatus="success" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <result xsi:type="xs:string">
        connection closed
    </result>
</response>

The Fix

I cannot change the XML, its an input from 3d party...

Since you cannot change the XML you need to use an XML parser that is not namespace aware. The good news is there is one right in the JDK/JRE.

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.UnmarshallerHandler;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;

public class Demo {

    public static void main(String[] args) throws Exception {
        SAXParserFactory spf = SAXParserFactory.newInstance();
        SAXParser sp = spf.newSAXParser();
        XMLReader xr = sp.getXMLReader();

        JAXBContext jc = JAXBContext.newInstance(MyResponse.class);
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        UnmarshallerHandler unmarshallerHandler = unmarshaller.getUnmarshallerHandler();
        xr.setContentHandler(unmarshallerHandler);

        String data = ...;
        StringReader reader = new StringReader(data);
        InputSource xmlSource = new InputSource(reader);
        xr.parse(xmlSource);

        MyResponse myResponse = (MyResponse) unmarshallerHandler.getResult();
     }

}

Upvotes: 2

Lazar Lazarov
Lazar Lazarov

Reputation: 2532

@XmlAttribute(name = "xsi:type")

to

@XmlAttribute(name = "type")

and

<result xsi:type="xs:string">

to

<result type="xs:string">

Upvotes: 0

Related Questions