如何使用 JAXB 附加外部生成的 XML 而不是 POJO 的变量值?
我有具体的数据结构如下:
Map<CustomEnum, CustomList>
到目前为止,我使用实用程序类生成此结构中数据的 xml 表示形式。它使用 SAX
生成 xml 输出。
进一步阅读,CustomEnum
是java enum
,CustomList
扩展了java.util.List
,它的实现通过工厂方法
获得。它允许只包含实现特定接口(interface)
的对象。它们的实现也是通过工厂方法
获得的,主要是根据具体情况。我无权修改任何这些类。
这就是为什么通过 jaxb
转换这个结构对我来说似乎很复杂,但是还有很多其他原因,为什么写了那个实用类(有很多条件评估,例如如果一些值不为空,从其他值获取数据,否则提供默认值等)
现在这个数据结构需要作为更大结构的一部分,基于 POJO 并使用 jaxb 转换为 xml。
是这样的:
public class CustomPojo {
...
private String data;
...
private Map<CustomEnum, CustomList> items;
}
XML 输出应该是:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<rootElement>
<data> value </data>
...
<items>
<!-- generated xml from my utility class -->
</items>
</rootElement>
我需要的是,只要 jaxb marshaller 找到 Map 类型的 pojo 成员变量,而不是尝试从该变量生成 xml,插入由我的实用程序类生成的 xml。
所以我想到了实现自定义适配器的想法:
public class CustomAdapter extends XmlAdapter<String, Map<CustomEnum, CustomList>>
用作
...
@XmlJavaTypeAdapter(CustomAdapter.class)
private Map<CustomEnum, CustomList> items;
并在覆盖的 marshal
方法中返回由我的实用程序生成的 xml。
但它给出了类似的输出:
<items>
<item itemType="1">
 ...
正如我所见,它是带有 xml 数据而不是 xml 标签树的转义字符串。
我的问题是: 有没有办法告诉 jaxb 不要从属性值生成 xml,而是将外部生成的 xml 作为其自己的 xml 的一部分插入?
附言抱歉,描述太长,但我想尽可能清晰地展示图片。 请注意,我知道这种设计并不理想,但我需要它才能正常工作。我正计划进行总体重构,但这似乎是一个远景。
最佳答案
默认情况下,JAXB 的编码器实现转义所有字符,即使对于自定义适配器也是如此(因为它们也通过相同的编码器)。防止字符转义的解决方案是覆盖默认机制。所以我们需要提供一个 CharacterEscapeHandler
的自定义实现,它绝对不会在字符转义方面做任何事情。 JAXB documentation 中给出了有关如何执行此操作的说明。 :
- 编写一个实现 com.sun.xml.bind.marshaller.CharacterEscapeHandler 接口(interface)的类。
- 为其创建一个新实例。
- 使用此属性(即
com.sun.xml.bind.characterEscapeHandler
)将该实例设置为 Marshaller。
因此,这样的实现看起来像...
public class NullCharacterEscapeHandler implements CharacterEscapeHandler {
public NullCharacterEscapeHandler() {
super();
}
public void escape(char[] ch, int start, int length, boolean isAttVal, Writer writer) throws IOException {
// Proxy the characters to the writer, with no encoding escape.
writer.write( ch, start, length );
}
}
...并以这种方式使用:
Marshaller m = jcb.createMarshaller();
m.setProperty("com.sun.xml.bind.marshaller.CharacterEscapeHandler",
new NullCharacterEscapeHandler());
此回复受到此stackoverflow thread 的极大启发.
关于java - 如何使用 JAXB 附加外部生成的 XML 而不是 POJO 的变量值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21117119/