如何使用 JAXB 使用不同的标签 marshal/unmarshal 抽象 class
How to marshal/unmarshal abstract class with a different tags using JAXB
<root-object>
<synchronous>
<command>C:\hello_world.exe</command>
<argument>aaaa</argument>
<argument>bbbb</argument>
</synchronous>
<asynchronous>
<command>C:\hello_world.exe</command>
<argument>aaaa</argument>
<argument>bbbb</argument>
</asynchronous>
<synchronous>
<command>C:\hello_world.exe</command>
<argument>aaaa</argument>
<argument>bbbb</argument>
</synchronous>
</root-object>
在这种 XML 格式中,我想通过 JAXB unmarshal/marshal 同步和异步对象到一个列表中。
我写了下面的代码,但是items里面什么都没有输入
我怎样才能使这个结构成为可能?
@XmlRootElement(name = "root-object")
@XmlAccessorType(XmlAccessType.FIELD)
@lombok.ToString
public class RootObject {
@XmlElement(type = CommandItem.class)
private List<CommandItem> items= new ArrayList<>();
public RootObject() {}
@lombok.Getter
@lombok.Setter
@lombok.NoArgsConstructor
@XmlType
@XmlSeeAlso({AsyncCommandItem.class, SyncCommandItem.class})
@XmlAccessorType(XmlAccessType.FIELD)
public static class CommandItem {
@XmlElement(name = "command")
private String command;
@XmlElement(name = "argument")
private List<String> argument;
}
@lombok.NoArgsConstructor
@XmlRootElement(name = "synchronous")
public static class SyncCommandItem extends CommandItem {
}
@lombok.NoArgsConstructor
@XmlRootElement(name = "asynchronous")
public static class AsyncCommandItem extends CommandItem {
}
}
我为您提供的 XML 使用了以下代码,它似乎对我来说工作正常。您需要稍微修改 POJO 才能使其正常工作。
RootObject.class:
@XmlRootElement(name = "root-object")
@Data
@XmlAccessorType(XmlAccessType.FIELD)
public class RootObject {
@XmlElement(name = "synchronous")
private List<Synchronous> synchronous;
@XmlElement(name = "asynchronous")
private List<Asynchronous> asynchronous;
}
Synchronous.class:
@Data
@XmlAccessorType(XmlAccessType.NONE)
public class Synchronous {
@XmlElement(name = "command")
private String command;
@XmlElement(name = "argument")
private List<String> argument;
}
Asynchronous.class:
@Data
@XmlAccessorType(XmlAccessType.NONE)
public class Asynchronous {
@XmlElement(name = "command")
private String command;
@XmlElement(name = "argument")
private List<String> argument;
}
Main.class:
public class Main {
public static void main(String[] args) throws JAXBException, XMLStreamException {
final InputStream inputStream = Unmarshalling.class.getClassLoader().getResourceAsStream("synchronous.xml");
final XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
final Unmarshaller unmarshaller = JAXBContext.newInstance(RootObject.class).createUnmarshaller();
final RootObject rootObject = unmarshaller.unmarshal(xmlStreamReader, RootObject.class).getValue();
System.out.println(rootObject.toString());
Marshaller marshaller = JAXBContext.newInstance(RootObject.class).createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(rootObject, System.out);
}
}
输出如下:
RootObject(synchronous=[Synchronous(command=C:\hello_world.exe, argument=[aaaa, bbbb]), Synchronous(command=C:\hello_world.exe, argument=[aaaa, bbbb])], asynchronous=[Asynchronous(command=C:\hello_world.exe, argument=[aaaa, bbbb])])
<root-object>
<synchronous>
<command>C:\hello_world.exe</command>
<argument>aaaa</argument>
<argument>bbbb</argument>
</synchronous>
<synchronous>
<command>C:\hello_world.exe</command>
<argument>aaaa</argument>
<argument>bbbb</argument>
</synchronous>
<asynchronous>
<command>C:\hello_world.exe</command>
<argument>aaaa</argument>
<argument>bbbb</argument>
</asynchronous>
</root-object>
我通过@XmlElements解决了。
@XmlRootElement(name = "root-object")
@XmlAccessorType(XmlAccessType.FIELD)
@lombok.ToString
public class RootObject {
@XmlElements({
@XmlElement(name = "synchronous", type = SyncCommandItem.class),
@XmlElement(name = "asynchronous", type = AsyncCommandItem .class),
})
private List<CommandItem> items= new ArrayList<>();
public RootObject() {}
@lombok.Getter
@lombok.Setter
@lombok.NoArgsConstructor
@XmlType
@XmlSeeAlso({AsyncCommandItem.class, SyncCommandItem.class})
@XmlAccessorType(XmlAccessType.FIELD)
public static class CommandItem {
@XmlElement(name = "command")
private String command;
@XmlElement(name = "argument")
private List<String> argument;
}
@lombok.NoArgsConstructor
@XmlRootElement(name = "synchronous")
public static class SyncCommandItem extends CommandItem {
}
@lombok.NoArgsConstructor
@XmlRootElement(name = "asynchronous")
public static class AsyncCommandItem extends CommandItem {
}
}
<root-object>
<synchronous>
<command>C:\hello_world.exe</command>
<argument>aaaa</argument>
<argument>bbbb</argument>
</synchronous>
<asynchronous>
<command>C:\hello_world.exe</command>
<argument>aaaa</argument>
<argument>bbbb</argument>
</asynchronous>
<synchronous>
<command>C:\hello_world.exe</command>
<argument>aaaa</argument>
<argument>bbbb</argument>
</synchronous>
</root-object>
在这种 XML 格式中,我想通过 JAXB unmarshal/marshal 同步和异步对象到一个列表中。
我写了下面的代码,但是items里面什么都没有输入
我怎样才能使这个结构成为可能?
@XmlRootElement(name = "root-object")
@XmlAccessorType(XmlAccessType.FIELD)
@lombok.ToString
public class RootObject {
@XmlElement(type = CommandItem.class)
private List<CommandItem> items= new ArrayList<>();
public RootObject() {}
@lombok.Getter
@lombok.Setter
@lombok.NoArgsConstructor
@XmlType
@XmlSeeAlso({AsyncCommandItem.class, SyncCommandItem.class})
@XmlAccessorType(XmlAccessType.FIELD)
public static class CommandItem {
@XmlElement(name = "command")
private String command;
@XmlElement(name = "argument")
private List<String> argument;
}
@lombok.NoArgsConstructor
@XmlRootElement(name = "synchronous")
public static class SyncCommandItem extends CommandItem {
}
@lombok.NoArgsConstructor
@XmlRootElement(name = "asynchronous")
public static class AsyncCommandItem extends CommandItem {
}
}
我为您提供的 XML 使用了以下代码,它似乎对我来说工作正常。您需要稍微修改 POJO 才能使其正常工作。
RootObject.class:
@XmlRootElement(name = "root-object")
@Data
@XmlAccessorType(XmlAccessType.FIELD)
public class RootObject {
@XmlElement(name = "synchronous")
private List<Synchronous> synchronous;
@XmlElement(name = "asynchronous")
private List<Asynchronous> asynchronous;
}
Synchronous.class:
@Data
@XmlAccessorType(XmlAccessType.NONE)
public class Synchronous {
@XmlElement(name = "command")
private String command;
@XmlElement(name = "argument")
private List<String> argument;
}
Asynchronous.class:
@Data
@XmlAccessorType(XmlAccessType.NONE)
public class Asynchronous {
@XmlElement(name = "command")
private String command;
@XmlElement(name = "argument")
private List<String> argument;
}
Main.class:
public class Main {
public static void main(String[] args) throws JAXBException, XMLStreamException {
final InputStream inputStream = Unmarshalling.class.getClassLoader().getResourceAsStream("synchronous.xml");
final XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
final Unmarshaller unmarshaller = JAXBContext.newInstance(RootObject.class).createUnmarshaller();
final RootObject rootObject = unmarshaller.unmarshal(xmlStreamReader, RootObject.class).getValue();
System.out.println(rootObject.toString());
Marshaller marshaller = JAXBContext.newInstance(RootObject.class).createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(rootObject, System.out);
}
}
输出如下:
RootObject(synchronous=[Synchronous(command=C:\hello_world.exe, argument=[aaaa, bbbb]), Synchronous(command=C:\hello_world.exe, argument=[aaaa, bbbb])], asynchronous=[Asynchronous(command=C:\hello_world.exe, argument=[aaaa, bbbb])])
<root-object>
<synchronous>
<command>C:\hello_world.exe</command>
<argument>aaaa</argument>
<argument>bbbb</argument>
</synchronous>
<synchronous>
<command>C:\hello_world.exe</command>
<argument>aaaa</argument>
<argument>bbbb</argument>
</synchronous>
<asynchronous>
<command>C:\hello_world.exe</command>
<argument>aaaa</argument>
<argument>bbbb</argument>
</asynchronous>
</root-object>
我通过@XmlElements解决了。
@XmlRootElement(name = "root-object")
@XmlAccessorType(XmlAccessType.FIELD)
@lombok.ToString
public class RootObject {
@XmlElements({
@XmlElement(name = "synchronous", type = SyncCommandItem.class),
@XmlElement(name = "asynchronous", type = AsyncCommandItem .class),
})
private List<CommandItem> items= new ArrayList<>();
public RootObject() {}
@lombok.Getter
@lombok.Setter
@lombok.NoArgsConstructor
@XmlType
@XmlSeeAlso({AsyncCommandItem.class, SyncCommandItem.class})
@XmlAccessorType(XmlAccessType.FIELD)
public static class CommandItem {
@XmlElement(name = "command")
private String command;
@XmlElement(name = "argument")
private List<String> argument;
}
@lombok.NoArgsConstructor
@XmlRootElement(name = "synchronous")
public static class SyncCommandItem extends CommandItem {
}
@lombok.NoArgsConstructor
@XmlRootElement(name = "asynchronous")
public static class AsyncCommandItem extends CommandItem {
}
}