我有一个相当复杂的 JAXB 树对象。 对于每个叶节点,我需要过滤其实际值
例如
<Book>
<Title>Yogasana Vijnana: the Science of Yoga</Title>
<Author>Dhirendra Brahmachari</Author>
<Date>1966</Date>
</Book>
此处的叶节点为Title
、author
和Date
。
想象一下,我需要为这个 JAXB 模型编写一个编码文档,每个叶节点的第一个字符都被删除:
<Book>
<Title>ogasana Vijnana: the Science of Yoga</Title>
<Author>hirendra Brahmachari</Author>
<Date>966</Date>
</Book>
什么是最好的方法?
我看到了两个起点,但是,我目前卡住了。
<强>1。在 JAXB 模型中进行更改
是否有一些遍历机制可以用来获取任何 JAXB 对象(某种访问者模式或其他)的叶元素?
<强>2。钩入编码
也许我们可以加入编码,例如使用 XMLStreamWriter
..
这种问题有没有优雅的解决方案?
最佳答案
另一种方法基于 XMLStreamWriter
类型的装饰器,它会简单地跳过文本内容的第一个字符,但您无法将其限制为叶子仅节点,它将对所有文本内容应用相同的逻辑,而不仅仅是叶节点,如果您的编码不像您的示例那样生成混合内容,这将不是问题。实际上,如果您没有混合内容(文本内容和节点混合在一起),则只有叶节点可以包含文本内容。
您的装饰器可能是这样的:
public class RemoveFirstCharacter implements XMLStreamWriter {
private final XMLStreamWriter delegate;
public RemoveFirstCharacter(final XMLStreamWriter delegate) {
this.delegate = delegate;
}
@Override
public void writeStartElement(final String localName) throws XMLStreamException {
delegate.writeStartElement(localName);
}
@Override
public void writeStartElement(final String namespaceURI, final String localName)
throws XMLStreamException {
delegate.writeStartElement(namespaceURI, localName);
}
...
@Override
public void writeCharacters(final String text) throws XMLStreamException {
// Skip the first character
delegate.writeCharacters(text.substring(1));
}
@Override
public void writeCharacters(final char[] text, final int start, final int len)
throws XMLStreamException {
if (start == 0) {
// Skip the first character
delegate.writeCharacters(text, 1, len - 1);
} else {
delegate.writeCharacters(text, start, len);
}
}
}
那么你的代码将是:
// Create the marshaller for the class Book
JAXBContext jaxbContext = JAXBContext.newInstance(Book.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
// Create the main XMLStreamWriter
XMLOutputFactory output = XMLOutputFactory.newInstance();
XMLStreamWriter writer = output.createXMLStreamWriter(System.out);
// Apply the custom XMLStreamWriter that will remove the first character
// of each text content
jaxbMarshaller.marshal(book, new RemoveFirstCharacter(writer));
关于java - JAXB 编码 : Filter values of leaf elements,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42301081/