-->

Unmarshalling following xml having inheritance str

2020-08-01 01:46发布

问题:

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 ?

回答1:

One solution although not elegant is to

  • read the input XML beforehand and check if it has <directory or <message
  • accordingly instantiate the jaxbcontext.

jaxbContext = JAXBContext.newInstance(MessageResponse.class);

or 

jaxbContext = JAXBContext.newInstance(DirListingResponse.class);


回答2:

I have a solution which uses the Sax-Parser. I uploaded it to Github. There should be better solutions (including implicit typings). But this would solve your problems, while creating new ones. Changes to File and Directory, etc. would introduce changes in the corresponding handlers...



标签: java jaxb