有没有办法在 JAXB 中为非 collection 元素编组期间添加包装器元素?
Is there a a way to add a wrapper element during the marshalling in JAXB for non collection element?
我正在尝试使用 JAXB
库中的 marshaling
方法创建 XML。对于这种方法,我使用标准 java class 并为其分配注释。我想对 class 中不是 Collections
.
中的某些元素进行包装元素
我知道 @XmlElementWrapper
可用于 Collections
,但我没有 collection。我有一些元素,我想要一个外部 XML 元素,以便它可以匹配标准 XSD.
我只是想知道是否有办法在某些元素中添加外部 XML 元素,以便创建 XML 与标准 XSD 格式匹配。如果没有直接的方法,那么我可以采用什么替代方法?
正如我们从示例 XML 中看到的那样,carinfo
标签是元素 engine
和 year
的外部(包装)标签,但是这个 carInfo
标记不存在于 Parent
或 Child
class 中。由于这些是标准 classes,我无法修改字段/添加新字段。因此,我想使用 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>
以下是我的 classes:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlTransient
@XmlType(name = "Parent")
public class Parent{
private String brand;
private String year;
//Getters and Setters avoided
}
Class 基于 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 的主要 class:我正在使用 Jackson
库从 Json
文件中读取值并创建 XML 基于 Jaxb
注释。
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 中包含一个新标签,同时保留原始 类 与 jaxb
和 javax.xml.transform
api。首先是为转换创建一个 xsl 样式表文件,如下所示:
template.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>
然后您可以使用集合 a Transformer
并向其传递一个新的 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);
最后,我能够使用 Moxy
中的 @XmlPath
获得它,它是基于 Jaxb
的库。您可以将 @XmlPath
用于任何元素,例如集合、非集合、字符串等。我花了很多时间尝试配置和做变通办法,所以在这里发布答案,这样它对某人有用将来他们不会像我一样浪费那么多时间:)
请找到配置 Moxy
的答案
此外,了解如何使用 @XmlPath
获取 XML
的包装元素
您还可以在 EclipseLink
文档中阅读更多相关信息。
我正在尝试使用 JAXB
库中的 marshaling
方法创建 XML。对于这种方法,我使用标准 java class 并为其分配注释。我想对 class 中不是 Collections
.
我知道 @XmlElementWrapper
可用于 Collections
,但我没有 collection。我有一些元素,我想要一个外部 XML 元素,以便它可以匹配标准 XSD.
我只是想知道是否有办法在某些元素中添加外部 XML 元素,以便创建 XML 与标准 XSD 格式匹配。如果没有直接的方法,那么我可以采用什么替代方法?
正如我们从示例 XML 中看到的那样,carinfo
标签是元素 engine
和 year
的外部(包装)标签,但是这个 carInfo
标记不存在于 Parent
或 Child
class 中。由于这些是标准 classes,我无法修改字段/添加新字段。因此,我想使用 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>
以下是我的 classes:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlTransient
@XmlType(name = "Parent")
public class Parent{
private String brand;
private String year;
//Getters and Setters avoided
}
Class 基于 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 的主要 class:我正在使用 Jackson
库从 Json
文件中读取值并创建 XML 基于 Jaxb
注释。
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 中包含一个新标签,同时保留原始 类 与 jaxb
和 javax.xml.transform
api。首先是为转换创建一个 xsl 样式表文件,如下所示:
template.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>
然后您可以使用集合 a Transformer
并向其传递一个新的 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);
最后,我能够使用 Moxy
中的 @XmlPath
获得它,它是基于 Jaxb
的库。您可以将 @XmlPath
用于任何元素,例如集合、非集合、字符串等。我花了很多时间尝试配置和做变通办法,所以在这里发布答案,这样它对某人有用将来他们不会像我一样浪费那么多时间:)
请找到配置 Moxy
此外,了解如何使用 @XmlPath
XML
的包装元素
您还可以在 EclipseLink
文档中阅读更多相关信息。