java - 有没有一种方法可以在 JAXB 编组期间为非集合元素添加包装器元素?
问题描述
我正在尝试使用库中的marshaling
方法创建 XML JAXB
。对于这种方法,我使用标准的 java 类并将注解分配给它。我想为类中的某些元素添加一个包装器元素,这些元素不是Collections
.
我知道@XmlElementWrapper
哪些可以用于Collections
但我没有收藏。我有一些元素,我希望有一个外部 XML 元素,以便它可以匹配标准 XSD。
我只是想知道是否有一种方法可以将外部 XML 元素添加到某些元素,以便创建 XML 匹配标准 XSD 格式。如果没有直接的方法,那么我可以采取什么替代方法?
正如我们从示例 XML 中看到的那样,carinfo
标签是元素的外部(包装)标签,engine
但year
该carInfo
标签不存在于Parent
orChild
类中。由于这些是标准类,我无法修改字段/添加新字段。因此,我想使用 JAXB 处理包装器 XML 标记添加。
以下是输入 JSON:
{
"brand": "Ferari",
"build": "Italy",
"engine": "Mercedes",
"year": "2021"
}
以下是我想要的输出 XML:
<?xml version="1.0"?>
<Car>
<brand>Ferari</brand>
<build>Italy</build>
<carinfo>
<engine>Mercedes</engine>
<year>2021</year>
</carinfo>
</Car>
以下是我的课程:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlTransient
@XmlType(name = "Parent")
public class Parent{
private String brand;
private String year;
//Getters and Setters avoided
}
基于创建 XML 的类:
@XmlRootElement(name = "Car")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Child",propOrder={"brand","engine","build","year"})
public class Child extends Parent{
private String engine;
private String build;
//Getter and Setters avoided
}
将创建 XML 的主类:我正在使用该Jackson
库从Json
文件中读取值并基于Jaxb
注释创建 XML。
public class Main{
public static void main(String []args){
JsonFactory jsonFactory = new JsonFactory();
JsonParser jsonParser = jsonFactory.createParser(new File(Main.class.getClassLoader().getResource("input.json").toURI()));
Child eventInfo = jsonParser.readValueAs(Child.class);
JAXBContext context = JAXBContext.newInstance(Child.class);
Marshaller mar = context.createMarshaller();
mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
mar.marshal(eventInfo, System.out);
}
}
解决方案
从我的角度来看,可以在您的 xml 中包含一个新标签,使用和api的组合保留原始类。首先是为转换创建一个 xsl 样式表文件,如下所示:jaxb
javax.xml.transform
模板.xsl
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<Car>
<brand>
<xsl:value-of select="/Car/brand"/>
</brand>
<build>
<xsl:value-of select="/Car/build"/>
</build>
<carinfo>
<engine>
<xsl:value-of select="/Car/engine"/>
</engine>
<year>
<xsl:value-of select="/Car/year"/>
</year>
</carinfo>
</Car>
</xsl:template>
</xsl:stylesheet>
然后你可以使用 set aTransformer
并传递给它一个新的JAXBSource
,如下所示:
Child eventInfo = jsonParser.readValueAs(Child.class);
JAXBContext context = JAXBContext.newInstance(Child.class);
// Create Transformer
TransformerFactory tf = TransformerFactory.newInstance();
StreamSource xslt = new StreamSource(xslFile);
Transformer transformer = tf.newTransformer(xslt);
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.STANDALONE, "yes");
//Print to the stdout the desired xml with the new nested tag
//including the two existing tags
StreamResult result = new StreamResult(System.out);
JAXBSource source = new JAXBSource(context, eventInfo);
transformer.transform(source, result);
推荐阅读
- postgresql - 无法连接到部署到 Kubernetes 的 Postgres
- react-native - 模块导入问题
- ios - 未添加本地通知
- javascript - 如何在javascript中检查动态构造的变量名
- python-3.x - 从数据框列名称中删除后缀 - Python
- javascript - RTCPeerConnection.setRemoteDescription 的参数不足
- dynamics-crm - 在 Dynamics 365 XRM Tooling SDK 中查询已删除的实体
- java - 布局不受 panel.setBackGround(Color.)
- r - 将 str_locate_all 取消列出到单独的开始和结束列表中
- javascript - 如何存储上传到 Firebase 数据库的文件的下载 URL