java - jaxb 按类型解组到对象
问题描述
我想根据 xml 解析出不同的类型,当 header=1 然后是 User,header=2 然后是 Order 等,例如:
<entity>
<header>1</header>
<body>
<userId>1</userId>
<userName>jonh</userName>
...
<body>
</entity>
<entity>
<header>2</header>
<body>
<orderId>1</orderId>
<orderNo>20200101</orderNo>
...
<body>
</entity>
如何实现这个功能?
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Object object = unmarshaller.unmarshal(xml);
解决方案
public class TwiceUnmarshalTest {
@Data
@ToString
public static abstract class HeaderResponse {
private String header;
}
@XmlRootElement(name = "entity")
@XmlAccessorType(XmlAccessType.FIELD)
public static class XmlHeaderResponse extends HeaderResponse {
}
private final String xml = "<entity>" +
" <header>2</header>" +
" <body>" +
" <orderId>1</orderId>" +
" <orderNo>2020</orderNo>" +
" </body>" +
"</entity>";
@SuppressWarnings("unchecked")
public static <T> T unmarshal(Reader reader, Class<T> typeClass) throws Exception {
JAXBContext jaxbContext = JAXBContext.newInstance(typeClass);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
return (T) unmarshaller.unmarshal(reader);
}
@Test
public void headerResponse() throws Exception {
HeaderResponse response = unmarshal(new StringReader(xml), XmlHeaderResponse.class);
System.out.println(response);
}
@ToString(callSuper = true)
public static abstract class Response<T> extends HeaderResponse {
@XmlAnyElement(lax = true)
public T body;
}
@Data
@XmlRootElement(name = "body")
public static class Order {
private String orderId;
private String orderNo;
}
@XmlRootElement(name = "entity")
@XmlSeeAlso({Order.class})
public static class OrderResponse extends Response<Order> {
}
@Test
public void response() throws Exception {
XmlHeaderResponse response = unmarshal(new StringReader(xml), XmlHeaderResponse.class);
System.out.println(response);
//TwiceUnmarshalTest.HeaderResponse(header=2)
if (response.getHeader().equals("2")) {
OrderResponse orderResponse = unmarshal(new StringReader(xml), OrderResponse.class);
System.out.println(orderResponse);
//TwiceUnmarshalTest.Response(super=TwiceUnmarshalTest.HeaderResponse(header=2), body=TwiceUnmarshalTest.Order(orderId=1, orderNo=2020))
}
}
}
解组两次,只需先获取标题,然后获取实体。不是很好,但可以使用。
推荐阅读
- django - 通过cmd在django服务器中运行网站时出错
- haskell - 在代码中找不到错误(Project Euler #11 (Haskell))
- python - 在 Python 中创建一个查看先前 IF 语句输出的 IF 语句
- php - 如何在 dj-classifieds(Joomla)的广告(项目)视图上添加下一个和上一个按钮?
- javascript - Internet Explorer 11 (IE 11) 使用 DOMParser 中的 parseFromString 删除反斜杠并更改属性顺序
- c# - 错误 CS0246:找不到类型或命名空间名称“WebDriverWait”?
- c++ - 如何在 cmake >= 2.6 中使用没有 gnu 扩展的 c++98?
- wcf - WCF 客户端作为控制台应用程序运行,但作为 Windows 服务运行,失败并出现 EndpointNotFoundException
- php - 使用特定查询从 JSON 创建 PHP 数组
- jquery - 我如何使用 JQuery 从没有名称的数组 Json 中获取元素