2016-08-31 5 views
0

Я хочу, чтобы распаковать этот XMLДемаршаллизация следующие XML, имеющие структуру наследования с JAXB

<?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> 

вот мой класс структура

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; 
    } 

} 

и главный класс

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

, но это не работает соответственно. obj содержит только поле команды класса ответа из-за не соответствующей аннотации. В теге «response» тег «каталог» и «сообщение» появляется по команде. Если команда «dir», то тег «directory» в противном случае тег «message». Поэтому я хочу, чтобы этот unmarshal и сохранил результат в относительном унаследованном классе. Как я могу это решить?

+0

Что вы ожидаете? – Jens

+0

Мне нужен объект result в моем относительном классе, который находится в DirListingResponse. –

+0

JAXB не является гибким по умолчанию. Но есть некоторые полезные расширения, которые могут вам помочь. Взгляните на [Eclipse Moxy] (http://www.eclipse.org/eclipselink/documentation/2.4/moxy/type_level003.htm). Никогда не использовал его, но звучит многообещающе. –

ответ

0

Одно решение, хотя и не является элегантный

  • заранее прочитать входной XML и проверить, если он имеет <directory или <message
  • соответственно экземпляр JAXBContext.

jaxbContext = JAXBContext.newInstance(MessageResponse.class); 

or 

jaxbContext = JAXBContext.newInstance(DirListingResponse.class); 
+0

чтение с использованием парсера? –

+0

'xpath' будет хорошим вариантом. Хотя простая строка содержит проверку, будет выполняться при условии, что поиск содержимого выполняется с помощью '<' – ulab

+0

, если ответ является текстом, тогда он работает нормально, но если я запускаю dir, тогда он показывает java.lang.ClassCastException: response.binding.MessageResponse не может быть отброшен в ответ .binding.DirListingResponse \t на client.ServerReader.run (ServerReader.java:42) –

0

У меня есть решение, которое использует Sax-Parser. Я загрузил его в Github. Должны быть лучшие решения (включая неявные типизации). Но это решит ваши проблемы, создавая новые. Изменения в файле и каталоге и т. Д. Вносят изменения в соответствующие обработчики ...

Смежные вопросы