Unmarshalling following xml having inheritance structure with JAXB

时间:2016-08-31 12:24:40

标签: java jaxb

I want to unmarshal this xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<response>

  <command>dir</command>
  <directory name="folder">
   <file>
     <lastModified>2016-06-06 12:45 AM</lastModified>
     <name>input.txt</name>
     <size>123</size>
     <type>file</type>
  </file>
  <file>
     <lastModified>2016-06-06 12:45 AM</lastModified>
     <name>data.txt</name>
     <size></size>
     <type>directory</type>
  </file>
 </directory>
</response>

here is my class structure

import java.util.ArrayList;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;



@XmlRootElement
@XmlSeeAlso({MessageResponse.class})
class Response {

    String command;

    public Response() {
    }

    @XmlElement
    public String getCommand() {
        return command;
    }

    public void setCommand(String command) {
        this.command = command;
    }
}

@XmlRootElement
class MessageResponse extends Response{
    String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

}

class DirListingResponse extends Response{

    String name;
    Directory directory;


    @XmlElement
    public Directory getDirectory() {
        return directory;
    }

    public void setDirectory(Directory directory) {
        this.directory = directory;
    }

}


class Directory {
    ArrayList<File> file;
    String name;

    public Directory() {
    }


    @XmlAttribute
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @XmlElement
    public ArrayList<File> getFile() {
        return file;
    }

    public void setFile(ArrayList<File> file) {
        this.file = file;
    }
}

class File {
    String name, type;
    String lastModified;
    long size;

    public File() {
    }

    public File(String name, String type, String lastModified, long size) {
        this.name = name;
        this.type = type;
        this.lastModified = lastModified;
        this.size = size;

    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getLastModified() {
        return lastModified;
    }

    public void setLastModified(String lastModified) {
        this.lastModified = lastModified;
    }

    public long getSize() {
        return size;
    }

    public void setSize(long size) {
        this.size = size;
    }

}

and the main class

try {
        jaxbContext = JAXBContext.newInstance(Response.class);
        jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        Object obj = jaxbUnmarshaller.unmarshal(new InputSource(new StringReader(inputXml)));
    } catch (JAXBException e) {
        e.printStackTrace();
    }

but this is not working accordingly. obj contains only command field of response class due to not the proper annotation. Under "response" tag "directory" and "message" tag appears based on command fired. If the command is "dir" then "directory" tag otherwise "message" tag. So I want this unmarshal and save the result in relative inherited class. How can I solve this ?

2 个答案:

答案 0 :(得分:0)

一个解决方案,虽然不优雅,但

  • 事先阅读输入XML并检查它是否有<directory<message
  • 相应地实例化jaxbcontext。
jaxbContext = JAXBContext.newInstance(MessageResponse.class);

or 

jaxbContext = JAXBContext.newInstance(DirListingResponse.class);

答案 1 :(得分:0)

我有一个使用Sax-Parser的解决方案。我将其上传到Github。应该有更好的解决方案(包括隐式打字)。但这可以解决您的问题,同时创建新问题。对文件和目录等的更改将在相应的处理程序中引入更改...